使用后期绑定将 Recordset 对象作为参数传递时出现类型不匹配 (13) 错误

Type Mismatch (13) error when passing Recordset object as parameter using late binding

我正在编写 VBA UDF 来检索有关编码位置的地理数据。

我有一个 Excel 工作簿,其中包含共享位置中的所有详细信息。

当用户在他们的工作簿上输入 UDF 并提供请求的编码参数时,会发生以下情况:

  1. 他们的工作簿打开到共享驱动器上目标工作簿的 ADO 连接,并将所有数据查询到记录集中。
  2. 然后将该记录集传递给另一个自定义 VBA 函数,该函数用记录集的内容填充 VBA 字典。
  3. UDF returns根据用户输入的参数在字典中的值之一。

(如果在步骤 1 之前已经存在于内存中,则重复使用现有词典。)

这个 在我的电脑上工作得很好,但在另一台电脑上测试它会导致明显的引用错误。所以我为代码中的对象切换到 late binding。现在,当我在上面的第 2 步中传递记录集时,出现了问题。我收到类型 13 不匹配错误。

这是(部分截取的)代码。

我知道问题出在记录集参数上,因为将其从调用中删除并且函数声明成功调用了该函数,但当然后来失败了。

这个!!!那里是为了说明代码在哪里失败。

Public Sub QueryFromExcel(sSQL As String, sPath As String, Optional vDestination As Variant, Optional aColumns As Variant)

    'Late Binding
        Dim objMyConn As Object
        Dim objMyRecordset As Object
        Set objMyConn = CreateObject("ADODB.Connection")
        Set objMyRecordset = CreateObject("ADODB.Recordset")

    'Open Connection
        On Error GoTo ErrCatch:
        objMyConn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sPath & ";Extended Properties=""Excel 12.0 XML;HDR=Yes,IMEX=1"""
        objMyConn.Open

    'Open Recordset
        Set objMyRecordset.ActiveConnection = objMyConn
        objMyConn.CommandTimeout = 0
        objMyRecordset.Open sSQL
        On Error GoTo 0

    'Copy Data to Destination    
        If IsMissing(vDestination) Or TypeOf vDestination Is Worksheet Then
            'Add a new sheet if there's no destination
            Dim outSheet As Worksheet
            If IsMissing(vDestination) Then
                Set outSheet = ActiveWorkbook.Sheets.Add
            Else
                Set outSheet = vDestination
            End If
            Call PopulateSheetFromRecordset(outSheet, objMyRecordset, aColumns)
        ElseIf TypeOf vDestination Is Dictionary And Not IsMissing(aColumns) Then

            '!!! 
            Call PopulateDictionaryFromRecordset(vDestination, objMyRecordset, aColumns)
        End If

End Sub

这里是发生错误的定义函数:

Public Sub PopulateDictionaryFromRecordset(dDictionary As Variant, rsRecords As Recordset, aColumns As Variant)

似乎更改为后期绑定改变了与 Recordset 对象类型相关的其他内容。研究表明,这可能是因为有多种类型的 Recordset 对象,但我已将 objMyRecordset 明确创建为 ADODB.Recordset.

来自 chris neilsen 的评论:这是因为当我更改为后期绑定时,我的函数定义不再需要 Recordset 对象。

You are late binding, so can't have rsRecords As Recordset. Use rsRecords As Object

更改 PopulateDictionaryFromRecordset 函数的定义解决了问题:

Public Sub PopulateDictionaryFromRecordset(dDictionary As Variant, rsRecords As **Object**, aColumns As Variant)