none
Relationship between Style.LinkToListTemplate, ListLevelNumber and ListTemplate? RRS feed

  • Question

  • Hi,

    I am studying the Word object model for VBA. And for Style object, I get confused on the following method and properties:

    Style.LinkToListTemplate (It seems to attach and apply a style to a list template)

    Style.ListLevelNumber (It seems that each style has a fixed list level number)

    Style.ListTemplate (It seems that a list template is attached to a style. Then why there will need such a method LinkToListTemplate to attach a style back to a list template?)

    I just write a small VBA code as follows:

        Dim MyListTemplate As ListTemplate

        Dim MyStyle As Style

       

        Set MyStyle = ActiveDocument.Styles.Item(1)

        Set MyListTemplate = MyStyle.ListTemplate

    MyStyle.LinkToListTemplate (MyListTemplate)

    It will get the ListTemplate in the MyStyle, then try to call LinkToListTemplate to re-attach the MyStyle to MyListTemplate. But the final statement will raise an error “Object does not support the method”. Don’t understand why.

    Friday, October 12, 2018 6:43 AM

All replies

  • Hi chcw,

    ListTemplate is a property of Style, so it can't be a Variable type. You should delete this line 'Dim MyListTemplate As ListTemplate'.

    Please use the code as below:

    Sub getListTemplate()
        Dim MyStyle As Style
        Set MyStyle = ActiveDocument.Styles.Item(1)
        Set MyListTemplate = MyStyle.ListTemplate
        MyStyle.LinkToListTemplate (MyListTemplate)
    End Sub

    For more information, please review the following link:

    Style.ListTemplate Property (Word)

    Hopefully it helps you.

    Best Regards,

    Lina


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.



    • Edited by Lina-MSFT Friday, October 12, 2018 9:17 AM
    Friday, October 12, 2018 9:11 AM
  • Hi chcw,

    ListTemplate is a property of Style, so it can't be a Variable type. You should delete this line 'Dim MyListTemplate As ListTemplate'.

    Please use the code as below:

    Sub getListTemplate()
        Dim MyStyle As Style
        Set MyStyle = ActiveDocument.Styles.Item(1)
        Set MyListTemplate = MyStyle.ListTemplate
        MyStyle.LinkToListTemplate (MyListTemplate)
    End Sub

    For more information, please review the following link:

    Style.ListTemplate Property (Word)

    Hopefully it helps you.

    Best Regards,

    Lina



    I have read the document for Style.ListTemplate. It just said the property returns the ListTemplate for the style. So if I understand correctly, a ListTemplate can be attached to a Style, while a Style can also be attached to a ListTemplate via  LinkToListTemplate?
    • Edited by chcw Friday, October 12, 2018 9:35 AM
    Friday, October 12, 2018 9:34 AM
  • Hi chcw,

    Yes, your understanding is correct. You need to know that the ListTemplate cannot be used as a variable type.

    Best Regards,

    Lina


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.


    • Edited by Lina-MSFT Friday, October 12, 2018 9:45 AM
    Friday, October 12, 2018 9:41 AM
  • Hi chcw,

    Yes, your understanding is correct. You need to know that the ListTemplate cannot be used as a variable type.

    Best Regards,

    Lina


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.


    In such a case, why the last line of my codes does not work? I mean

    MyStyle.LinkToListTemplate (MyListTemplate)

    or

    MyStyle.LinkToListTemplate (MyStyle.ListTemplate)

    I try to attach the style to its own ListTemplate.

    Friday, October 12, 2018 10:26 AM
  • Hi chcw,

    Sorry for the late reply. You deleted this line 'Dim MyListTemplate As ListTemplate', it still does not work?

    Base on my test, it works well.

    Best Regards,

    Lina


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.


    • Edited by Lina-MSFT Monday, October 15, 2018 6:37 AM
    Monday, October 15, 2018 6:36 AM
  • Hi chcw,

    Sorry for the late reply. You deleted this line 'Dim MyListTemplate As ListTemplate', it still does not work?

    Base on my test, it works well.

    Best Regards,

    Lina


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.


    After deleting the line 'Dim MyListTemplate As ListTemplate', the code will work. But why? I check the document on ListTemplate at https://docs.microsoft.com/en-us/office/vba/api/word.listtemplate , it seems that ListTemplate is just a class type and should be able to be used in declaring a new varaible?
    • Edited by chcw Monday, October 15, 2018 7:24 AM
    Monday, October 15, 2018 7:21 AM
  • Hi chcw,

    As I said in my first reply, ListTemplate is a property of Style, so it can't be a Variable type.

    Best Regards,

    Lina


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.

    Monday, October 15, 2018 7:23 AM
  • Hi chcw,

    Thanks for your asking. Please remember to mark the replies(Include your solution) as answers if they helped and please help us close the thread.

     

    Thank you for understanding. If you have any question, or update, please feel free to let us know.

     

    I wish you a happy life!

     

    Best Regards,

     

    Lina


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread.

    Wednesday, October 17, 2018 6:02 AM
  • There are (at least) two parts to your question.

    The first is about the meaning of some members of the Style class, and the second is about the error you are seeing.

    On the first point, Lina has pointed out what the difference between Style.ListTemplate and MyStyle.LinkToListTemplate is - the first returns the current ListTemplate attached to the Style. The second allows you to change the Style's ListTemplate to a different ListTemplate. 

    A multi-level List Template will have 9 LisLlevels, each of which has various properties including numbering, indentation etc. When you use LinkToListTemplate, you can use the second parameter of the method call to specify the ListLevel you want this style to be linked to.

    Incidentally, IMO the fact that .ListTemplate is a property of the Style class does in itself mean that it is a read-only property. It could in principle be a read/write property. But in this case the Class designers have chosen to make it a readonly property and to provide a method to modify its value. It's not unreasonable to assume that they have done this because if you could do

    Set myStyle.ListTemplate = someListTemplate

    there would be no way to specify the ListLevel. So although they could have said, "well, if you try to change the ListTemplate that way, you can, but you'll always get level 1, but for anything else you'll have to use LinkToListTemplate". But I suppose they consider that it was better design to allow only one way to change it.

    In all cases, you are really talking about the Style having an associated ListTemplate. (In your question you suggest that the relationship one way around in one case, and the other way around in another case, but the relationship between styles and listtemplates is not very simple. I may try to address this later, but let's just say that as a consequence of changing the listtemplate for style B to the listtemplate of some other style, you may find that you end up with 2 listtemplates instead of one.)

    On the second point, the reason why you are seeing an error is actually because of a combination of the Dim statement and  the way you have written the call to the LinkToListTemplate.

    Briefly, when you call a method that does not return a result (cf. a VBA Sub), or you do not want the result, and you just use the name of the method to call it, you should not enclose the parameters in ().

    At the moment, you have

    MyStyle.LinkToListTemplate (MyListTemplate)

    What you need is

    MyStyle.LinkToListTemplate MyListTemplate

    That may be unfamiliar, especially if you are used to using a language such as C which does not distinguish between "Functions" and "Subs" in quite the same way, and always puts parameters inside (). If you prefer C-style syntax, you can do it this way:

    Call MyStyle.LinkToListTemplate(MyListTemplate)

    The rules are essentially: if you use Call, you must put the parameters inside (). If you do not use Call, you should not put the parameters inside ().

    If you have more than one parameter, and you do not use Call, putting the parameters inside () will actually generate a syntax error. So

    Call MySub(a,b)

    is OK, but

    MySub (a,b) is not

    When you use

    MySub (a) 

    what happens depends on what type of thing VBA decides "a" is. In essence, VBA insists that the result of the expression a must be a "simple data value", and that means that it can be, for example, an integer, a string, a variable declared as an Object (maybe), but what it cannot be is a variable declared as a specific type of object. If it is, you'll get a runtime error.

    So lets' say that MySub can accept one parameter of any type. Then

    MySub ("abc") should not cause an error and will in effect be the same as MySub "abc". Similarly for MySub (1+2)

    But in your case you have

    MyStyle.LinkToListTemplate (MyListTemplate)

    VBA sees this differently depending on how you declared MyListTemplate. To see what is going on, I suggest you use the VB Editor to step through the code, using the Locals Window to inspect the Type column for the MyListTemplate variable.

    When you declare it using

    Dim MyListTemplate As ListTemplate

    When you start running the Sub, the Type shows as ListTemplate. This is the "declared type" of the variable. After you have assigned a value to MyListTemplate, the Type shows as ListTemplate/ListTemplate, which means that both the "declared type" and the actual type are "ListTemplate"
    the "declared type" of  MyListTemplate is "ListTemplate", a specific type of object. In this case, the only way VBA can make a "simple data type" out of MyListTemplate is if the ListTemplate class has a Public default Property Get or function which returns a value of a simple data type. Now a lot of objects in the Word object model do have such a default - often it is .Item. But the ListTemplate class does not (you can look all of this up in View->Object Browser in the VB Editor). So VBA flags an error (438 I think).

    When you do not declare MyListTemplate

    VBA actually uses the default type, Variant for the variable. In the Locals window, when the routine starts, the Type of MyListTemplate is shown as Variant/Empty. After VBA has executed the assignment to MyListTemplate, it shows MyListTemplate as having Type Variant/Object/ListTemplate. So the "declared type" is Variant and the specifc type it contains is an Object of type ListTemplate.

    Now, when VBA evaluates (MyListTemplate), because the declared type is Variant, and that is actually considered to be a simple data type, VBA does not throw a runtime error, and in fact, the routine call will probably execute in the way you expect.

    As a comparison, suppose your Activedocument has one bookmark called "abc" and you run the following code:

    Dim MyBookmark As Bookmark
    Set MyBookmark = ActiveDocument.Bookmarks(1)
    MySub (MyBookMark)

    The VBA then behaves differently from your example because the Bookmark class does have a default member (.Name) which returns the Name of the bookmark as a string. So the effect is actually

    MySub "abc"


    Peter Jamieson


    Wednesday, October 17, 2018 1:53 PM