【问题标题】:Output recordset in VBA using condition使用条件在 VBA 中输出记录集
【发布时间】:2017-03-25 03:08:13
【问题描述】:

我在这里遇到了一些麻烦。

我有一个包含 2500 万行的 csv 数据库,其中包含四列:FIELD(从 1 到 5)、DATEHOUR(格式为 yyyyddmmhhmmssxxx、年、日、月、小时、分钟、秒和毫秒)、BOUND(南或北)和类别(从 1 到 10)。

我正在使用以下代码

Public Sub QueryTextFile()
    Dim Recordset As ADODB.Recordset
    Dim ConnectionString As String
    ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.Path & ";" & _
      "Extended Properties=Text;"

    Const SQL As String = "SELECT * FROM Dados.csv WHERE Categoria=3;"

    Set Recordset = New ADODB.Recordset
    Call Recordset.Open(SQL, ConnectionString, CursorTypeEnum.adOpenForwardOnly, LockTypeEnum.adLockReadOnly, CommandTypeEnum.adCmdText)
    Call Sheet1.Range("A1").CopyFromRecordset(Recordset)
    Recordset.Close
    Set Recordset = Nothing

End Sub

问题是,例如,我只想获取 2 月(02 月)和 FIELD 3 的寄存器。我该怎么做?

谢谢你们!

【问题讨论】:

  • CopyFromRecordset 只会返回前 65536 条记录。 ADODB.Recordset.GetRows 会将完整的 Recordset 加载到一个数组中,您可以使用该数组来填充工作表。如果您可以提供 CSV 文件的下载链接,我将提供代码帮助。

标签: sql vba select


【解决方案1】:
SELECT * FROM Dados.csv 
WHERE 
Categoria = 3 AND
FIELD = 3     AND
DATEHOUR Like '######02*'

【讨论】:

    【解决方案2】:

    对于这种大小的文件,如果您只需要一个简单的过滤操作 - 您可能只想逐行读取并存储匹配的行。这是一个例子:

    输入文件

    FIELD,DATEHOUR,BOUND,CATEGORY
    1,20030609100744914,south,2
    2,19530310011542750,north,5
    5,19780506121938486,south,6
    3,19201602155516116,south,2
    3,19381909204504683,north,2
    4,19641002092156003,south,10
    1,19142109082009062,south,8
    5,19762306242234798,north,11
    2,19261008163849534,south,2
    1,19093003100715152,south,12
    1,19282102090128629,north,2
    5,19652606190400678,south,3
    3,19162302062356493,south,3
    5,20151605125616260,north,6
    

    和 VBA 函数:

    Option Explicit
    
    Sub filterData()
    
        Dim fileNum As Integer
        Dim csvLine As String
    
        Dim arrLine() As String      ' fields from the csv line, 0-based
        Const FIELD = 0: Const DATEHOUR = 1: Const BOUND = 2: Const CATEGORY = 3
    
        Dim arrResult() As String    ' string array for filtered data
        Dim idx As Long: idx = 1     ' current index in the array
        ReDim arrResult(idx To 1000) ' initial size
    
        ' read file line-by-line
        fileNum = FreeFile()
        Open ThisWorkbook.Path & Application.PathSeparator & "dataFile.csv" _
                For Input As #fileNum
    
        While Not EOF(fileNum)
            Line Input #fileNum, csvLine
            ' 0-FIELD, 1-DATEHOUR, 2-BOUND, 3-CATEGORY
            arrLine = Split(csvLine, ",")
    
            ' check the condition for inclusion
            If arrLine(FIELD) = "3" And Mid(arrLine(DATEHOUR), 7, 2) = "02" Then
                If idx > UBound(arrResult) Then
                    ReDim Preserve arrResult(1 To UBound(arrResult) * 2)
                End If
                arrResult(idx) = csvLine
                idx = idx + 1
            End If
        Wend
    
        Close #fileNum
    
        ' trim excess entries
        ReDim Preserve arrResult(1 to idx - 1)
    
        ' display results in the spreadsheet (only up to 1mm)
        Worksheets("Sheet1").[a1].Resize(UBound(arrResult), 1) = Application.Transpose(arrResult)
    
    End Sub
    

    这是您将在“Sheet1”中获得的结果:

    P.S.:或者你可以只使用 UNIX grep...

    P.S.S.:另请注意,如果结果数组将大于 1 毫米条目 - 您将无法在 Excel 中显示它。可以修改代码以限制数组中的条目数、仅显示数组的一部分、将其显示在多列中或将结果数组写入另一个文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-09
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多