FrontPage2000/2002 Macros - Getting Started

That's actually the difficult bit - getting started.  If you're reading this, you already know the documentation is useless, and worse than useless.  So, what do we want to do, and how do we want to do it?

What I wanted to do was to add verse numbers to a Latin text, without having to type them all, in the format [1] ... [2] ... etc throughout the text.  I wanted to stick the cursor at the start of the right sentence, and press a key and get the [n] inserted.  I wanted the number to increment automatically every time I hit the same key; and to reset back to [1] when a new chapter started.  

Obviously the number would be a public global variable, set by two macros.  But how to code it?

This is bad enough to find out about in Word.  It's worse in FP2000, and the code won't work across both platforms (thank you, Microsoft).

[Note: These instructions also work in FP2002.  If you install FP2002 without removing FP2000, the macros are preserved, but you have to recreate the toolbar entries.  The process is marginally more obvious in FP2002, but not much, and the following instructions still work.]

[Why did I upgrade?  I found that the editor in FP2000 does not reliably handle unicode.  If you enter

<font face="Code2000,TITUS Cyberbit Basic"><font size="6">&#1808;&#1810;</font>

in FP2000, you get an empty square --  in FP2002, and in Dreamweaver 6, you get the correct character displayed (these are Syriac, if you're interested -- the Greek unicode entries work OK).  In both FP2000 and FP2002, the Preview works -- but of course I wanted to enter text wysiwyg].

1.  Creating a Macro

I presume you did open FrontPage?  I don't use webs, so you needn't worry about them.  From the menu, choose Tools|Macro|Macros.  This gives the screen

(This will be blank when you start - these are my three macros). Type in a name, and the 'Create' button will become active.  Click it, and you'll be placed in the Visual  Basic editor in a sub of the name you chose.  If you want to check things are OK, try this

public sub test()
   msgbox "hello"
end sub

as your first test.  Save the macro.

Where is the Macro Saved?

'Where is it saved?' I hear you cry.  There is a "Microsoft FrontPage.fpm" file somewhere on the system (the location varies with Windows version - thank you, Micro$oft), and they are saved in there.  So they will be available in every document automatically, but of course are not included in the documents themselves.

When you move PC, do remember to take it with you!

The best way to find out where it is is this:

  1. Create an empty VB macro, Debug|Compile, File|Save, then close, and exit FP.  This will create a .fpm file.  You just have to find it.  It's usually under wherever temporary files get saved.

Here's what I recall off-hand:

2.  Running a Macro

Remarkably, Microsoft have managed to make this difficult.  The simple way (and the one suggested in all the documentation, which tells you no-one outside the development team reviewed that documentation) is to load that screen above (Tools|Macro|Macros, or Alt-F8), highlight the macro, and press run.  Not exactly something you want to do 3 times a second, is it?

Of course in MS Word, you'd assign it to a hot-key.  Well, forget about that right now - they haven't made that possible!  But you can get round this a certain amount, as they will allow you to create your own menu items and toolbar items.  The index gives no help unless you know the magic words to look for.  The one to look for is 'view or customize toolbars'.  This will tell you (inadequately) how to add a new icon to the toolbar.  The process is much better described on this page, which I derived from one by Robert Robbins - print it and follow the instructions.  

Note that you can remove any icons by View|Toolbars|Customize|Toolbars, selecting the toolbar you've messed up, and pressing Reset.

What the tutorial does not tell you is that the same process can also be used to add Menu items.  This means you can use the keyboard to help you.  If instead of choosing a toolbar icon, you ask for a new menu item, you can drop it in the top menu bar.  Make sure you include an & in the name, as that will allow you to use a hot-key.  So I named my top level menu '&Macros', which means that Alt-M will pop it up.  Then you have to add items to the menu.  Each of these will, of course, be a macro.  Again you make sure the name has '&' in it, so you can simply press a single letter once the menu is open to run the macro.

And there you have it.  So I can run macro A (which I called &A when prompted for a name) by Alt-M, A.  That's almost as good as hot keys.

While I was writing, Robert Robbins has just emailed me a better way (thank you!):

"To create a hotkey you must select "Image and Text" for the button and then enter a button name. The first letter of the button name will be the hotkey ALT + letter. But you should pick a letter that is not being used for a menu item."

Note: Error 70, Permission denied

If you try to run a macro which inserts in a page with the document open in HTML mode rather than Normal mode, you get an error 70, Permission denied.  This happened to me when I was debugging, and I wondered what the problem was.

3.  Writing text into your document from a Macro.

You won't find out how to do this from the documentation.  However it is fairly simple.

Sub test()
  '-- Your cursor position, as in MS Word, must be treated as a 'selection'.
  Dim myRange As IHTMLTxtRange

  '-- ActiveDocument is the page you have open.  Selection is either a selection highlighted on the screen
  '-- or your cursor position / insertion point.  This is a strange way to do things, but they do it in Word also.
  Set myRange = ActiveDocument.selection.createRange
  '-- You can then stick some raw HTML in, and it will be inserted either instead of what you highlighted,
  '-- or after the selection point.  So the following will appear in Italics, rather than with chevrons in
  '-- the text.  Try it and see!
  myRange.pasteHTML ("<i>hello</i>")
  '-- Alternatively you may not want HTML, so you can just use the .Text method.
  'myRange.Text = "fred"

  '-- If you then want to change what you entered sky blue, you can do so... provided it's between HTML tags!
  '-- These are called the 'parent element' of your text.  Of course if you didn't specify any, you get whatever
  '-- is around - usually the whole paragraph - modified.
  '-- In our case, Parentelement being the <i>...</i> element/block
  myRange.parentElement.Style.backgroundColor = "SkyBlue"

End Sub

It's worth looking at the HTML that results, just so you know what happens.  It's OK - but I don't want that sort of inline Style stuff, myself.  I think I would not use the Style stuff at all, but code it myself.

4.  Navigating around the document

I haven't had to do this yet, so I haven't worried about it.  I can see, tho, that the ActiveDocument object contains all the tags, in order, and each tag contains text, etc.  So one could iterate through these in some way, I think, if you wanted some sort of Search and Replace.

My suggestion is to type in the object, and then look up in turn each of the methods and properties that intellisense supplies when you type '.' and wait.  As we have seen, the names mean nothing.  Who would have thought pasteHTML was 'insert after selection?'.

5.  Other thoughts

I hope that's helpful.  Remember you can save the macros out as .bas files from the VB editor, and import them.  Have fun - and if you find out anything useful, put it online for the rest of us!

6. FAQ

1.  Writing HTML around the selection

>What about writing html around the selection. Say I select the url and run a macro that puts:
>     <a href="http://www.kghvkhg.com">www.kghvkhg.com</a>
>this macro will have to use the selected region as a variable.
>
>how do I do this?

sub mySub

'-- Get the selection
Dim myRange As IHTMLTxtRange
Set myRange = ActiveDocument.selection.createRange

'-- Display the bit selected
MsgBox (myRange.Text)

'-- Change the bit selected
myRange.pasteHTML ("<B>" & myRange.Text & "</B>")

end sub

2. How do I find the insertion point?

> How do I find out where the cursor is in the page?
Dim myRange As IHTMLTxtRange
Set myRange = ActiveDocument.selection.createRange

If there is no existing selection, text written to myRange will be inserted at the cursor.  If there is a selection, the selected text will be overwritten.

3. How do I insert the contents of the clipboard into the text?

Note that you need to have the right references defined in Tools|References for this.  My list is

Visual Basic for Applications; Microsoft Frontpage 4.0 Web Object Reference Library;OLE Automation;Microsoft Office 9.0 Object Library; Microsoft Frontpage 4.0 Page Object Reference Library; Microsoft Forms 2.0 Object Library

Sub InsertApparatusLink()
'-- Take the contents of the clipboard (the text for a #link) and apply as url to current selection

'-- Get text
Dim MyData As DataObject
Set MyData = New DataObject
MyData.GetFromClipboard
'-- Get the text into a string
Dim mystr As String
mystr = MyData.GetText(1)

'-- Get the selection/insertion point
Dim myRange As IHTMLTxtRange
Set myRange = ActiveDocument.selection.createRange

'-- Build the text
myRange.pasteHTML ("< A HREF=""#" & mystr & """>" & myRange.Text & "</A> ")

End Sub

4. How do I save the file and close it?

(Hooked it up to alt+q. -- This one by Carsten Engel)

Sub saveandclose()

'Checks that the document is in Page view in FrontPage and that at least one page is open.
If (Application.ActiveWebWindow.ViewMode = fpWebViewPage _
    And ActiveWebWindow.PageWindows.Count > 0) Then

    Dim activePage, page As PageWindow 'Declare variables
   'Set the variable ActivePage to the current active page
    Set activePage = ActivePageWindow
    activePage.Save
    activePage.Close
End If

End Sub

5. How do I change the name of all the <A NAME="fred bloggs"> to get rid of spaces as <A NAME="fred_bloggs">

There are various collections of the tags in the document model.  Do this one like this:

Private Sub RemoveSpacesFromAnchorNames()

Dim anchor
Dim i As Long

For Each anchor In ActiveDocument.anchors
   'MsgBox anchor.Name & " " & Replace(anchor.Name, " ", "_")
   'i = i + 1
   'If i > 5 Then Exit Sub
   anchor.Name = Replace(anchor.Name, " ", "_")
Next

End Sub

The commented out code I used before making the change to check that what I was seeing was right.  I didn't want the msgbox to keep popping up for every anchor in the document, as it had a lot of these!

The same method works for links/urls in the document:

Private Sub RemoveSpacesFromLinkNames()

Dim link
Dim i As Long

For Each link In ActiveDocument.links
    'MsgBox link.href & " " & Replace(link.href, " ", "_")
    'i = i + 1
    'If i > 5 Then Exit Sub
    link.href = Replace(link.href, " ", "_")
Next

End Sub

6. How do I sweep all text in the page?

Select a range which includes the contents of the <BODY> tags (HEAD and HTML are not supported):

Set myRange = ActiveDocument.all.tags("BODY").Item(0).createTextRange

Then use it like any other range, as above, and you can change any character, or apply formatting to the whole thing.

e.g.:

Private Sub EveryCharacter()

'-- Get the selection
Dim myRange As IHTMLTxtRange
Set myRange = ActiveDocument.all.tags("BODY").Item(0).createTextRange

MsgBox (myRange.htmlText)    '-- All the ASCII text, including tags, etc, all raw
MsgBox (myRange.Text)        '-- Just the text, not the HTML tags
'myRange.pasteHTML ("<B>" & myRange.Text & "</B>")   '-- Do something to the selected text

End Sub

7. How do I change the Title of the document?

Use/Set ActiveDocument.title.

8.  How do I emulate 'Paste Special'?

Carsten Engel sent me this:

Sub pastespecial()
  '-- Get text
  Dim MyData As DataObject
  Set MyData = New DataObject
  MyData.GetFromClipboard
  '-- Get the text into a string
  Dim mystr As String
  mystr = MyData.GetText(1)

  '-- Get the selection/insertion point
  Dim myRange As IHTMLTxtRange
  Set myRange = ActiveDocument.selection.createRange

  '-- Paste the text asif HTML
  myRange.pasteHTML (mystr)

End Sub

9. How do I set the Target property on all my HREF tags?

If you want to change all your <A HREF=ibm.com> tags to <A HREF=ibm.com TARGET=fred>, run the following.  Note that the VB help supplied with FP is quite useless -- it won't tell you what properties there are on ActiveDocument, nor that there is a links collection, nor that it has a property 'target'.  I just guessed that the property name would be available, and it was.  (But if it was a non-existent property MYPROP then FP gives a compile error).

Private Sub changethem()

Dim link
Dim i As Long

For Each link In ActiveDocument.links
  MsgBox link.target
  link.target = "fred"
  MsgBox link.target
  --i = i + 1
  --If i > 5 Then Exit Sub
Next

End Sub

Getting Help from the Help

You already have found that you can't find anything.  Actually it's worse than that -- if you open the VB help and look for keywords in the index, in the same session later on 'active' will bring up ever fewer keywords each time!  Something is badly wrong.

What you need to do is to open the VB editor.  Then Help|Microsoft Visual Basic Help.  Then select Index.  Enter Active in the box and find ActiveDocument.  The first help item for this is 'ActiveDocument Property'.  This page is useless, but has a hyperlink to the Microsoft FrontPage Page object model.  This in turn takes you to a page 'Exploring the Object Model in FrontPage'.  On this are three lists of 'events'/methods/properties not supported from the Document model.  But on each of these pages, the 'see also' will take you to a list of events/methods/properties which are supported.  Painful or what?!

And don't forget the intellisense.  When you declare an object of a given type, or use a pre-defined variable like ActiveDocument, when you type the full-stop on the end a list of possible methods will appear.

Constructive feedback is welcomed to Roger Pearse.

Last updated 6th August, 2004.

This page has been accessed by  ****** people since 20th July 2001.

Return to Roger Pearse's Pages