MS Office Forum / Word / Programming / September 2005
Greetings, problems with setting a bookmarked textbox value...it's protected?
|
|
Thread rating:  |
Shell - 23 Sep 2005 01:03 GMT Hi all,
I've been writing code in various environments, in varying application, for a wide range of customers, for about 35 years now and I'm still learning new stuff. ;) This week I'm helping a friend create a Word document template (Word 97) that stores a bunch of answers to questions in the registry (Using SaveSetting and GetSetting). In this document, as a part of the startup processing (AutoNew), I want to load the stored values back into the bookmarked places where they belong. The problem is I'm getting a error saying the location is protected. From what I understand of this, yes it is! I've protected the document so the body cannot be modified...but I want to be able to enter text/values into those places where I've defined fields (such as Textboxes, Checkboxes...et al)
Here's the code I have so far, the error comes from this line:
BkMrkRng.Text = RegVal
<code> Option Explicit Private BkMrk As Bookmark, BkMrkRng As Range
Sub AutoNew() Dim sBMName As String, S1 As String, S2 As String, RegVal As String
For Each BkMrk In ActiveDocument.Bookmarks sBMName = BkMrk.Name S1 = Mid(sBMName, 1, Len(sBMName) - 1) S2 = Mid(sBMName, Len(sBMName)) RegVal = GetSetting("MBD", S1, S2, vbNullString) If RegVal <> vbNullString Then Set BkMrkRng = ActiveDocument.Bookmarks(sBMName).Range BkMrkRng.Text = RegVal ActiveDocument.Bookmarks.Add sBMName, BkMrkRng End If Next BkMrk End Sub </code>
Hints: I've used the bookmark name, split into 2 strings, to name the Section and Key for the SaveSetting function so I can easily retrieve the values. I've learned that by setting the text value of a bookmark it clears the bookmark itself, therefore making it necessary to Add the bookmark back in after setting the text value.
Thanks for any help, Shell (Yes, this is my real name)
Jay Freedman - 23 Sep 2005 01:55 GMT At the beginning of the code, put in
If ActiveDocument.ProtectionType <> wdNoProtection Then ActiveDocument.Unprotect End If
and at the end put in
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True
Also, a bit of unsolicited advice: The registry isn't a suitable place to store data for specific documents.
- They're available only on that one computer; if the document is moved to another computer, the values won't be found.
- The registry is already a bloated monster on most PCs; it was never intended for storing large chunks of text. Performance of the whole PC is likely to suffer as the registry grows.
A better choice is to create document variables, members of the ActiveDocument.Variables collection. These values are stored in the document file when it's saved. They can be created and deleted only by macro code, but they can be displayed in the body of the document by {DocVariable} fields.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org
>Hi all, > [quoted text clipped - 44 lines] >Thanks for any help, >Shell (Yes, this is my real name) Shell - 23 Sep 2005 03:36 GMT In response to the post: On Thu, 22 Sep 2005 20:55:29 -0400, Jay Freedman <jay.freedman@verizon.net> stated...and I replied:
>At the beginning of the code, put in > [quoted text clipped - 21 lines] >macro code, but they can be displayed in the body of the document by >{DocVariable} fields. That sounds good. Would I be able to reference them from another document? The reason I'm storing the vlues in the registry is so I can get to them easily from other documents...there will be 4-5 other documents that I'll plug the values into when they are opened.
Thanks for the quick reply, Shell
Shell - 23 Sep 2005 04:07 GMT In response to the post: On Thu, 22 Sep 2005 20:55:29 -0400, Jay Freedman <jay.freedman@verizon.net> stated...and I replied:
Maybe I responded too soon :) Now I'm getting a completely unintelligable error...at least the doc is unprotected now (thanks).
Runtime error '5148: The number must be between :: <----this is a box in the message
The error occurs on the same line as before:
BkMrkRng.Text = RegVal
Also, I've noticed the text is preceeded with the value "FORMTEXT " which seems to be plugged in there by Word for some reason :/
I've been programming in VB6 for the last 5-6 years and I'm getting pretty good at finding the methods/properties/events of those controls...but this Word stuff seems to be like trying to see through mud. I do not understand how you can tell, from the collection of bookmarks, what type of form field it is the bookmark is referring to, textbox, checkbox or dropdownbox.
Shell
Jay Freedman - 23 Sep 2005 17:09 GMT This is in response to both of your most recent replies...
1. About storing things in document variables or in the registry: Your concern is correct, the document variables of one document aren't available to another document; but the registry still isn't a good choice. There's a third alternative, a separate file on the disk, which you can read and write with the System.PrivateProfileString property. The VBA help has a good example of how to use it. That file will be available to any open document on the same PC.
2. About the error: This requires some background. In Word there are plain bookmarks, which you manage in the Insert > Bookmark dialog; and there are bookmarks associated with form fields, which you see in the fields' Properties dialog. If you simply cycle through the ActiveDocument.Bookmarks collection, you'll get both kinds, but you can't treat them the same. The error you see comes from trying to treat a form-field bookmark like a plain bookmark, just assigning text to its range. But since the value you picked up from the registry is the whole field including the field markers, VBA complains. (The 'FORMTEXT' is part of the field code, which you can see when you select the field in an unprotected document and press Shift+F9.)
The right way to go about this is to declare a FormField object, and then cycle through the ActiveDocument.FormFields collection (Dim oFld As FormField; For Each oFld In ActiveDocument.FormFields ...). One advantage of this is that the code in this loop will never see any of the plain bookmarks. A second advantage is that a FormField object has a property named Type, and you can use an If statement or a Select Case statement to do different things depending on whether its value is wdFieldFormTextInput (a text box), wdFieldFormCheckBox, or wdFieldFormDropDown.
The value you should be storing, wherever you put it, should not be the .Range.Text of some bookmark, but instead the .Value property of the FormField object. For a textbox this will be the text in the box; for a checkbox it will be either True or False; and for a dropdown it will be the index (not the text!) of the selected item. When you retrieve the value from storage, assign it back to the .Value property of the corresponding FormField object.
I can sympathize with your frustration! The core of VBA is similar to VB, but probably 80% of the things you need to know in VBA are the details of the Word/Office object model and not just the programming principles. It takes a while to get the hang of these things.
 Signature Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org
> In response to the post: > On Thu, 22 Sep 2005 20:55:29 -0400, Jay Freedman [quoted text clipped - 21 lines] > > Shell Shell - 24 Sep 2005 01:25 GMT In response to the post: On Fri, 23 Sep 2005 12:09:49 -0400, "Jay Freedman" <jay.freedman@verizon.net> stated...and I replied:
>This is in response to both of your most recent replies... I really appreciate your help on this...you've been both extremely helpful and patient. Because of your help I now have about 20% of the code I had before...now you can help me to make what remains work ;)
How can I tell what FormField has triggered an Entry or Exit Module? I've tried to use the Selection.FormField(1).Name in both an Entry and Exit Module, but neither collection contains ANY members. I can see that focus moves from the field when the Exit Mod is being processed...so where can I find which one triggered the event?
Shell
Jay Freedman - 24 Sep 2005 02:51 GMT >In response to the post: > [quoted text clipped - 11 lines] > >Shell If your typing of 'Selection.FormField(1).Name' is literally what you have in your code, you're missing the 's' in 'FormFields'.
If it isn't a typo, then I'll guess that the field you're exiting from is a text box -- those don't follow the rules (bug? who knows?). See this page for an explanation of what you need to do: http://www.word.mvps.org/FAQs/TblsFldsFms/GetCurFmFldName.htm
That code goes in the exit macro of a field (or more likely, the same macro called as the exit macro of several fields), and it returns the name of the field you're exiting from.
Another page that has code you can study is http://www.word.mvps.org/FAQs/TblsFldsFms/ValidateFFields.htm.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org
Shell - 24 Sep 2005 06:44 GMT In response to the post: On Fri, 23 Sep 2005 21:51:42 -0400, Jay Freedman <jay.freedman@verizon.net> stated...and I replied:
>If your typing of 'Selection.FormField(1).Name' is literally what you >have in your code, you're missing the 's' in 'FormFields'. [quoted text clipped - 10 lines] >Another page that has code you can study is >http://www.word.mvps.org/FAQs/TblsFldsFms/ValidateFFields.htm. Hehehe, ok what can I say? Microsoft is not known for it's stability or consistencies of procedure. What I typed before was a typo and what you resonded with resolved the problem. Another thing I noticed was that once I had the name of the bookmark, I was still not able to reference it with the name...I had to use the workaround even there. Maybe the index doesn't like string variables containing the bookmark name...whatever, I was able to work around it with your much appreciated help.
Another thing I noticed, although this is not a problem that has stopped development, is that ActiveDocument.Path doesn't return anything...it's blank. I've found a work around (patch really) where I store the Application.Path in a Main entry program (in VB6), then use that path in the Word macro. I have a few more things to work into it...like a document name in the SaveAs dialog (I have the article for that one), and directing the SaveAs to my program directory instead of MyDocuments.
For now, I have a nice quiet weekend to enjoy, and some birthday cake to eat (my neice is turning 11) With a classic "Doc" Sevrenson bow and wave, you have a good one too.
Shell
|
|
|