Hi Jim,
If you dig back far enough in this thread, you'll find that I did say "Also,
if the field might be revised after it's already been filled once, you would
want a mechanism to "read" the form field and select the corresponding items
in the list box before the userform appears."
This isn't too difficult -- essentially, the code of the Userform_Initialize
procedure has to take the current contents of the field (if any), break it
into its items, and select each item where it appears in the list box on the
userform.
But wait! What if the user has edited some or all of the items in the field
so they don't match the items in the list box? The code won't be able to
select anything for them. The solution is to store a copy of the field
contents where the user can't make a mess of it. That place is a "document
variable", a string that's stored invisibly and accessible only to macro
code, and that's stored in the document file during each save. This makes
the macro code more complex, but with the benefit of predictable behavior.
Here are the modified cmdClose_Click and Userform_Initialize procedures. (Of
course, you'll have to fold in your process for loading the list box's
..List, and change the names of fields, buttons, etc. as necessary.) You can
give any value (not containing spaces or punctuation, and I think up to 32
characters) to the constant myVarName.
Const myVarName = "JGitems"
Private Sub cmdClose_Click()
Dim rslt As String
Dim inx As Long
With ListBox1
For inx = 0 To .ListCount - 1
If .Selected(inx) Then
rslt = rslt & .List(inx) & vbCr
End If
Next
End With
If Right(rslt, 1) = vbCr Then
rslt = Left(rslt, Len(rslt) - 1)
End If
With ActiveDocument
.Variables(myVarName).Value = rslt ' <== new
.Unprotect
.Bookmarks("Text1").Range.Fields(1).Result.Text = rslt
.Protect Type:=wdAllowOnlyFormFields, NoReset:=True
End With
Unload Me
End Sub
Private Sub UserForm_Initialize()
Dim myVar As Variable
Dim myList As Variant
Dim myItem As Variant
Dim inx As Long
' change this to use your data
ListBox1.List = Array("one", "two", "three", "four", "five", "six")
With ActiveDocument ' <== new from here to End Sub
For Each myVar In .Variables
If myVar.Name = myVarName Then
myList = Split(myVar.Value, vbCr)
For Each myItem In myList
For inx = 0 To ListBox1.ListCount - 1
If ListBox1.List(inx) = myItem Then
ListBox1.Selected(inx) = True
Exit For
End If
Next inx
Next myItem
Exit For
End If
Next myVar
End With
End Sub
The new line in cmdClose_Click just assigns the value of rslt to the
document variable (and creates the variable if it doesn't already exist).
The new code in UserForm_Initialize first loops through the existing
document variables (if any) until it finds one whose name matches myVarName.
(If there are no variables, or if none have that name, the loop does
nothing.) This loop is necessary because trying to access a nonexistent
document variable causes an error. Although this could be handled by an On
Error statement, I prefer not to use the "I expected this error" method of
programming when it's easily avoided.
If the loop finds the right variable, it uses the Split function to make a
"variant array" containing the separate items within the variable's value.
The splits occur at the vbCr characters.
The next thing is to loop through all the separate items in the variant
array. For each one, the "For inx" loop finds the corresponding item in the
list box's .List and makes it selected.
--
Regards,
Jay Freedman
Microsoft Word MVP
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.