尝试调用外部 VBA 函数时,只能强制在公共对象模块中定义的用户定义类型

Posted

技术标签:

【中文标题】尝试调用外部 VBA 函数时,只能强制在公共对象模块中定义的用户定义类型【英文标题】:Only user-defined type defined in public object modules can be coerced when trying to call an external VBA function 【发布时间】:2014-07-30 20:42:17 【问题描述】:

我正在尝试从 Excel 调用 Access 函数并收到此错误:

编译错误:只有在公共对象中定义的用户定义类型 模块可以强制转换为变体或从变体强制转换或传递给后期绑定 功能。

我尝试采用我找到的这个solution,但没有运气。这是我的代码:

在 Excel 模块 ExternalStatistics 中

Option Explicit

    Public Type MyExternalStatistics
        esMyInvites As Single
        esMyInvitePerTalk As Single
    End Type

Public MyExtRecStats As MyExternalStatistics

在 Sheet1(A-Crunched Numbers) 对象中:

Option Explicit

Public appRecruitingAccess As Access.Application

Public Sub Worksheet_Activate()
    Dim MyExtRecStats As MyExternalStatistics
    Dim RecruitWindow As Integer
    Dim test As String 

    Set appRecruitingAccess = New Access.Application
    With appRecruitingAccess
        .Visible = False
        .OpenCurrentDatabase "C:\Dropbox\RECRUITING\Remote0\Recruiting 0.accdb"
        RecruitWindow = DateDiff("d", Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveStart").Value), Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveEnd").Value))
        RecruitWindow = DateDiff("d", Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveStart").Value), Format(Date, Worksheets("ActivityAndIncentive").Range("IncentiveEnd").Value))
        MyExtRecStats = .Run("ExternalRecruitingStats", RecruitWindow) '*** ERROR HERE ***
        .CloseCurrentDatabase
        .Quit
    End With
    Set appRecruitingAccess = Nothing
End Sub

在访问模块外部统计中

Option Compare Database
Option Explicit

Public Type MyExternalStatistics
    esMyInvites As Single
    esMyInvitePerTalk As Single
end Type

Public Function ExternalRecruitingStats(StatWindow As Integer) As MyExternalStatistics 
    Dim MyRecStats As MyExternalStatistics
    Dim Invites As Integer, Talks As Integer

    Invites = 1
Talks = 2

    With MyRecStats
        .esMyInvites = CSng(Invites)
        .esMyInvitesPerTalk = CSng(Invites/Talks)
    End With
    ExternalRecruitingStats = MyRecStats 'return a single structure
End Function

它不喜欢MyExtRecStats = .Run("ExternalRecruitingStats", RecruitWindow) 语句。我想最终在 Access 函数中分配几个集合,并用一个对象将它们全部带回来。然后,我可以将这些值放在电子表格中应放在的位置。

【问题讨论】:

您是否有理由不使用 Excel 中的数据库查询来提取您需要的数据?在我看来,这会更容易、更有效。 最终我需要让该函数向 Excel 提供至少 36 个数据点。我正在使用一个字符串并解析该字符串,这是有效的,但我上面所做的研究似乎是完成它的一种更有效的方法。我不知道可以为我做到这一点的查询方法。接受建议... 【参考方案1】:

VBA 中的类型定义非常本地化,当您尝试将它们与可能无法访问类型的确切定义的对象一起使用时它们无法正常工作(这里可能就是这种情况)。

有时,使用Class 可能会起作用。您需要在传递它之前将类公开并实例化它,但我怀疑它是否真的有效(出于同样的原因,类定义不会从一个应用程序到另一个应用程序可见)。

另一个简单的解决方案是使用一个简单的Collection 对象,您可以在其中将值作为项目添加到集合中。当然,添加/检索项目的确切顺序很重要。

User Defined Type (UDT) As Parameter In Public Sub In Class Module 中有类似问题的一些有趣答案。它是关于 VB6 的,但它也应该在很大程度上适用于 VBA。

说了这么多,您也许可以通过将 Access 代码导入 Excel 来解决所有问题。 您可以在 Excel 中使用 DAO 或 ADO 并像在 Excel 中一样操作 Access 数据库,例如:

Connecting to Microsoft Access Database from Excel VBA, using DAO Object Model Using Excel VBA to Export data to Ms.Access Table

【讨论】:

以上是关于尝试调用外部 VBA 函数时,只能强制在公共对象模块中定义的用户定义类型的主要内容,如果未能解决你的问题,请参考以下文章

尝试调试调用 C++ DLL 的 VBA,“未加载 wntdll.pdb”

对象的私有/公有/静态/特权 属性/方法

在VBA中,怎样打开或者调用另一个EXCEL文件

Excel中的VBA如何调用Java呀?

vba如何调用dll中的过程函数或变量

如何在excel中使用VBA调用其它外部程序