I am struggling quite a bit with ContentControl(s) in my Word VBA project. There are a number of content control text fields which all have the same name (they have the same name because at the beginning the total number of required fields is not known, so I copy and paste the fields as many times as required). Now I want to loop through the content control fields and change the name of the fields based on the index of the individual items (e.g. first field in the document = "One", second field in the document = "two" and so on).
However, as mentioned in other threads, the index of the content control element does not correspond to its position in the document (I do not know, what it corresponds to). Thus, instead of getting the fields in order, I get e.g. "four" --> "one" --> "three" --> "two" (or any other possible combination).
The content of the fields is coming from UserForm TextBoxes. The text boxes are named Text_Box_1 to Text_Box_4:
Private Sub Test() 'Note: The actual code is more complex, this is just to demonstrate my problem.
Dim i As Integer
UserForm1.TextBox1 = "one"
UserForm1.TextBox2 = "two"
UserForm1.TextBox3 = "three"
UserForm1.TextBox4 = "four"
For i = 1 To 4 - 1 'Since there are four text boxes in the UserForm in this example, the text snippet containing the text field gets copied and pasted three times; Note: Here the number of textboxes is pre-determined and fixed, in the actual project, it is variable.
ActiveDocument.Bookmarks(Index:="Copy").Range.Copy '
ActiveDocument.Bookmarks(Index:="Paste").Range.Paste
Next i
For i = 1 To 4 'This code is supposed to loop through the four content control text fields and insert text from the corresponding UserForm text box. However, content control text field 1, unfortunately does no correspond to UserForm.TextBox1 for some reason.
ActiveDocument.SelectContentControlsByTitle("Number").Item(i).Range.Text = UserForm1.Controls("TextBox" & i)
Next i
End Sub
Is there any way to name to content control fields in the right order? If not, what would be an alternative method to achieve my goals. I think legacy text fields are not an option, since the document has to be protected; I have not looked into ActiveX text fields too much; Text boxes (shapes) might be another option, but they might have their own drawbacks.
It is really frustrating that the content control fields are behaving so weirdly and that something seemingly very simple and straight-forward can be so complicated (at least for me).
edit: Fixed a typo in the title.
Rather than use copy and paste I would insert the required text and content controls in my routine, something like this.
Private Sub Test()
Dim i As Integer
UserForm1.TextBox1 = "one"
UserForm1.TextBox2 = "two"
UserForm1.TextBox3 = "three"
UserForm1.TextBox4 = "four"
Dim cc As ContentControl
Dim rng As Range
Dim ccLocation As Range
For i = 4 To 1 Step -1 'Insert in reverse order to ensure that they are correct in the document
Set rng = ActiveDocument.Bookmarks("Paste").Range
rng.InsertAfter Text:="Number: "
rng.Collapse wdCollapseEnd
Set ccLocation = rng.Duplicate
rng.InsertAfter vbCr & "----------------------------------------" & vbCr
Set cc = ccLocation.ContentControls.Add(wdContentControlText)
cc.Range.Text = UserForm1.Controls("TextBox" & i).Text
cc.Title = "Number" & i
Next i
End Sub
If you cannot delete the existing content and must work with what you have then you could use the following:
Private Sub Test()
Dim i As Integer
UserForm1.TextBox1 = "one"
UserForm1.TextBox2 = "two"
UserForm1.TextBox3 = "three"
UserForm1.TextBox4 = "four"
ActiveDocument.SelectContentControlsByTitle("Number").Item(i).Range.Text = UserForm1.Controls("TextBox1").Text
Dim cc As ContentControl
Dim rng As Range
Dim ccLocation As Range
For i = 4 To 2 Step -1 'Insert in reverse order to ensure that they are correct in the document
Set rng = ActiveDocument.Bookmarks("Paste").Range
rng.InsertAfter Text:="Number: "
rng.Collapse wdCollapseEnd
Set ccLocation = rng.Duplicate
rng.InsertAfter vbCr & "----------------------------------------" & vbCr
Set cc = ccLocation.ContentControls.Add(wdContentControlText)
cc.Range.Text = UserForm1.Controls("TextBox" & i).Text
cc.Title = "Number" & i
Next i
End Sub