Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Running code in a different Word template (Word 2000 SR1a)

    I originally asked <A target="_blank" HREF=http://www.wopr.com/cgi-bin/w3t/showflat.pl?Cat=&Board=wrd&Number=102240>this </A> in the word forum. It was suggested that it would be better if I clarified the question and posted it here.

    I have a Word document - say <font color=red>Stuart.Doc</font color=red>
    This document is attached to a template in my Templates folder - say <font color=red>Template.Dot</font color=red>
    Template.Dot has many procedures and user forms.

    I also have a Global Template - say <font color=red>Global.Dot</font color=red>
    Global.Dot has many procedures and user forms, it also has a toolbar.

    When I click a particular button on the toolbar I want it to do something different if the ActiveDocument is using Template.Dot as its template. This is fairly easy if all the code and userforms are in Global.Dot. Some of the code I want to run is identical to code already in a UserForm in Template.Dot. Ideally I want the Macro running in Global.Dot to detect that the ActiveDocument has Template.Dot as its template and then to Show a user form in Template.Dot instead of its own user form.

    So - finally - to the specific question. Is there a way to specify a different (already loaded) Template in a command like
    <pre> frmMyform.Show
    </pre>

    I imagine a syntax like
    <pre> myTemplate!frmMyform.Show
    </pre>


    StuartR

  2. #2
    Super Moderator jscher2000's Avatar
    Join Date
    Feb 2001
    Location
    Silicon Valley, USA
    Posts
    23,112
    Thanks
    5
    Thanked 93 Times in 89 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    I think form objects are a bit harder to reach than Sub procedures. Maybe you can start with this in Global.dot and tackle the direct form call later:
    <pre>Sub MacroRun()
    With Dialogs(wdDialogToolsMacro)
    .Name = "foreignSubProcedureName"
    .Run = True
    .Execute
    End With
    End Sub</pre>

    Of course, the foreign sub procedure would load its local form. If you need to return values from the UserForm to your global procedure, I think this might present a scope problem. Public vars are not visible outside of Template.dot (I can't remember); if not, you could use a text file or the registry to pass values.

    If you prefer to call a Function rather than a Sub procedure, you have to resort to the old WordBasic Call syntax:
    <pre>returnVar = WordBasic.Call("ModuleName.FunctionName"[, parameter1[, parameter2 etc.]])</pre>

    For safety's sake, you should give the module a very unique name.

    Hope this helps.

  3. #3
    Super Moderator
    Join Date
    Dec 2000
    Location
    New York, NY
    Posts
    2,970
    Thanks
    3
    Thanked 29 Times in 27 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    Application.Run ("macroname") is relevant here - more direct than using the dialog. You can also add up to 30 arguments to pass to the procedure(!). - see the Word VBA help for Run method.

  4. #4
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    Thanks for all the help, I'm nearly there. One last question (I hope <img src=/S/smile.gif border=0 alt=smile width=15 height=15>)

    To make the error handling, I would like to check that the Macro exists in the target module. Is there a way to get a list of Modules in a Project?

    Looking in the VB help I can see things like VBCodeModule, but I can't quite see how to use them to get a list of procedures.

    StuartR

  5. #5
    Super Moderator
    Join Date
    Dec 2000
    Location
    New York, NY
    Posts
    2,970
    Thanks
    3
    Thanked 29 Times in 27 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    Stuart,

    Far as I know, there is (annoyingly) no direct way to do this. It's just something that was left out of the Office/VBA object model.

    For an entertaining discussion of this, see <A target="_blank" HREF=http://www.wopr.com/cgi-bin/w3t/showthreaded.pl?Cat=&Board=vb&Number=44600&page=0& view=expanded&sb=5&o=0#Post44600>this post</A> by Chris Greaves and the ones that follow it.

    Probably the best you can do is test-run the code with a name that you know will raise an error, make note of the error number, and then trap for that in the error handler.

    Gary

  6. #6
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    Thanks for all the help. I guess I'll just have to trap any error I get when I try to call the Macro.

    StuartR

  7. #7
    Gold Lounger
    Join Date
    Dec 2000
    Location
    New Hampshire, USA
    Posts
    3,386
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    I'm a bit off today, so the following is in rambling mode.

    WOPR.Posting.Mode. Rambling = True

    Instead of trying to invoke the userform in the other template, try the following:

    1. In the other template, insert a Public module that does nothing but invoke the userform.
    2. The module would have an arg list to return whatever.
    3. Any macro that wanted to invoke that userform would call the Public module with appropriate args to retrieve the error code, etc.

    WOPR.Posting.Mode. Rambling = False

  8. #8
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    Thanks, that's exactly what I am testing now.

    StuartR

  9. #9
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    >When I click a particular button on the toolbar

    When you click a button on the toolbar, you are, by definition, running a macro, but specificially one tied to a toolbar button. Macros tied to toolbar buttons are weird things.

    Charles Kenyon also did some reserach on how macros are linked to toolbar buttons. My feeling is that the toolbar button has an absulte address, carved in stone, which address includes the macro name, the module name and the template name (and possibly the template path). Clicking on a toolbar button is therefore very explicit.



    If you rephrase your question to "How can I have a macro cause conditional execution of code", then the process ought to be fairly easy.

    Consider writing a simple macro, same name ("myMacro"), same module, but in different templates. When you try to execute myMacro, which macro gets executed, and how does it depend on what templates are loaded and available?

    The means of determining which macro gets run (by an Application.Run with no excess baggage) is, I suspect, up for grabs, and has been since the days of The UnderGround Guide To Word for Windows" (p 99-101 are what I'm thinking of, I think) where Woody discusses the means by which Word determines which macro gets called).

    In Word6 I once ran an experiment with identically named macros in identically named modules in different templates, just to see the effect of the name sequence of the templates on the selection of macros to execute.

    Once you establish this general principal your way is clear to have any number of macros doing any number of things depending on the run-time template environment.


    I'm rambling, I know.

    Make a toolbar button that runs a macro via Application.Run and let Word determine which version of that macro gets run. That's what I'm thinking.

    This technique ought to work for all situations. Word will select the appropriate macro, within each macro you will perform the conditional action. The action might be as simple as loading a form local to the host template (your original request) or setting a global switch (in INI file, registry or global or static variable) that permits some other conditional execution down the line.



    You're probably going to have to get someone else in the lounge to interpret what I've written, or wait for me to get some more sleep.


    I think that it is worthwhile solving the general problem of conditional execution of code based on what templates are available, and then use that solution in any specific application.

  10. #10
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    OK.

    1. Created a template Erase1.dot, in it composed a macro myMacro:
    <pre>Sub myMacro()
    MsgBox "myMacro in Template Erase1"
    End Sub
    </pre>


    2. Created a document Erase1.doc, in it composed a macro myMacro:
    <pre>Sub myMacro()
    MsgBox "myMacro in Document Erase1"
    End Sub
    </pre>


    3. In Normal.dot created a macro aaTest:
    <pre>Sub aaTest()
    Application.Run ("myMacro")
    End Sub
    </pre>


    4. In the active document Erase1.doc, ran the macro aaTest; witnessed the message "myMacro in Document Erase1".

    5. Closed the active document Erase1.doc, ran the macro aaTest; witnessed the message "myMacro in Template Erase1".


    I could have placed a link to aaTest as a button on the standard toolbar of Normal.dot. The result would have been the same. Toolbar buttons confuse the issue for now (mainly on account of the way that they can become dissociated from their macro definition).


    This simple (and reproducible) test shows that a single macro (aaTest) could garner data about its environment, in this case, it could determine whether a macro of a global template was available, whether a macro more local (to the active document) was available etc.

    On this base one could build a nifty structure that determined which of several identically-named macros sets was being invoked, whether a local add-in layer, a global startup layer, or a document layer was predominant. "Layer" is probably not the right word to use here.


    I am not sure of the scope of public subroutines in forms. I believe that they are invisible if the form is not loaded; that restricts their use somewhat, but could be beneficial in our situation, since I could have a myMacro as a public subroutine in the form's code module, and as a public subroutine in a user code module in the template that houses the form. With the form not loaded I should execute the macro from the code module. With the form loaded I have a chance of executing the macro in the form module, especially if I am calling the macro from the code of the form module itself.


    I have not really explored the sequence used by Word97SR2 in determining which macro gets called. Woody wrote something in TUG or Hackers that suggested a sequence of calls, but even then I don't think it was definitive.

    What happens if a Startup template is active, then is unlinked (Tools, Templates, Global, uncheck) and is then brought back in as Tools, Templates, Add? Does it move to the end of the line because it is a more recent addition? It ought to be difficult enough (sic) to determine this sort of thing assuming that Word is consistent in the way it maintains its lists of available macros, but if Word/Harold fills in gaps in tables as it goes, then the behaviour would most probably be unpredictable.


    For those of you who plan on being bored over the Christmas Break, the first step would be to identify all the PLACES where myMacro could be stored (in a user form, in a user module, in a document module, in the attached template module, in a template module, as a Startup template, as a Workgroup template, as a User template etc) and then a second list of the chronological sequence in which items were made visible or not (User form loaded/unloaded, document active/not active, template checked out/in) etc), and then, while dynamically running through all permutations, build a table showing permutations, and from that table, list which version of the macro was being called in, and from THAT a theory of how Word determines which version of the macro is called in.

    That theory ought be posted here, and then tested by a second person using a different structure, a different set of names etc to see if they can repeat the experiment and duplicate the results.


    In any case, understanding what happens in the general case is going to be the first step towards determining a solution that is guaranteed to work ALWAYS for your production code.



    If anyone does decide to try it out, I've just re-read pages 99-103 of TUG, and if I were having a stabat the matter (sorry Geoff!) I'd start off real simple, with just a macro myMacro in a user module of the ActiveDocument, and an aatest in the Normal.dot, both as outlined above, and check that that works.

    Then I'd introduce a second version of myMacro, and see where the second version fits into the hierarchy. Suppose you introduced the second version into Normal.dot. Can you ever NOT execute that macro? That is, does a version within Normal.dot inhibit all other (right now, "the only other") verions? If so, I'd set that as Rule 1, then introduce a 3rd version, perhaps in a Startup template, and figure that one out, then ring the changes with the Normal.dot to make sure Rule1 still works, and thus declare create Rule2 based on experience with the Startup. Then cautiously add a fourth version to determine Rule3, and so on.


    It's time-consuming and I'm not surprised that Woody caveated hisself near to death. Woody does point out that Word(version 6) says it does things alphabetically, but appears to put afterthoughts at the end of the list chronologically, disregarding alphabetic sequence, so even a macro in a Startup template might get jostled to the end of the line if it were inadvertently checked off then immediately checked back on, as in "ooops".

    Here be dragons, more terrifying than any I've read about in the only Harry Potter book I've read.

    I probably shan't get much sleep again tonight.

    Especially if I'm thinking of what I've put in my Christmas stocking for myself to discover in the morning.

  11. #11
    Gold Lounger
    Join Date
    Dec 2000
    Location
    New Hampshire, USA
    Posts
    3,386
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    Invoking a macro by a toolbar is no different than invoking that same macro by a menu, a keyboard shortcut, in the VBE, or via the Tools menu.

    In each case, the result should be identical.

    The macro must be in the attached template, in a global template, or available via the VBE in a template attached to an open document.

  12. #12
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    > In each case, the result should be identical.

    I agree; it should.

    But it isn't.

    As Charles pointed out some months ago, copying toolbars with macros requir4es special handling. If you copy across the macros then copy across the toolbars (which contain buttons which invoke macros) the copied toolbar won't necessarily work. The macro always will.

    As far as I can see this comes about because the toolbar button has a link to a macro, but is not a macro. Copying the toolbar before the macro is copied leaves us with a local toolbar button with no local macro to point at. Copying the macro first doesn't seem to improve the situation. Charles suggested copying everything three times, and that seems to work.


    In the current discussion, on which macro gets called in preference to which templatre, the possibility of corrupted links via toolbar buttons seems to be relevant.

  13. #13
    Gold Lounger
    Join Date
    Dec 2000
    Location
    New Hampshire, USA
    Posts
    3,386
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    My gut (and I do have a big gut) feeling is the following:

    1. If you move a toolbar, and the necessary macros are where they should be, you should be OK.

    2. If you move a toolbar, and the necessary macros are NOT where they should be, then when you use the toolbar, the link to the macros gets "dirtied" in some way. If you then move the macros to where they should be, the toolbar is still dirtied and the toolbar links would need to be restored.

  14. #14
    Platinum Lounger
    Join Date
    Feb 2001
    Location
    Yilgarn region of Toronto, Ontario
    Posts
    5,453
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    It's nothing to do with the SIZE. Your gut is a darn sight more intelligent than mine. My gut can't fit past the 4-litre tub of vanilla at $3.77cdn in Price Chopper!

    I essayed with a starter kit of rules <A target="_blank" HREF=http://www.vif.com/users/cgreaves/whichmac.zip>here</A>.

    I figure that it is something I could play with every now and then, adding rules as I learn. Today's sampler is just to give me an idea of how I might lay out a document that aims to clarify what happens.

    I might make the rules hierarchical in some way, so that someone looking to see "What happens if I ...." can drill down to deeper levels, variations on a theme by, sort of thing.

    There seem to be an awful lot of possibilities. I can see me taking some shortcuts, making sweeping assertions along the lines of "Active Document ALWAYS takes preference over Normal.dot", that kind of thing. Working through all permutations of scenarios would be prohibitive as a volunteer effort.

  15. #15
    Plutonium Lounger
    Join Date
    Nov 2001
    Posts
    10,550
    Thanks
    0
    Thanked 7 Times in 7 Posts

    Re: Running code in a different Word template (Word 2000 SR1a)

    Thanks for all the help and discussion.

    Since I was interested in my code actually working every time, regardless of the setup that the end user has, I have gone for a very simple workaround. I did enjoy the discussions and I will think about doing something more sophisticated later.

    StuartR

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •