将 Word 对象分配给 VBA 中的 Variant 变量

Assign Word Object to Variant Variable in VBA

我的目标是创建我在 table 中定义的各种全局模板的数组。我的宏读取 table。如果名称指定了一个可用的模板,我的数组应该保存该对象。如果找不到模板,则该数组应包含无法处理的名称。 ThisDocument 是 docm 类型。它默认分配给 Sfs(0)。这是我的代码的摘录。

Private Sub TestSetSfs()
    Dim Sfs() As Variant
    SetSfs Sfs
    Debug.Print Sfs(0).Name
    Debug.Print VarType(Sfs(0))             ' returns vbString
End Sub

Function SetSfs(Sfs() As Variant) As Long

    Dim Tbl As Table

    ReDim Sfs(20)                           ' max 20 references
    Set Sfs(0) = ThisDocument

    Debug.Print Sfs(0).Bookmarks.Count      ' works as expected
    Debug.Print VarType(Sfs(0))             ' returns vbString
    Debug.Print GetTextTbl(Tbl, Sfs(0), "SomeName")
End Function

Function GetTextTbl(Tbl As Table, Doc As Document, Tn As String) As Boolean
    GetTextTbl = True
End Function

我的问题出在行 Set Sfs(0) = ThisDocument 上。在测试程序的下一行中,Sfs(0) 作为对象正确工作,允许 Bookmarks.Count。它也显示为 Locals window 中的一个对象。但是,函数 GetTextTbl 将其拒绝为 "ByRef argument type mismatch",而在函数调用中将其替换为 ThisDocument 时它不会这样做。这促使我查看它的 VarType,其中 returns VbString 而不是 vbObject。

让我补充一点,我已经在 Excel(使用插件)中实现了这个想法,但我需要 Word 中的等效项,我认为如果我可以将对象分配给 Sfs,全局模板将满足我的要求() 变体。知道怎么做吗?

它需要从 Variant 转换为 Object,但我在网上阅读的关于该主题的所有内容都表明您不能将 Variant 转换为 Object 在 VBA.

您的替代方案是坚持在所有地方使用 Variant(而不是 Document 对象)或坚持在所有地方使用 Object,因为它们看起来都一样以提供您在此示例中需要的功能。

因此要么将其更改为(以使用变体方法):

Function GetTextTbl(Tbl As Table, Doc As Variant, Tn As String) As Boolean

或者将这两个都改成这样(使用对象方法):

Dim Sfs() As Object 

Function SetSfs(Sfs() As Object) As Long 

在所有情况下将其用作 Object 对我来说最有意义,因为这样您就可以将 GetTextTbl 函数的原始声明用作:

Function GetTextTbl(Tbl As Table, Doc As Document, Tn As String) As Boolean

然后您的智能感知将在该函数内部运行。只要确保您没有将 Word 文档以外的对象传递给它,否则您会收到错误消息。

它的回答有点迟了,但解决您的问题的方法是使用集合而不是数组。集合(或 Scripting.Dictionaries)是处理对象的更自然的方式。

Private Sub TestSetSfs()
    Dim Sfs As Collection
    Set Sfs = New Collection
    SetSfs Sfs
    Debug.Print Sfs.Item(1).Name
    Debug.Print VarType(Sfs.Item(1))             ' returns vbString
End Sub

Function SetSfs(ByVal Sfs As Collection) As Long

    Dim Tbl As Table

    
    Sfs.Add ThisDocument

    Debug.Print Sfs.Item(1).Bookmarks.Count      ' works as expected
    Debug.Print VarType(Sfs.Item(1))             ' returns vbString
    Debug.Print GetTextTbl(Tbl, Sfs.Item(1), "SomeName")
End Function

Function GetTextTbl(Tbl As Table, Doc As Document, Tn As String) As Boolean
    GetTextTbl = True
End Function