代码之家  ›  专栏  ›  技术社区  ›  mikstravaganza

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

  •  0
  • mikstravaganza  · 技术社区  · 8 年前

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

    我有一个Excel工作簿,所有详细信息都在一个共享位置。

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

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

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

    在我的电脑上工作正常,但在另一台电脑上测试它会导致明显的参考错误。所以我换了 后期绑定 对于代码中的对象。现在,当我在上面的步骤2中通过记录集时,有些东西被破坏了。我得到一个类型13不匹配错误。

    这是(部分剪断的)代码。

    • sSQL是要在共享工作簿上执行的查询,在UDF中定义
    • sPath也在UDF中定义
    • VDestation可以是一个工作表(从记录集触发PopulateSheetFromRecordset以将记录集转储到一个工作表上以便可视化),也可以是一个字典(此处讨论的用例)
    • aColumns是一个数组,它传递有关记录集字段的信息,以确定哪些是键,哪些是值

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

    这个是否有说明代码失败的地方。

    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)
    

    似乎更改为后期绑定更改了与记录集对象类型相关的其他内容。研究表明,这可能是因为存在多种类型的记录集对象,但我已将objMyRecordset显式创建为ADODB。记录集。

    1 回复  |  直到 7 年前
        1
  •  1
  •   mikstravaganza    8 年前

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

    您正在延迟绑定,因此不能将rsRecords作为记录集。将rsRecords用作对象

    更改记录集函数PopulateDictionaryFromRecordset的定义解决了以下问题:

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