How to refer to Word Field by name in VBA Code? - vba

I want to update a word field content using VBA. I already have a code that works, but I have to refer to the field's index instead of field's name, which I would prefer.
The code I have is as follows:
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields(1).Result.Text = myString
End Sub
Suppose that the field's name is MyField1. The following code will not work (I get the Run-time error '13': Type mismatch'.
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields("MyField1").Result.Text = myString
End Sub
I create my word fields from File Menu > Informations > Advanced Properties > Custom Tab.
So, how to refer to the field's name when we want to update its content?

These are DocProperty fields. If you press Alt+F9 you'll see the field codes.
A DocProperty field references (links to) a Document Property. The Document Property has the name, but this does not "name" the field. Nor is it possible to update a DocProperty field directly since it links to the Document Property. It might be possible to make it temporarily display something else, but this will be lost any time the field is updated.
In order to update a DocProperty field it's necessary to update the underlying Document Property. For example
Sub EditDocPropUpdateDocPropertyField()
Dim doc As Word.Document
Dim prop As Office.DocumentProperty
Dim propName As String
Dim newPropValue As String
Set doc = ActiveDocument
propName = "MyField"
newPropValue = "new value"
Set prop = doc.CustomDocumentProperties(propName)
prop.value = newPropValue
doc.Fields.Update
End Sub

In the VBE, the Object Browser is a great way to find out what's possible. When I find Word>Field and click on it, I see a list of the members of Field. Name is not in that list. This means that the field object does not have a Name property. That's why you get the error.
You can work around this. One way is to create a bookmark around the field in question. Then in code, find the bookmark by name, then find the field by index inside the bookmark range.

Sample to set text to fields by field name:
ThisDocument.FormFields.Item("MyField1").Result = "hello"

Related

How to search only the first line of a multiline textbox in VB.NET

Is there any way to search only the first line of a Multiline Textbox without knowing exactly at what position the text is you're looking for?
If I knew the position of the text I was looking for I could do something like:
Dim myNotes As String = "The book has a lot of text"
Dim myText As String = "text"
If Not myNotes.Substring(0,4) = myText Then
' Do Something
End If
Or if I wanted to search the entire textbox I could do something like:
Dim myNotes As String = "The book has a lot of text"
Dim myText As String = "text"
If Not myNotes.Contains(myText) Then
' Do Something
End If
But I want to search only the first line of the textbox and I'm not sure at what position the text may be. Is there anyway to do a search like that?
This is another example of why you should ALWAYS read the relevant documentation. If you had read the documentation for the TextBox class then you'd know that it has a Lines property. To get the first line of text, you simply get the first element of that array:
Dim firstLine = myTextBox.Lines(0)
If Not filrstLine.Contains(myText) Then
'Do something
End If
Note that this only applies where the user has explicitly added a line break to the text. I assume that that is what you want, given that you have accepted another answer that does the same thing. If you mean the first line based on automatic word-wrap then that requires a bit more effort.
You could take the text and extract the first line.
int pos = text.IndexOfAny('\r', '\n');
if (pos >= 0)
text = text.SubString(0, pos);
// text now contains only the first line
Then you can search the resulting string.

Append Strings and values together to target a form control in VBA

I'm so close to getting this code working, I just need a little push please. I would like to
take the name of a combo box and then add a string to the end, But then get the value of a textbox with that string. This is to create a dynamic function instead of pasting the same code over and over.
Here's what I have so far, after you select something in the dropdown, the data is then pulled to populate the boxes next to it. I have about 8 drop downs so far so that's why I need this to work.
'Combobox after update
Call GrabData(Me, Me.ActiveControl)
Then
Private Sub GrabData(ctl As Control)
'name of ctl/combobox is "Kitchen"
data1 = (ctl.Name & "Size") '"KitchenSize"
'Here is where it all goes wrong
data1.Value = size.value
'size.value is just a textbox for example
End Sub
I can debug this with:
msgbox(data1)
'outputs "KitchenSize"
But I cannot get the value of kitchensize's textbox with data1.value
Error:
Object Required
I have also added Dim As String / Dim As Control.
I will be assigning the variable to some other stuff in this 50 line code I wrote so please don't take the above example as exactly what I intend to do, I just need help appending the ctl.name to a string, then use that to reference another control and so on.
EDIT
For anyone who wants to know, I figured it out.
Dim Ctrl As Control
Dim CtrlName As String
CtrlName = ctl.Name & "Size"
Set Ctrl = Me.Controls(CtrlName)
Ctrl.Value = 'Wherever you want to send the values to
See the edit.
You need to dim it as a string, then use Set Ctrl

Is there an easy VBA code using Split() Function to get a list of values for a combo box that was originally from a text box as a string?

On my access form, I have a text box that will be a string of characters with multiple "/"s throughout the string. I want to use the split function to separate this string into a list of values to use for my combo box on a subform.
I know it's somewhere along the lines of:
Public Function MakeList()
Dim MyList as String
Dim txt as String
txt = [myTextBoxField].Value
MyList = Split(txt,"/")
Either:
[myComboBox].Value = MyList
Or:
[myTextBoxField].Value = MyList
End Sub
I am not sure if this is supposed to be on "Form Load" or in a module for the Public Function.
All other code shows a For Loop or Debug.Print. I am looking to store this list as a field in my table and then use that field for my Row Source in my combo box.
First, combobox RowSourceType property must be set to ValueList. Next, VBA sets RowSource property, not Value. List is not a property of combobox in Access. Simply:
Me.myComboBox.RowSource = Replace(Me.myTextBoxField, "/", ";")
Form Load event should be appropriate.

Word CheckBox ContentContol OnChange Event

I try to make a word document with two checkboxes where each checkbox will show/hide a part of the document with a custom style.
I plan to set value Style.Font.Hidden = True/False depending from checkbox values, but...
I found that there are 3 types of controls:
Legacy Controls - This seems old the ugly.
ActiveX Controls - I can easyly attach to checkbox onChange events, but these are also ugly and I think it's not that secure, also this is probably now working on mac.
ContentControls - This seems like the right way to do this, but I just can't attach to the right event. (Also there is some XML attachment described, but I'm not using this, this seem too complicated, I don't know.)
Can you tell me how to atach to onChange event of CheckBox ContentContol? I need the same behaviour like it's ActiveX CheckBox.
Content Controls do not have "onChange" events, so you can't get a content control to behave like the ActiveX checkbox in a simple manner. Similarly to form fields, the code for ContentControls fires when the control is entered/exited.
The only way to emulate "onChange" for a Content Control is to link the content control to a node in a CustomXMLPart in the document then work with the Document_ContentControlBeforeStoreUpdate event that triggers when the content of the node in the CustomXMLPart is going to be changed.
If, as your question indicates, this is too complex for your purposes you could use a MacroButton field that displays a font character (Symbol) that looks like a checkbox. Clicking the field would exchange that character for a different one, that looks checked. And the reverse again for the next click. Here's some sample code to get you started. If you don't like the checkboxes I chose, you can pick something else from Insert/Symbols/Symbol. Just change the character numbers and the font name.
By default a MacroButton field triggers on double click. You can change this to a single click when the document is opened in an AutoOpen macro.
Sub AutoOpen()
Application.Options.ButtonFieldClicks = 1
End Sub
Sub ToggleCheckBox()
Dim iNotChecked As Integer, iChecked As Integer
Dim rngCheck As word.Range
Dim sBkmName As String, sFontName as String
iNotChecked = 111
iChecked = 253
sBkmName = "bkmCheck"
sFontName = "Wingdings"
Set rngCheck = ActiveDocument.Bookmarks(sBkmName).Range
If Asc(rngCheck.Text) = iNotChecked Then
rngCheck.Text = Chr(iChecked)
ActiveDocument.Bookmarks.Add sBkmName, rngCheck
rngCheck.Font.Name = sFontName
ElseIf Asc(rngCheck.Text) = iChecked Then
rngCheck.Text = Chr(iNotChecked)
rngCheck.Font.Name = sFontName
ActiveDocument.Bookmarks.Add sBkmName, rngCheck
End If
End Sub

Combobox assignment of variable

If I put:
variableName = namecombobox.selectedItem
or
Dim variablename as type = namecombobox.SelectedIndex
Visual Studio gives me the error
Option Strict disallows conversions from object to string.
I can fix this by putting:
variableName = convert.ToString(namecombobox.SelectedItem)
Are all values contained in a combobox automatically treated as a non-string even when they are string values (in this case "Male" & "Female") and what is the correct way of assigning the value selected in a combobox to a variable?
This is normal, the ComboBox.Items property is a collection of System.Object. You should use the item's ToString() method, just like ComboBox does to generate the visible text.
Dim variableName As String = namecombobox.SelectedItem.ToString()
Or use CStr(), the VB.NET way.
If you are using this, assuming you select 'Selection1' on the combo box:
Dim x As Boolean
Dim MyVariable As String = ""
MyVariable = ComboBox1.SelectedItem.ToString()
If MyVariable = "Selection1" Then
x = True
Else
x = False
Pretend the above code is YOUR code... This is CORRECT for selecting strings from a ComboBox. Insert a breakpoint on the IF statement checking "MyVariable"- you will see the variable content if you hover your mouse over the variable name. It is a quick way to view the contents of your variable. If hovering above the variable shows an empty string ("") or simply Nothing, then it hasn't picked up any selected item.
In my code above, if I clicked an item containing the words "Selection1", the 'MyVariable' would contain a String of "Selection1" and the boolean variable 'x' would also read as TRUE.
If you're getting reading errors by comparing the variable you have issues elsewhere in your code.