VBA - 使用.NET类库

时间:2014-10-01 06:15:49

标签: vb.net excel vba excel-vba com

我们有一个自定义类库,它是从头开始构建的,它执行商业模型所需的各种功能。我们还使用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

1 个答案:

答案 0 :(得分:0)

在vba4all的帮助下,我们设法深入研究了这个问题。

当我尝试使用Dim x as new Test_Object.SQLCalls创建对象的新实例时,我完全忘记了我没有重新进入这个关键线的事实: <ClassInterface(ClassInterfaceType.None)> _

在这之前,我在我的对象资源管理器中有这个,它在Classes部分同时具有ISQLCalls和SQLCalls enter image description here

但是等等,ISQLCalls不是一个类,它是一个接口!

通过在SQLCalls类中输入<ClassInterface(ClassInterfaceType.None)> _,对象资源管理器看起来好一点:

enter image description here

然后,我可以创建一个新的类实例,然后公开这些方法。

tldr: 我需要显式声明接口并在接口上使用<InterfaceType(ComInterfaceType.InterfaceIsDual)>并在类上使用<ClassInterface(ClassInterfaceType.None)>

非常感谢vba4all,他无私地投入时间协助解决这个问题。