Variable Values Disappears...

J

jab

Hi all

I have made a custom Dialog in which users will enter information.
This information will then be downloaded into the document via
docvariables. Some of the values shall also be saved as custom
properties with the document

I want the dialog to have preset values if no values are present in
the document i.e NOT in the document show the message "Error, No
document variable supplied" but a predefiend value via VBA instead. If
entries priviously have been made those should be loeded into the
dialog text fields when it is opened.

The code so far works and displays everything as stated if ALL the
fields of the dialog are prefilled in the dot file or if the user
fills them all in. But if one field is left empty when clicking ok in
the dialog, the variable entry in the document shows the error
statement described above in the docuument variable field (I want the
default value to be there). AND, here's the weirdest part, when
opening the dialog again for reentry of information, not only the left
out field is empty but a few of the others as well, i.e the code does
not pick up the values of the variables in the document and presents
them as the're supposed to. It only does so if ALLthe fields are
filled in and the values transferred to the document

Could som1 please tell me what is going on?

Here is the code:

Option Explicit
Dim oVar As Variables
Dim objCustomProperties As DocumentProperties
Private Sub UserForm_Initialize()

On Error GoTo Handler
Set oVar = ActiveDocument.Variables
' ## JAB Added ref to custom doc properties
Set objCustomProperties = ActiveDocument.CustomDocumentProperties

Me.txtprojname.Text = oVar("Project").Value
Me.Txtclientname.Text = oVar("Client").Value
Me.txtDocutype.Text = oVar("DocType").Value
Me.txtdate.Text = oVar("PrefDate").Value
Me.txtcontactp.Text = oVar("Contact").Value
Me.txtdirphonenumber.Text = oVar("DirPhone").Value
Me.Txtmobil.Text = oVar("Mobil").Value
Me.txtemail.Text = oVar("email").Value
Me.Txtnameofauthor.Text = oVar("DocAuthor").Value
Me.txtfax.Text = oVar("fax").Value
Me.txtstad.Text = oVar("City").Value
Me.txtpostal.Text = oVar("Postalnr").Value
Me.txtstreet.Text = oVar("street").Value

Exit Sub

With ActiveDocument
txtprojname = .Variables("Project").Value
Txtclientname = .Variables("Client").Value
txtDocutype = .Variables("Doctype").Value
txtdate = .Variables("Prefdate").Value
txtcontactp = .Variables("Contact").Value
txtdirphonenumber = .Variables("Dirphone").Value
Txtmobil = .Variables("Mobil").Value
txtemail = .Variables("email").Value
Txtnameofauthor = .Variables("DocAuthor").Value
txtfax = .Variables("fax").Value
txtstad = .Variables("City").Value
txtpostal = .Variables("Postalnr").Value
txtstreet = .Variables("Street").Value

End With

txtprojname.SetFocus
Txtclientname.SetFocus
txtDocutype.SetFocus
txtdate.SetFocus
txtcontactp.SetFocus
txtdirphonenumber.SetFocus
Txtmobil.SetFocus
txtemail.SetFocus
Txtnameofauthor.SetFocus
txtfax.SetFocus
txtstad.SetFocus
txtpostal.SetFocus
txtstreet.SetFocus

Handler:
oVar("Project").Value = "Project name"
oVar("Client").Value = "Client Name"
oVar("DocType").Value = "Type of Document"
oVar("PrefDate").Value = "Last editing date of document"
oVar("Contact").Value = "Contact person name at "
oVar("dirphone").Value = " "
oVar("mobil").Value = " "
oVar("email").Value = "...@"
oVar("DocAuthor").Value = "Name of document responsible"
oVar("fax").Value = " "
oVar("city").Value = " "
oVar("postalnr").Value = " "
oVar("street").Value = " "

End Sub

Private Sub cmdCancel_Click()
If ActiveDocument.ProtectionType = wdNoProtection Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True,
Password:=""

End If

If ActiveDocument.ProtectionType = wdAllowOnlyFormFields = True Then
ActiveDocument.Unprotect Password:=""

Else

If ActiveDocument.ProtectionType = wdNoProtection Then
ActiveDocument.Protect Type:=wdAllowOnlyFormFields,
NoReset:=True, Password:=""
Else
ActiveDocument.Unprotect Password:=""

End If
End If
ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True,
Password:=""
Unload Me
End

End Sub

Private Function CheckExistsCDP(CDPName As String, propcoll As Object)
As Boolean
Dim PrCust As Object
For Each PrCust In propcoll
If PrCust.Name = CDPName Then
CheckExistsCDP = True
Exit For
Else
CheckExistsCDP = False
End If
Next
End Function

Private Sub CmdOK_Click()

Set oVar = ActiveDocument.Variables
Set objCustomProperties = ActiveDocument.CustomDocumentProperties

If Not CheckExistsCDP("Project", objCustomProperties) Then
objCustomProperties.Add Name:="Project", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.txtprojname.Text
Else
objCustomProperties("Project").Value = Me.txtprojname.Text
End If

If Not CheckExistsCDP("Client", objCustomProperties) Then
objCustomProperties.Add Name:="Client", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.Txtclientname.Text
Else
objCustomProperties("Client").Value = Me.Txtclientname.Text
End If

'If Not CheckExistsCDP("Contact", objCustomProperties) Then
' objCustomProperties.Add Name:="Contact", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.txtcontactp.Text
'Else
' objCustomProperties("Contact").Value = Me.txtcontactp.Text
'End If

If Not CheckExistsCDP("DocType", objCustomProperties) Then
objCustomProperties.Add Name:="DocType", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.txtDocutype.Text
Else
objCustomProperties("DocType").Value = Me.txtDocutype.Text
End If

If Not CheckExistsCDP("DocAuthor", objCustomProperties) Then
objCustomProperties.Add Name:="DocAuthor", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.Txtnameofauthor.Text
Else
objCustomProperties("DocAuthor").Value = Me.Txtnameofauthor.Text
End If

'If Not CheckExistsCDP("fax", objCustomProperties) Then
' objCustomProperties.Add Name:="fax", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.txtfax.Text
'Else
' objCustomProperties("fax").Value = Me.txtfax.Text
'End If

'If Not CheckExistsCDP("city", objCustomProperties) Then
' objCustomProperties.Add Name:="city", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.txtstad.Text
'Else
' objCustomProperties("city").Value = Me.txtstad.Text
'End If

'If Not CheckExistsCDP("postalnr", objCustomProperties) Then
' objCustomProperties.Add Name:="postalnr", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.txtpostal.Text
'Else
' objCustomProperties("postalnr").Value = Me.txtpostal.Text
'End If

'If Not CheckExistsCDP("street", objCustomProperties) Then
' objCustomProperties.Add Name:="street", LinkToContent:=False,
Type:=msoPropertyTypeString, Value:=Me.txtstreet.Text
'Else
' objCustomProperties("street").Value = Me.txtstreet.Text
'End If


oVar("DocType").Value = Me.txtDocutype.Text
oVar("Project").Value = Me.txtprojname.Text
oVar("Client").Value = Me.Txtclientname.Text
oVar("PrefDate").Value = Me.txtdate.Text
oVar("Contact").Value = Me.txtcontactp.Text
oVar("Dirphone").Value = Me.txtdirphonenumber.Text
oVar("mobil").Value = Me.Txtmobil.Text
oVar("email").Value = Me.txtemail.Text
oVar("DocAuthor").Value = Me.Txtnameofauthor.Text
oVar("fax").Value = Me.txtfax.Text
oVar("City").Value = Me.txtstad.Text
oVar("postalnr").Value = Me.txtpostal.Text
oVar("street").Value = Me.txtstreet.Text
 
J

Jay Freedman

The easiest solution, I think, is to define all the document variables _in
the template_ to contain at least a space character. Then each document
based on the template will automatically start with all the variables
defined. (Setting a document variable's value to the empty string "" deletes
the variable.) That will prevent error messages in the DocVariable fields.

The reason you're seeing empty fields in your dialog is that the first time
the Userform_Initialize procedure tries to retrieve a value for an undefined
docvariable, the On Error trap sends execution immediately to the Handler
label. That error handler then defines all the docvariables, but it never
branches back to the beginning of the procedure to load the rest of the
fields in the userform. So an alternative would be to place a label
(something like StartAgain) just after the Set objCustomProperties
statement. Then, at the bottom of the error handler, add the lines

Err.Clear
GoTo StartAgain

As a separate issue, everything between the Exit Sub statement and the
Handler label should be removed. I assume those were just some things you
tried for debugging, but now it's dead (unreachable) code because of the
Exit Sub statement. The declaration and setting of objCustomProperties can
also be removed from Userform_Initialize, because that object isn't used in
that procedure -- it's used only in CmdOK_Click.

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
J

jab

Thanx a bunch Jay for your swift answer. I will try this tomorrow.
Signing off for today. I didn't even see the exit sub statement. Must
have been left there by mistake at some point. Boy one gets blind
sometimes

I will come back tomorrow and tellyou how it went

Kind Regards

Jan
 
J

Jay Freedman

Hi Jan,

I hope you see this before you get too frustrated...

You do need the Exit Sub statement, between the code that should be executed
and the error handler. If it's omitted, the error handler will execute every
time the code runs -- not what you want. Besides that, if you include the
GoTo to send execution back to the top of the procedure when an error
occurs, but omit the Exit Sub, then you'll get into an infinite loop.

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
J

jab

Hi Jay

Maybe I haven't done the changes you suggested in the correct way but
I think so...How does write the StartAgain lable..."StartAgain:"
right?

I still get the Error message in the document saying "Error! No
document variable supplied." when a value is not supplied in the
dialog. I want the the preset value in the handler to show when when
that value is left out by the user. Also, now, if ONE value is left
out ALL of the preset values for the different txtfields in the VBA
handler code fills the dialog fields if one bring up the dialog again
and not just the one field left out.

This is how I want it to work.
If the user decides to not fill in one of the fields that field will
still be populated with something (like a space character as you
suggested) thus preventing the error message to appear in the
document.

If the above has been done and the user brings up the dialog again,
all the variable values that contains the users priviously added
information, shall populate the fields in the dialog and NOT the
handler codes preset values.

I have to somhow controle what field(s) has been left empty and
populate that field(s) with a default value (like space). The other
fields in the document that contains the priviously user defined
values must populate the dialogs txtfileds when/if the users brings up
the dialog again.

Maybe a controle making sure that the user cannot leave a field
completely empty...better solution whould be that the code fills an
empty/left out field with a space. Please assist me futher.

Kind Regards Jan
 
J

Jay Freedman

Hi Jan,

Sorry, I didn't sufficiently analyze what your error handler was doing. The
handler should not set all the defaults at once when there's only one (or
more) nonexistent document variable. The better solution is to make a
separate subroutine that's called once for each document variable; that
subroutine will contain the error handler, which will set the proper default
value only for that variable.

Similarly, you should have a subroutine that is called once to transfer each
text box value to the document. If the text box value is an empty string
because the user deliberately left it empty, the corresponding document
variable (and custom document property) will be set to a single space
character.

This is the code I recommend. I've shown calls for only the Project and
Client variables, but I think you'll see what is needed for the others.

Private Sub cmdCancel_Click()
Unload Me
End Sub
'--------
Private Sub cmdOK_Click()
FillDocVariable tBox:=txtprojname, _
docVar:="Project", docProp:="Project"
FillDocVariable tBox:=txtclientname, _
docVar:="Client", docProp:="Client"
ActiveDocument.Fields.Update
Unload Me
End Sub
'--------
Private Sub UserForm_Initialize()
InitializeTextBox tBox:=txtprojname, _
docVar:="Project", defaultVal:="Project name"
InitializeTextBox tBox:=txtclientname, _
docVar:="Client", defaultVal:="Client name"
End Sub
'--------
Private Sub InitializeTextBox(tBox As TextBox, _
docVar As String, defaultVal As String)

Dim tmp As String
On Error GoTo Handler

tmp = ActiveDocument.Variables(docVar).Value
If Trim(tmp) <> "" Then
tBox.Text = tmp
Else ' value is one or more space characters
tBox.Text = ""
End If
Exit Sub

Handler:
tBox.Text = defaultVal
End Sub
'--------
Private Sub FillDocVariable(tBox As TextBox, _
docVar As String, docProp As String)

If Trim(tBox.Text) <> "" Then
ActiveDocument.Variables(docVar).Value = tBox.Text
Else ' value is one or more space characters
ActiveDocument.Variables(docVar).Value = " "
End If

If CheckExistsCDP(CDPName:=docProp) Then
ActiveDocument.CustomDocumentProperties(docProp).Value = _
ActiveDocument.Variables(docVar).Value
Else
ActiveDocument.CustomDocumentProperties.Add _
Name:=docProp, LinkToContent:=False, _
Type:=msoPropertyTypeString, _
Value:=ActiveDocument.Variables(docVar).Value
End If
End Sub
'--------
Private Function CheckExistsCDP(CDPName As String) As Boolean
Dim PrCust As DocumentProperty
CheckExistsCDP = False
For Each PrCust In ActiveDocument.CustomDocumentProperties
If LCase(PrCust.Name) = LCase(CDPName) Then
CheckExistsCDP = True
Exit For
End If
Next
End Function

While you're looking at this, notice that I've simplified the
cmdCancel_Click and CheckExistsCDP code. For the cancel button, you had a
lot of unprotecting and reprotecting for forms, accomplishing nothing that I
could see. For CheckExistsCDP , it's more efficient to set the return value
to False once, and then change it to True only if the property is found.
Also, when comparing strings, you should make sure their cases are the same.

--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
 
J

jab

Hi Jay

It all works like a dream now thanks to you.

The reason for the protect unprotect thing is that the area where the
variables are supposed to go in is protected to prevent users from
accidentally delete the variable placeholders. I guess I could skip
the noreset parts due to that I'm no longer using formfields.

Thnx again. I will definately study some more VBA!

Kind Regards

Jan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top