PDA

View Full Version : How does this VBA code work? (Word doc w/ bookmarks)



JohnnyBravo
10-31-2005, 11:11 AM
Can someone please explain for me what the following code means? Basically i know the code is supposed to run through the document, look for fields (in a form) then insert a bookmark name (bookmark#1 thru...whatever). I just don't know what the code (words) mean. I'm interested in modifying this for my own purposes. Thanks.


Option Explicit
Private Sub s_FillinBookmarks()
Dim i As Integer
Dim aBookmark As Bookmark
Dim amarks() As String

If ActiveDocument.Bookmarks.Count >= 1 Then
ReDim amarks(ActiveDocument.Bookmarks.Count - 1) As String
i = 0
For Each aBookmark In ActiveDocument.Bookmarks
amarks(i) = aBookmark.Name
If Mid(amarks(i), 1, 4) = "Text" Then
ActiveDocument.FormFields(amarks(i)).Result = _
CStr(Mid(amarks(i), 5, Len(amarks(i)) - 4))
ElseIf Mid(amarks(i), 1, 5) = "Check" Then
ActiveDocument.FormFields(amarks(i)).CheckBox.Value = True
ActiveDocument.Bookmarks(amarks(i)).Select
Selection.InsertAfter (CStr(Mid(amarks(i), 6, Len(amarks(i)) - 5)))
End If
i = i + 1
Next aBookmark
End If

End Sub

fumei
11-01-2005, 01:54 AM
Please please please use the underscore! Please.

Here is the code, with - as there should be.....comments....and AHEM....underscore characters.....
VBA:
Option Explicit
Private Sub s_FillinBookmarks()
Dim i As Integer
Dim aBookmark As Bookmark
' this is an array with no upperbound to it
' in other words it is NOT dimensioned
Dim amarks() As String

' if there ARE any bookmarks
If ActiveDocument.Bookmarks.Count >= 1 Then
' redimension (ReDim) the array
' however, most likely this should also have a Preserve
' added to it
ReDim amarks(ActiveDocument.Bookmarks.Count - 1) As String
' the following is completely unneeded, as i already = 0
i = 0
' for every bookmark in bookmark collection
For Each aBookmark In ActiveDocument.Bookmarks
' add the bookamark name to the array
amarks(i) = aBookmark.Name
' if the first four letters = Text
If Mid(amarks(i), 1, 4) = "Text" Then
' use the BOOKMARK name (in the array)
' as the FORMFIELD name and
' set the result of the formfield =
' remaining text of the bookmark name
ActiveDocument.FormFields(amarks(i)).Result = _
CStr(Mid(amarks(i), 5, Len(amarks(i)) - 4))
' else if the first FIVE letters are Check
ElseIf Mid(amarks(i), 1, 5) = "Check" Then
' use the BOOKMARK name
' as the FORMFIELD name
' with the assumption it is a checkbox
' and set it to TRUE (checked)
ActiveDocument.FormFields(amarks(i)) _
.CheckBox.Value = True
' select the bookmark and insert
' the remaining text of the bookmark name
' after it
ActiveDocument.Bookmarks(amarks(i)).Select
Selection.InsertAfter (CStr(Mid(amarks(i), 6, _
Len(amarks(i)) - 5)))
End If
i = i + 1
' go to the next bookmark
Next aBookmark
End If
End Sub
There are flaws to this code.

1. it uses both the bookmark collection, and the formfield collection. All formfields are also bookmarks. The flaw is that there is an assumption that could not be other bookmarks. This is not good practice.

2. There is no real purpose in the array, especially as it is not preserved. A plain ordinary string variable would work fine.

3. it uses the Selection object, rather than a Range.

4. the code is based on the use of default names for the formfields, that is "Text1" etc for textboxes, "Check1" etc for checkboxes. Again, this is not good practice.

5. it could (most likely) be done using the type of formfield, rather than conditional testing of the name. This also avoids any issue with the default name.

The result of the code is as follows:

Formfield name = Text1; result in the formfield = "1"
Formfield name = Check1; result is checked, followed by "1"
Formfield name = Text2; result in the formfield = "2"
Formfield name = Check2; result is checked, followed by "2"

etc etc.

You are incorrect - it does not insert a bookmark name. It fills the TEXT formfield with the remaining string after the word Text. Further, the checkbox has the number (assuming the default names again) with no space between it and the checkbox.

I am not sure what the intention is. It could be done (getting the same result that is) much easier.

If you wish to modify it for your own purposes I would suggest you write out exactly what you want to happen, and think about why you want to do it.

fumei
11-01-2005, 02:32 AM
Just as a demonstration, the following does precisely the same thing as the code you posted. That is, as long as there are no more than 9 formfields. I pick up the last character of the name - Text1 to Text9 will work fine. You would have to add two more lines of code to check for the index of the formfield collection to see if there were more than 9, as if there was 10 (11, 12 , 13....) then you want to pick up the last TWO characters.

However,for simplicity sake, I left it as such. It will give EXACTLY the same result as the submitted code.
Private Sub s_FillinBookmarks()
Dim oFF As Word.FormField
Dim oDocFF As FormFields
Set oDocFF = ActiveDocument.FormFields
If oDocFF.Count >= 1 Then
For Each oFF In oDocFF
Select Case oFF.Type
Case wdFieldFormTextInput
oFF.Result = Right(oFF.Name, 1)
Case wdFieldFormCheckBox
oFF.CheckBox.Value = True
oFF.Range.InsertAfter " " & Right(oFF.Name, 1)
End Select
Next
End If
Set oDocFF = Nothing
End Sub

Nothing needs to be selected, and only one collection is enumerated.

No need for an array to be declared, or ReDim'd.

No need for an integer or a counter at all.

So I have to ask....this code does not do very much, and seems almost pointless to me. What do you want to do that you think you can modify it for your purposes?