Distributing Macros

Once you've created a few macros, you may want to distribute your macros to other Word users. The way in which you distribute your macros depends on how you intend others to store, run, or modify them. There are also important issues to consider before distributing a macro for use in another language version of Word.

Distributing Macros with a Local Template

Distributing your macros to others can be as easy as distributing the template where your macros are stored. For example, if you've created a template for an automated form or a Wizard, you can distribute your macros by giving the template to others. They can then copy the template to their User Templates location specified on the File Locations tab in the Options dialog box (Tools menu). Alternatively, you can write a setup macro or program that automatically copies the template to the appropriate location using the CopyFile statement. You can use the GetPrivateProfileString$() function to retrieve the User Templates location from the system settings file or the registry.

Note

Most users have a Normal template on their computer, so if your macros are currently stored in your Normal template you shouldn't distribute them by giving others your Normal template. Instead, create a new template and use the Organizer to copy the appropriate macros into the new template. Save and distribute the new template instead of your Normal template.

Prior to distributing a macro, you can make it "execute-only" so that other people can only run your macro. When a macro is execute-only, the Edit button in the Macro dialog box (Tools menu) is unavailable (dimmed) when the macro name is selected. The execute-only format is best used when you don't want other people to be able to view or edit your macro. To make a macro execute-only, use the MacroCopy statement in another macro. Be sure to make a backup copy of your macro prior to making it execute-only. Once the macro is execute-only, you won't be able to view or edit the instructions.

If you're working in a workgroup setting and want everyone to have access to your macros, you can copy your template to the Workgroup Templates location specified on the File Locations tab in the Options dialog box (Tools menu). The Workgroup Templates location allows multiple users to access a group of templates from one network share. Templates that are used by everyone in the workgroup are copied to this location. Templates from the User Templates and Workgroup Templates locations are available in the New dialog box (File menu). When you update your macros, you can copy the updated template to the Workgroup Templates location. This distribution technique ensures that everyone is using the latest version of your macros.

Distributing Macros with a Global Template

If the macros you want to distribute are not specific to a particular type of document, users may want to run your macro from any document (regardless of the attached template). To be run this way, the macro needs to be stored in a loaded global template. Users can temporarily load a global template by selecting the template in the Templates And Add-ins dialog box (Templates command, File menu). Alternatively, you can write a setup macro that uses the AddAddIn statement to load a template as a global template. The template is not, however, permanently loaded as a global template.

Templates stored in the Startup folder are automatically loaded as global templates when Word starts. If you want your global template loaded automatically, you can ask users to manually copy the file to their Startup folder, or you can write a setup macro. The setup macro can copy the template to the Startup folder using the CopyFile statement (use the GetPrivateProfileString$() function to retrieve the Startup folder location from the system settings file or the registry).

Loading templates globally consumes memory. A way to control this is to allow the user to dynamically load or unload the template at the click of a button. As a result, the template is only loaded into memory when the user needs to run the macros in the template. The following macro uses the AddInState statement to load or unload a global template.


Sub MAIN
state = AddInState("agenda.dot")        'check current state
If state = 1 Then
    AddInState "agenda.dot", 0        'load template
Else
    AddInState "agenda.dot", 1        'unload template
End If
End Sub

During an installation macro, this macro can be copied to the user's Normal template and assigned to a toolbar button. Use the MacroCopy or the Organizer statement to copy a macro to the Normal template, and use AddButton to add a toolbar button.

Another distribution technique is to write an AutoOpen macro that copies macros from the current template to the user's Normal template. Use the MacroCopy or Organizer statement to copy macros between templates. However, because users may have a number of macros already in their in Normal template or may have macros with the same names as the macros you want to copy, this technique is not the preferred way of distributing macros.

Distributing Macros Without a Template

If you want to distribute a macro without a template, you can save your macro as a text file. Open your macro in a macro-editing window and choose Save Copy As from the File menu. Type a file name and then choose Save. You can send the text file to another Word user. To run the macro, the user can copy the instructions from the text file into a new macro.

Distributing Macros Internationally

Microsoft Word is available in many different languages. At some point, you may need to distribute your macro to someone using a different language version of Word. Functionally, the programs are the same, but distributing macros between different language versions of Word requires some forethought.

WordBasic macros that are stored in templates are stored in a "tokenized" format. Macro keywords (statements and arguments such as "EditFind" and ".Name") are compressed and stored as three-byte tokens. When you edit a macro, the tokens are decoded into keywords for the current language of Word. For example, if a macro is written in the English (US) version of Word and then opened in the German version of Word, the WordBasic keywords will appear in German. The command to open a new document appears as "FileNew" in the English version of Word and "DateiNeu" in the German version of Word.

While macro keywords are translated, string values are not translated between languages. The following table demonstrates how English instructions are translated into German. The text enclosed in quotation marks is not translated.

English instruction

Instruction translated into German

Insert "Hello World"

Einfügen "Hello World"

Style "Tag Line"

Formatvorlage "Tag Line"

EditGoTo "Bookmark2"

BearbeitenGeheZu "Bookmark2"

MsgBox "Insert Disk A"

MsgBox "Insert Disk A"


To run in multiple language versions of Word, your macro must determine the current language version and then use the appropriate string values for that version. Use the AppInfo$() function to determine the current language version, as shown in the following example.


Sub MAIN
lang$ = AppInfo$(16)                'Determine the language version
Select Case lang$
Case "English (US)"                'English version
    sometext$ = "Hello World"  
Case "Deutsch"                    'German version
    sometext$ = "Hallo Welt"
Case Else
End Select
Insert sometext$
End Sub

For a list of language names returned by the AppInfo$() function, see ToolsLanguage in Part 2, "WordBasic Reference."

Tip

Macros that use numerous strings can either use arrays to store strings for each language or return strings stored in a text file by using sequential file access.

The default measurement unit specified on the General tab in the Options dialog box (Tools menu) and the decimal separator in most languages is different from the defaults in the English (US) version of Word. Because of this, measurements you specify in statements such as FormatParagraph and FilePageSetup may not work as expected or may cause syntax errors when the macro is run in another language version of Word.

You can use the same technique described earlier for creating message string values to create measurement unit string values.


Sub MAIN
lang$ = AppInfo$(16)                'Determine the language version
Select Case lang$
Case "English (US)"                'English version
    points$ = "pt"  
Case "Espagńol"                    'Spanish version
    points$ = "pto"
Case Else
End Select
FormatParagraph .LeftIndent = "36" + points$
End Sub

An alternative is to specify a numeric value for arguments that accept either a numeric or string value, because the default measurement unit of a numeric value for a given argument is the same across multiple language versions of Word. For example, the default unit for a numeric value specified for the .LeftIndent argument of FormatParagraph is points. Therefore, the following statement works in any language version of Word.


FormatParagraph .LeftIndent = 36            '36 points in any language

For information about the default measurement units of numeric values for an argument of a specific statement, see the corresponding entry in Part 2, "WordBasic Reference."

The English (US) version of Word uses a period (.) for a decimal separator, while most European countries use a comma (,). You can use the AppInfo$() function to determine the decimal separator. Once you know the character, you can create a string that includes the decimal separator ("12.5" or "12,5" in the following example).


dec$ = AppInfo$(18)    'Get the decimal separator
FormatParagraph .LeftIndent = "12" + dec$ + "5 pt"  

No matter which language version of Word you are using, if you specify a numeric value for an argument that accepts either a numeric or string value, you must use a period for the decimal separator. A comma decimal separator generates a syntax error. For example, if the following statements in an English (US) macro were opened in the German version of Word, the translated versions would be equivalent:


FormatParagraph .LeftIndent = "12,5 pt"
FormatParagraph .LeftIndent = 12.5