0
votes

My aim is to create an array of various global templates which I define in a table. My macro reads the table. If the name specifies an available template my array should hold the object. If the template can't be found the array should hold the name that couldn't be processed. ThisDocument is of docm type. It's assigned to Sfs(0) as the default. Here is an excerpt from my code.

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

My problem is with the line Set Sfs(0) = ThisDocument. In the next line of the test procedure Sfs(0) works correctly as an object, permitting a Bookmarks.Count. It's also shown as an object in the Locals window. However, the function GetTextTbl rejects it as "ByRef argument type mismatch" which it doesn't do when replaced with ThisDocument in the function call. This prompted me to look at its VarType which returns VbString instead of vbObject.

Let me add that I already have this idea working in Excel (with addins) but I need an equivalent in Word where I think the global template would meet my requirements if I could assign objects to the Sfs() variant. Any idea how to do that?

2
Remove your 2 debug.print lines and use this instead - Debug.Print Sfs(0).Bookmarks.Count - and that should prove that it's assigning the document object as you want.braX
Perhaps you are right but why does GetTextTbl(Tbl, Sfs(0), TnRef) - in the next line after the bookmark check (which works for me, too) - give a "ByRef argument type mismatch" error and GetTextTbl(Tbl, ThisDocument, TnRef) doesn't? Function GetTextTbl expects Doc As Document. It was this that prompted me to look at the VarType. I'll do some more testing. Thanks for the encouragement.Variatus
I have expanded the question as you suggest.Variatus
It probably needs to be casted from a generic object to an actual document object, but as a workaround, you can just change the function definition to Function GetTextTbl(Tbl As Table, Doc As Variant, Tn As String) As Boolean and it will work. That doesnt exactly answer your question, but it works if you put MsgBox Doc.Bookmarks.Count in your GetTextTbl() function.braX
I found another option for a workaround - use Object instead of Variant - Dim Sfs() As Object and Function SetSfs(Sfs() As Object) As Long - then you can use Function GetTextTbl(Tbl As Table, Doc As Document, Tn As String) As BooleanbraX

2 Answers

2
votes

Its a bit of a late answer but the solution to your problem is to use a collection rather than an array. Collections (or Scripting.Dictionaries) are a more natural way to work with objects.

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

0
votes

It would need to be casted from a Variant to an Object, but everything I have read on the subject online says that you cannot convert a Variant to an Object in VBA.

Your alternatives are to stick with using a Variant in all places (instead of the Document object) or stick with using an Object in all places, as they both seem to provide the functionality you need in this example.

So either change it to this (to use the variant method):

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

Or change both of these to this (to use the object method):

Dim Sfs() As Object 

Function SetSfs(Sfs() As Object) As Long 

Using it as an Object in all cases makes the most sense to me, as then you can use your original declaration of your GetTextTbl function as:

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

And then your intellisense will work inside of that function. Just make sure you do not pass an object to it that is something other than a Word Document or you will get an error.