我正在编写VBA UDF来检索有关编码位置的地理数据。
我有一个Excel工作簿,其中包含共享位置的所有详细信息。
当用户在其工作簿上输入UDF并提供所请求的编码参数时,会发生以下情况:
(如果现有字典在步骤1之前已经存在于内存中,则会重复使用。)
在我的计算机上工作正常,但测试它会导致另一台计算机出现明显的引用错误。所以我切换到代码中对象的后期绑定。现在,当我在上面的步骤2中传递记录集时,某些内容会被破坏。我得到了13型不匹配错误。
这是(部分剪辑的)代码。
我知道问题出在recordset参数上,因为从调用中删除它并且函数声明成功调用了函数,但当然它稍后会失败。
!!!是用来说明代码失败的地方。
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。
答案 0 :(得分:1)
来自chris neilsen的评论:这是因为当我改为后期绑定时,我的函数定义不再期望Recordset对象。
你是后期绑定,因此不能将rsRecords As Recordset。使用rsRecords As Object
更改PopulateDictionaryFromRecordset函数的定义解决了问题:
with aa as (
select count(*) count
from [PRODUCTTAG]
where ProductID = '19A947C0-6A0F-4A6F-9675-48FBE30A877D'
), bb as
(
select ProductID, count(*) count
from [PRODUCTTAG]
group by ProductID
)
select distinct b.ProductID
from [dbo].[PRODUCTTAG] a join
[dbo].[PRODUCTTAG] b on a.TagID = b.TagID cross join
aa join
bb on aa.count = bb.count and b.ProductID = bb.ProductID
where a.ProductID = '19A947C0-6A0F-4A6F-9675-48FBE30A877D'