【问题标题】:Late Binding a UDT in a form module to pass as a parameter后期在表单模块中绑定 UDT 以作为参数传递
【发布时间】:2020-07-13 20:04:57
【问题描述】:

我有一个访问数据库,我正在尝试编写一些 VBA 来提高自动化程度。

我有一个名为 Global Variables 的模块,我已经成功地使用它来定义全局常量(文件路径等)和一个模块 ReportCode,它有两个主要子程序,一个用于使用 ADODB 运行查询(在需要时抓取表单参数 - 返回一个记录集),第二个获取该记录集并将数据写入 Excel 模板。

鉴于我可能希望将多个查询写入多个选项卡,我认为最好的方法是定义一个 ExportDocument 对象以包含公共参数和一个 OrgReport 对象,其中包含查询和选项卡特定参数 - 然后收集多个 @ 987654329@ 集合中的对象。

我希望只将这两个参数传递到主子例程中。事实证明,这在 VBA 中是一种痛苦(或者至少与 ruby​​ 相比!)。

在这里你可以看到我是如何通过自定义对象定义的

Option Private Module

' Define Custom Doc Object
Public Type ExportDocument
    TeamName As String
    TemplatePath As String
    SaveName As String
    SavePath As String
End Type

' Define Custom Report Object
Public Type OrgReport
    Query As String
    Fields As Variant
    Sheet As String
    StartCol As Integer
    StartRow As Integer
    Headers As Boolean
End Type

这是我表单中的代码,然后调用了一个额外的模块来完成繁重的工作 - 我知道这部分有效,因为它在我尝试对此进行所有 OOP 之前就已经完成了......

Private Sub my_report_from_form_Click()

    ' Prep Query Inputs
    Dim TeamX_Report As OrgReport

    TeamX_Report.Query = "qry_TeamReporting Query"
    TeamX_Report.Sheet = "RawData"
    TeamX_Report.StartCol = 1
    TeamX_Report.StartRow = 2
    TeamX_Report.Headers = True
    TeamX_Report.Fields = Nothing

    ' Prep Document Inputs
    Dim Teamx_Doc As ExportDocument

    Teamx_Doc.TeamName = "MyTeam"
    Teamx_Doc.TemplatePath = strReportTemplatePath & "MyTeam.xltm"
    Teamx_Doc.SaveName = ""
    Teamx_Doc.SavePath = strReportSavePath & Teamx_Doc.TeamName

    ' Init and set collection for CHAIN reports
    Dim TeamReports As New Collection
    TeamReports .Add Item:=TeamX_Report, Key:=TeamX_Report.Query

    Call export_data_dump(Teamx_Doc, TeamReports)
End Sub

这给了我以下问题:

Only public user defined types defined in public object modules can be used as parameters or return types for public procedures of class modules or as fields of public user defined types

听从here的建议我改变了

Dim Teamx_Doc As ExportDocument

Teamx_Doc = CreateObject("ExportDocument")

但是现在我明白了

运行时错误“429”:ActiveX 组件无法创建对象 VBA

对这个问题的所有引用似乎都与从Word.Excel.Outlook. 代码库调用代码有关,所以也许我只是缺少存储在我的数据库中的我自己的模块的前缀?

我发现的最佳线索是 one,这似乎表明我正在尝试做的事情存在更深层次的问题,或者我可以通过调用 Friend 来解决部分问题,尽管我迷路了地点和方式。

有没有一种方法可以在我的表单代码中后期绑定我的 UDT 对象,将一个存储在集合中,然后将两者都传递给一个子例程,该子例程将能够从第一个“Doc”对象中获取参数,然后遍历第二个“报告”对象?

VBA >_

【问题讨论】:

  • 你试过删除“选项私有模块”

标签: excel ms-access vba


【解决方案1】:

我没有理由明白为什么这不起作用:

Dim Teamx_Doc As ExportDocument

特别是如果您没有在线收到错误

Dim TeamX_Report As OrgReport

我以前使用过自定义公共类型 - 不需要 CreateObject

虽然文档似乎说没问题,但您可以尝试删除

Option Private Module

【讨论】:

  • 最初也是我,但我认为这是一个早期绑定的例子,我的错误消息说它不起作用!
  • 如果您在自己的代码中定义公共类型,则它不是早期绑定。早期的 bindng 更多是指设置对外部 DLL 或 ActiveX 对象的引用
  • 嗯...好吧,也许是因为我试图将我的代码组织在不同的模块中...我尝试先从那里删除选项私有模块,然后将所有模块复制到同一个模块中。顶部的模块...不知道为什么它不起作用,我的常量是!
  • 您不需要将所有代码复制到一个模块中。如果您不希望在模块外看到它们,只需将每个模块内的常量和函数设为 PRIVATE。任何共享函数或常量都应标记为 PUBLIC - 我认为这是默认值
  • 好吧……经过仔细检查(并且所有内容都设置为公开的所有内容),我相信当我尝试将我的对象添加到集合时会出现问题。调试在TeamReports .Add Item:=TeamX_Report, Key:=Teamx_Doc.Query 处停止,TeamX_Report 突出显示,然后抛出唯一的公共......这可能更多地与我如何将对象添加到集合中有关?
【解决方案2】:

错误信息有点误导。您根本无法将具有用户定义类型的变量放入集合中。

选项 1:改用 数组。这实际上听起来很适合您想做的事情。

选项 2:为 OrgReport 创建一个类模块,而不是 UDT。然后实例化该类的对象,您可以将它们添加到集合中。


Excel VBA Collections and Custom Data Types

http://www.mrexcel.com/forum/excel-questions/16849-adding-user-defined-types-collection.html

【讨论】:

  • 选项 1 看起来很有希望,非常感谢。将对数组进行更多阅读并尝试一下!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多