PDA

View Full Version : Solved: Rename Checkboxes



Shred Dude
05-01-2008, 07:34 AM
I've written a Macro to go through a document and rename all of the checkboxes. It works great on my test documents. However, when I attempt to run it on the document I really need it to work on, it crashes everytime.

Here's the Macro:
Public Sub NameCheckBoxes()
Dim frmfld As FormField
Dim chckcount As Long
Dim newname As String
chkcount = 0
Application.ScreenUpdating = False
With ActiveDocument

For Each frmfld In .FormFields

If frmfld.Type = wdFieldFormCheckBox Then
chkcount = chkcount + 1
newmname = "Check" & chkcount + 1000

frmfld.Name = newname
frmfld.Select
Selection.InsertBefore frmfld.Name & ": "
Selection.Font.Color = wdColorRed
End If

Next frmfld
End With 'ActiveDocument

Application.ScreenUpdating = True
MsgBox "Processed " & chkcount & " CheckBoxes."
End Sub


When I run it on the document in question, it crashes everytime on the line:
frmfld.Name = newname

With the follwing error message:


Run-time error '-2147467259 (80004005)'
Method 'Name' of object 'FormField' failed

My searches on MSDN came up with 3 KB articles referring to this err #, all referring to a situation where the formfield does not have a name. those articles suggest going through your document manually to add Bookmark names!

My document's CheckBoxes all have names already. I'm just trying to change them to unique values.

Any ideas?

Thanks in advance.

fumei
05-01-2008, 09:14 AM
My document's CheckBoxes all have names already. I'm just trying to change them to unique values.If they all have names, then they have to be unique already. What you are trying to do is change the values.

You are not using Option Explicit, it seems. Look at my bolding below. Dim chckcount As Long
Dim newname As String
chkcount = 0
Application.ScreenUpdating = False
With ActiveDocument

For Each frmfld In .FormFields

If frmfld.Type = wdFieldFormCheckBox Then
chkcount = chkcount + 1
newmname = "Check" & chkcount + 1000



Dim chckcount As Long But chkcount (no "c") is used.

Dim newname As String But newmname (an added "m") is used.

If I make the names match (as they should), it works just fine.

Another thought is if you did any copying of formfields. Copied formfields do NOT have names. The bookmark name ends up being blank.

Shred Dude
05-01-2008, 09:44 AM
Thanks for taking the time to reply. I appreciate your help.

Thanks for catching my typos. I've corrected. I turned on Option Explicit to catch myself too. My bad.

Here's the corrected from my VBE:

Public Sub NameCheckBoxes()
Dim frmfld As FormField
Dim chkcount As Long
Dim newname As String
chkcount = 0
Application.ScreenUpdating = False
With ActiveDocument

For Each frmfld In .FormFields

If frmfld.Type = wdFieldFormCheckBox Then
chkcount = chkcount + 1
newname = "Check" & chkcount + 1000

frmfld.Name = newname
frmfld.Select
With Selection
.InsertBefore frmfld.Name & ": "
.Font.Color = wdColorRed ' InsertBefore Expands Selection to inlcude what you inserted
End With
End If

Next frmfld
End With 'ActiveDocument

Application.ScreenUpdating = True
MsgBox "Processed " & chkcount & " CheckBoxes."
End Sub

The document I'm trying to work this on has 394 checkboxes. There are 212 duplicate names in that 394. (I wrote another little routine to capture the unique names in a scripting.dictionary) I've inherited this document. It would appear that many of the checkboxes were created by copying an existing one to another location in the doc.

I'm new to Word VBA, but have been pretty successful with it in Excel so I thought I'd give it a go. My objective is to populate this Word document with responses that I have in Excel. I've written another routine that can accomplish this. What I ran into during that exercise were duplicate named formfields (checkboxes and textboxes). This is when I started writing this little utility macro. I have the same issue when it's run against field type wdFieldFormTextInput.

(With theText boxes, I have 934 textboxes, with 512 duplicate names in the document)

I thought if I could go through and name each formfield uniquley, it'd make my task easier in my Excel to Word macro. I became very frustated when finding that I can run this macro on a generic test document with hundreds of checkboxes that I've added via another macro, but then it crashes on the document I need it to work on! I'm stumped!

OFF TOPIC: If there's another way to populate my document with my Excel data without being able to identify the textbox or checkbox specificaly, I'd be very interested.



Any thoughts?

Shred Dude
05-01-2008, 09:58 AM
If they all have names, then they have to be unique already. What you are trying to do is change the values.

You are not using Option Explicit, it seems. Look at my bolding below. Dim chckcount As Long
Dim newname As String
chkcount = 0
Application.ScreenUpdating = False
With ActiveDocument

For Each frmfld In .FormFields

If frmfld.Type = wdFieldFormCheckBox Then
chkcount = chkcount + 1
newmname = "Check" & chkcount + 1000



Dim chckcount As Long But chkcount (no "c") is used.

Dim newname As String But newmname (an added "m") is used.

If I make the names match (as they should), it works just fine.

Another thought is if you did any copying of formfields. Copied formfields do NOT have names. The bookmark name ends up being blank.
fumei:

I reread your post and dug into my doc more deeply.

If I run my little routine with the offending line commented out, I end up with my document having all the checkboxes nicely labeled in Red with their Name. In many cases, you'll see the same name appearing. If I go to the raw document (pre macro running on it), and right click on the checkboxes that appear to have the same name, there is no bookmark name in the formfield dialog box. To your point I guess, that a copied field would have a blank bookmark.

This is all new to me as I'm just venturing into Word Object Model. So now I'm a little more confused. I would think my routine reads a new value (frmfld.name) with each iteration of the loop, and uses that for the insertbefore method as directed. How then does it come up with the same name for multiple checkboxes? Are Bookmark and Name two differnt properties of a formfield object? I don't see Bookmark in the Object Library as a property of formfield, just Name.

Shred Dude
05-01-2008, 11:41 AM
This version of the utility goes about it a different way. It works on the first few in the document and then crashes. I've tried some stall loops in the code in case it was getting ahead of itself around the dialog window, but it didn't help. It tends to crash on my machine about 5-7 checkboxes into the doc.

The For Each Next loop seemed to cause lots of problems. This loop iteration gets me a little further, but is still not making through the whole doc.

Any ideas?


Public Sub NameWithDialogBox()
Dim frmfld As FormField
Dim chckcount As Long
chkcount = 0
On Error Resume Next
With ActiveDocument


For i = 1 To .FormFields.Count

If .FormFields(i).Type = wdFieldFormCheckBox Then

chkcount = chkcount + 1

.FormFields(i).Select
With Dialogs(wdDialogFormFieldOptions)
.Name = "Check" & chkcount + 6000
.Execute
End With
End If


Next i
End With 'ActiveDocument

MsgBox "Processed " & chkcount & " CheckBoxes."


End Sub

fumei
05-01-2008, 12:32 PM
"How then does it come up with the same name for multiple checkboxes? "

Can you chop it up into a smaller doc (I don't need to see hundreds!) so I can see this?

There is confusion regarding this, and IMO Microsoft did it screwy. I don't kniw if I would call it a bug, but....

Make a new doc.
Put in one checkbox.
Right click > Properties and look at "bookmark". It shows as "Check1"

Insert > Bookmark. You will see "Check1".

Delete the bookmark "Check1". Insert > Bookmark should now show nothing, no bookmarks.

Right click > Properties on the checkbox.

The "Bookmark" STILL shows as "Check1", even though Bookmarks no longer has "Check1".

The "Bookmark" in the Properties of a formfield is actually .Name.

"I don't see Bookmark in the Object Library as a property of formfield, just Name."

Because you are quite correct, Bookmark is NOT a property of a formfield. Creating a formfield creates a Bookmark, with its Range being the range of the newly created formfield. Technically (and literally) they are independent objects.

fumei
05-01-2008, 12:57 PM
Gotta say I am having deep issue with this one.

If a formfield "bookmark" name is blank, it is NOT "". It is vbNullString. I am having problems changing it AND make the match real bookmark.

Shred Dude
05-01-2008, 03:31 PM
Fumei:

Glad to hear it's just not me. I've gone around and around for hours. I've finally accomplished my goal. I"ve processed my 17 page document with 394 checkboxes and 931 textboxes successfully with thefollowing code.
(The Commented Out pieces allow me to actually show the name of the control in the document, while preserving the bookmark name, by using the .previous maneuver prior to doing the InsertBefore. I run it once with that on for a visual working copy to assist with coding my datamap from Excel data.)

Public Sub ReNameControlsWithDialogBoxMethod()
' Renames checkboxes and Textboxes throughout Document
' Places new name, in Red, in front of each Form Control
Dim frmfld As FormField
Dim chckcount As Long
Dim txtcount As Long

chkcount = 0
txtcount = 0
Application.ScreenUpdating = False
'On Error Resume Next
With ActiveDocument

For i = 1 To .FormFields.Count
If .FormFields(i).Type = wdFieldFormCheckBox Then

chkcount = chkcount + 1

.FormFields(i).Select
On Error Resume Next
With Dialogs(wdDialogFormFieldOptions)
.Name = "Check" & chkcount + 1000
.Execute
End With

' Selection.Previous(Unit:=wdCharacter, Count:=-1).Select
' Selection.InsertBefore .FormFields(i).Name & ": "
' Selection.Font.Color = wdColorRed
End If
On Error GoTo 0
If .FormFields(i).Type = wdFieldFormTextInput Then

txtcount = txtcount + 1

.FormFields(i).Select
On Error GoTo errhandler
With Dialogs(wdDialogFormFieldOptions)
.Name = "TBox" & txtcount + 1000
.Execute
End With
On Error GoTo 0
' Selection.Previous(Unit:=wdCharacter, Count:=-1).Select
' Selection.InsertBefore .FormFields(i).Name & ": "
' Selection.Font.Color = wdColorRed
End If

Next i
End With 'ActiveDocument

Application.ScreenUpdating = True
MsgBox "Processed " & chkcount & " CheckBoxes, " & txtcount & " textboxes."

Exit Sub
errhandler:
MsgBox "Crashed after doing " & chkcount & " checkboxes, & " & txtcount & " textboxes."
Resume Next

End Sub


Even with the on error resume next code in the checkbox section, I still had to manually monitor the routine to click OK in a window that would periodically appear. it was Word window popping up telling me this command not available because this contorl was not added via the Insert Forms Menu ...

By manually clicking OK when this window appeared, I was able to get through my document. I didn't have to resort to that Resume Next in the Textbox section of my loop. Apparently my document had something weird going on with checkboxes.

I NEVER got the frmfld.Name = "XXX" to work consistently. If the .name property is "", or Null (I'm not clear either on which it is), it would crash. I even tried trapping the condtion with something like
if LEN(frmfld.name)=0 then... and then carrying on around it,
but that didn't help either.


Additionally, the For Each Next construct attempted in my first versions, gave me problems too. I'm not sure why, but it worked better for me doing it as above.


This was a long road for me, but a god learning experience. As my first foray into the world of Word VBA, I got a lot more than I was expecting. There are some concepts in Word that are very different than Excel. but after a while I guess they kinda make sense.

Thanks for your participation in my mental gymnastics. Hopefully this thread can save someone else some time.

Shred

fumei
05-02-2008, 09:25 AM
I also tried error trapping the vbNullString of an unnamed formfield. While I can get a True return (if it is True), I can NOT change the name.

If frmfld.Name = vbNullString Then
frmfld.Name = "whatever"
End If


It will process the True/False of If frmfld.Name = vbNullString, but fails on making any changes to .Name.

I spent two hours on this yesterday and was ready to punch Word in the face.