【问题标题】:VBA - Using .NET class libraryVBA - 使用 .NET 类库
【发布时间】:2014-11-25 22:17:16
【问题描述】:

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

迄今为止,我们基本上已经重新编写了 VBA 应用程序宏中的代码,但现在正在将类库包含到 VBA 引用中。我们已经为 COM 互操作注册了类库,并确保它是 COM 可见的。该文件是可引用的,我们在每个公共类上方添加了<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/s。

但是,当我按照完全相同的过程尝试不同的课程时,我收到了错误 (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

【问题讨论】:

  • 您需要显示.SQLNumber() 方法的代码,可能还有.SQLCalls 类的代码。
  • 我可以输入.SQLNumber()方法,但是整个类本身就超过1000行。
  • 请与我们分享.SQLNumber(),因为我相信这可能至关重要。
  • 我已经加入了.SQLNumber() 方法,以及工作的.extractNumber() 方法进行比较。感谢您一直以来的帮助。
  • 好的,我看到的第一件事是不正确的是 .SQLNumber() 方法的返回类型 - 它是 double 并且您正试图将其分配给 VBA 中的 String t。你知道吗?

标签: vb.net vba excel com


【解决方案1】:

在 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,他们无私奉献了自己的时间来帮助解决这个问题。

【讨论】:

  • 感谢编辑,没有注意到链接已失效。问题的答案在正文中,因此不需要指向旧页面的链接。
猜你喜欢
  • 2011-05-11
  • 2020-05-10
  • 2013-11-26
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多