繁体   English   中英

VBA-使用.NET类库

[英]VBA - Using .NET class library

我们有一个自定义类库,该类库是从头开始构建的,可以执行适当的业务模型所需的各种功能。 我们还使用VBA自动从标准Microsoft软件包和SolidWorks中插入一些数据。

迄今为止,我们基本上已经在VBA应用程序宏中重新编写了代码,但是现在正在将类库包含到VBA引用中。 我们已经为COM互操作注册了类库,并确保它对COM可见。 该文件是可引用的,我们在每个Public <ClassInterface(ClassInterfaceType.AutoDual)> _上方添加了<ClassInterface(ClassInterfaceType.AutoDual)> _标记,以便智能操作。

话虽如此,现在出现了问题-当我们引用类库时,对于该实例,我们将其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

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

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

在执行此操作之前,我将其放在对象浏览器中,该浏览器的“类”部分中同时包含ISQLCalls和SQLCalls 在此处输入图片说明

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

通过在SQLCalls类中输入<ClassInterface(ClassInterfaceType.None)> _ ,对象浏览器看起来会更好一些:

在此处输入图片说明

瞧瞧,我现在可以创建该类的新实例,并公开这些方法。

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

非常感谢vba4all,他花了无私的时间来协助解决此问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM