SQL 查询从另一个 Excel 获取数据 - VBA

问题描述 投票:0回答:1

我正在开发一个简单的 Excel VBA 应用程序来控制公司的一小部分股票。 这个想法是让包装好的盒子按货架索引。 在 Excel Database.xlsx 文件中,我们有两个表: 包装:包含包装箱的重量和尺寸; Trans:该包的目的地是货架。

示例:

包装:

| Pack_ID    | SalesIDLine    |
| --------   | --------       |
| 030F7D78   | SO00265293-1510|
| E2B9BD52   | SO00265293-130 |

译:

| Loc_ID  | Pack_ID   |
| ------  | --------  |
| D0305   | 030F7D78  |
| B0204   | E2B9BD52  |

但是每次运行查询时都会收到此错误: bof 或 eof 为 true 表示当前记录已被删除 BOF 为 false,EOF 为 true,记录计数为 -1

我尝试了这段代码:

Private Function SearchSalesID(SalesIDLine As String) As String()
    Dim conn As Object
    Dim cmd As Object
    Dim rs As Object
    Dim result() As String
    Dim index As Integer
    
    'On Error GoTo ErrorHandler

    Dim filePath As String
    filePath = DataBase_Path & "\" & DataBase_Name

    Set conn = CreateObject("ADODB.Connection")

    conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
              "Data Source=" & filePath & ";" & _
              "Extended Properties=""Excel 12.0 XML;HDR=YES;IMEX=1"";"

    Set cmd = CreateObject("ADODB.Command")
    Set cmd.ActiveConnection = conn

    cmd.CommandText = "SELECT Loc_ID FROM [Trans$] AS T INNER JOIN [Pack$] AS P ON T.Pack_ID = P.Pack_ID WHERE P.SalesIDLine LIKE '" & SalesIDLine & "%'"
    
    Set rs = cmd.Execute

    result = rs.GetRows
    
    rs.Close
    conn.Close
    
    SearchSalesID = Application.Transpose(result)
    
    Exit Function

ErrorHandler:
    If Not conn Is Nothing Then
        conn.Close
    End If
    If Not rs Is Nothing Then
        rs.Close
    End If
    SearchSalesID = Array() 
End Function
sql excel vba
1个回答
0
投票

对我来说,你的代码几乎可以工作。

问题是

recordSet.GetRows
返回一个二维数组 - 即使您只得到一行和/或一列。看起来有点但违反直觉的是,第一个索引获取列号,第二个索引获取行号,但这可能就是你的原因
Application.Transpose

但是,无论您是否使用转置,结果始终是二维的,并且您的函数定义表示它返回一个一维数组。因此,当您将

Transpose
的结果分配为函数结果时,会出现类型不匹配的情况。

根据您的需求,您需要手动创建一维数组,或者更改查询的返回类型。例如,您可以使用这段代码来代替转置

ReDim resultVector(LBound(result, 2) To UBound(result, 2))
Dim row As Long
For row = LBound(result, 2) To UBound(result, 2)
    resultVector(row) = result(0, row)
Next
SearchSalesID = resultVector

现在您还需要处理一件事:如果查询不返回任何值会发生什么?我过去使用过以下功能。我使用 早期绑定,如果您不想要,请将 rs 的类型更改为

Object

Public Function GetDataFromRecordSet(rs As Recordset) As Variant
    If rs Is Nothing Then
      Exit Function
    ElseIf rs.State = 0 Then    ' State = 0: RS is closed
      Exit Function
    ElseIf rs.EOF Then
      Exit Function
    End If
    
    Dim result
    On Error GoTo GetDataFromRecordSet_ERROR
    result = rs.Getrows
    GetDataFromRecordSet = result
    Exit Function
    
GetDataFromRecordSet_ERROR:
    Debug.Print Err.Number, Err.Description
    
End Function

如果由于任何原因无法从记录集对象中读取任何内容,则此函数将返回 Empty 作为结果 - 在日常生活中,如果查询中没有数据,主要是这种情况。您需要考虑如何在代码中反映这一点。您可以返回

Empty
(在这种情况下,您需要将函数的返回类型更改为
Variant
),或者如果您想返回一个包含一个元素为“”的数组)...

空返回:

Private Function SearchSalesID(SalesIDLine As String) As Variant
    (...)
    Set rs = cmd.Execute
    result = GetDataFromRecordSet(rs)
    rs.Close

    If IsEmpty(result) Then Exit Function  
    (...)
End Function

返回一个虚拟数组:

Private Function SearchSalesID(SalesIDLine As String) As Variant
    (...)
    Set rs = cmd.Execute
    result = GetDataFromRecordSet(rs)
    rs.Close
    
    If IsEmpty(result) Then
        ReDim resultVector(0 To 0) As String
    Else
        ReDim resultVector(LBound(result, 2) To UBound(result, 2))
        Dim row As Long
        For row = LBound(result, 2) To UBound(result, 2)
            resultVector(row) = result(0, row)
        Next
    End If
    SearchSalesID = resultVector
End Function
© www.soinside.com 2019 - 2024. All rights reserved.