我们有一个自定义类库,它是从头开始构建的,它执行商业模型所需的各种功能。我们还使用VBA自动从标准Microsoft软件包和SolidWorks中插入一些数据。
到目前为止,我们基本上已经在VBA应用程序宏中重写了代码,但现在正在将类库包含到VBA引用中。我们已经为COM interop注册了类库,并确保它是COM可见的。该文件是可引用的,我们在每个公共类上面添加了<ClassInterface(ClassInterfaceType.AutoDual)> _
标记,以便intellisense“有效”。
话虽如此,问题现在出现了 - 当我们引用类库时,对于这个实例,我们称之为Test_Object
,它被拾取并且似乎工作得很好。因此,我们继续尝试一个小样本,以确保它使用公共函数并返回预期值:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim test As New Test_Object.Formatting
Dim t As String
t = test.extractNumber("abc12g3y45")
Target.Value = t
End Sub
这按预期工作,在所选单元格中返回12345。
然而,当我尝试不同的类时,遵循完全相同的过程,我收到错误(Object variable or With block variable not set
)。代码如下:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim test As New Test_Object.SQLCalls
Dim t As String
t = test.SQLNumber("SELECT TOP 1 ID from testdb.dbo.TESTTABLE") 'where the string literal in the parentheses is a parameter that is passed.
Target.Value = t
End Sub
t = test.SQLNumber
行失败。它也在SQLCalls
类中的另一个函数失败,该函数以SQL格式返回日期(因此它与数据库的连接无关)。
任何人都可以协助导致此错误的原因吗?我用谷歌搜索了几个小时无济于事,我愿意尽一切努力让它发挥作用。
干杯。
编辑:(在.SQLNumber()
方法中添加)
Function SQLNumber(query As String) As Double
Dim tno As Double
Try
Using SQLConnection As SqlConnection = New SqlConnection(Connection_String_Current)
SQLConnection.Open()
SQLCommand = New SqlCommand(query, SQLConnection)
tno = SQLCommand.ExecuteScalar
End Using
Catch ex As System.Exception
MsgBox(ex.Message)
End Try
Return tno
End Function
为了进行比较,extractNumber()
方法:
Function extractNumber(extstr As String) As Double
Dim i As Integer = 1
Dim tempstr As String
Dim extno As String = ""
Do Until i > Len(extstr)
tempstr = Mid(extstr, i, 1)
If tempstr = "0" Or tempstr = "1" Or tempstr = "2" Or tempstr = "3" Or tempstr = "4" Or tempstr = "5" Or tempstr = "6" Or tempstr = "7" Or tempstr = "8" Or tempstr = "9" Or tempstr = "." Then
extno = extno & tempstr
End If
i = i + 1
Loop
If IsNumeric(extno) Then
Return CDbl(extno)
Else
Return 0
End If
End Function
答案 0 :(得分:0)
在vba4all的帮助下,我们设法深入研究了这个问题。
当我尝试使用Dim x as new Test_Object.SQLCalls
创建对象的新实例时,我完全忘记了我没有重新进入这个关键线的事实:
<ClassInterface(ClassInterfaceType.None)> _
。
在这之前,我在我的对象资源管理器中有这个,它在Classes部分同时具有ISQLCalls和SQLCalls
但是等等,ISQLCalls不是一个类,它是一个接口!
通过在SQLCalls类中输入<ClassInterface(ClassInterfaceType.None)> _
,对象资源管理器看起来好一点:
然后,我可以创建一个新的类实例,然后公开这些方法。
tldr:
我需要显式声明接口并在接口上使用<InterfaceType(ComInterfaceType.InterfaceIsDual)>
并在类上使用<ClassInterface(ClassInterfaceType.None)>
。
非常感谢vba4all,他无私地投入时间协助解决这个问题。