Consulting

Results 1 to 3 of 3

Thread: How does this VBA code work? (Word doc w/ bookmarks)

  1. #1

    How does this VBA code work? (Word doc w/ bookmarks)

    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.


    [VBA]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[/VBA]

  2. #2
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Please please please use the underscore! Please.

    Here is the code, with - as there should be.....comments....and AHEM....underscore characters.....
    [vba]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 [/vba]
    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.

  3. #3
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    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.
    [vba]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[/vba]

    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?

Posting Permissions

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