How do I store a variable permanently in a Word 2010 document using VBA? - vba

I know how to use variables in Word 2010 using VBA. However, they are all reset when the document in closed and reopened.
How do I store a variable permanently in a Word document?

This can be used:
Sub Test()
ActiveDocument.Variables.Add Name:="PermanentVar", Value:=100
'ActiveDocument.Variables("PermanentVar").Delete
End Sub
Check if it is retained:
Private Sub Document_Open()
Msgbox ActiveDocument.Variables("PermanentVar")
End Sub
Ref MS kb Link
Ref SO link

Use a custom document property instead. These are stored on the Word document permanently, and can be edited and retrieved using VBA.
To create a custom property, go to File > Properties > Advanced Properties (this will be in a slightly different place in older version of Word but will still be there somewhere...).
Go to the Custom tab from the advanced properties, and fill in the name of your custom document property, the field type (you can select text, date, number or a Yes/No flag, which should cover off most options), and a starting value - you have you include a starting value or the Add button will be greyed out. Click Add.
You now have a custom property in your document, and you can use VBA to manipulate and reference it.
To change the value of your property, use the following code:
Application.ActiveDocument.CustomDocumentProperties.Item(1).Value = "Your new value..."
Item(1) is set because this is reference the first custom document property in your document. If you have more than one custom property, you'll need to change the number to reference the correct property, or write some VBA that will reference the property by name.
To pass the property to a variable, use the following code:
strYourVariable = Application.ActiveDocument.CustomDocumentProperties.Item(1).Value

Related

Word 2013 - Macro Reference in .docx file

I have a pretty large template (in terms of macros) and I've created a new module that is called when the user does a specified shortcut on the keyboard.
The Macro does nothing more but call "ThisDocument.HideComboBoxes".
"HideComboBoxes" is a Sub in ThisDocument, which does the obvious: hide all combo boxes in the document.
The code works fine as long as I'm working with the template.
If I render a new document out of it (a docx file) the shortcut does not work anymore (which is kinda obvious because the ThisDocument is now empty for the document).
How do I access the template's ThisDocument from within the document or how can I hide the combo boxes from within the docx?
Here's the code for hiding the comboboxes in the template's ThisDocument:
Sub HideComboBoxes()
Me.ComboBoxConfi.Width = 1
Me.ComboBoxConfi.Height = 1
Me.ComboBoxState.Width = 1
Me.ComboBoxState.Height = 1
End Sub
Thanks in advance
You need to put the code in a "normal" module. This will require changing the calls to the ActiveX controls, which is a pain, but works.
Assuming the ActiveX controls are managed on the document surface as InlineShapes a call would look like this:
Dim cbConfi as Object 'or as MsForms.ComboBox to get Intellisense
Set cbConfi = ActiveDocument.InlineShapes([indexvalue]).OLEFormat.Object
cbConfi.Width = 1
If you don't want to rely on the index value (position of the control in the InlineShapes collection) you can select the ActiveX control and assign a bookmark to it. Or you can loop the collection of ActiveX controls, check the Type and, if it's a OLE object, check whether the Class type is MSForms.Combobox and then via OLEFormat.Object.Name whether its the right one.

Assign Shortcut keys within the VBE Window

From the Excel Window, I can assign a shortcut key to my macro by:
going to the Developer tab
touching the Macros button
touching Options... in the resulting Dialog Box
Can I assign this from within the VBE Window, using the VBE menu bar instead??
The Application.OnKey approach keeps the shortcut separate from the procedure (which makes maintenance difficult), and you might end up with conflicts - particularly if you've assigned keys using the Macros dialog and the Application.OnKey property. And, of course, you need the SetShortCutKeys code to run on workbook_open, which might not always run.
Fortunately, it is possible to assign the shortcut key in VBA, and within the procedure itself, but you'll need to export the module, edit the text file, and then reimport. Unfortunately, while VBA does maintain the code, the shortcut keys only seem to work in Excel. Perhaps it's a feature of VBA that the host application can optionally support.
Let's say you have the following VBA in a standard module:
Option Explicit
Public Sub Bar()
MsgBox "Bar"
End Sub
If you use the Macros dialog in Excel, and choose a shortcut key for the Bar macro to Ctrl+Shift+T, and then Export the module to a text file, you'll find the module source is:
Attribute VB_Name = "Module1"
Option Explicit
Sub Bar()
Attribute Bar.VB_ProcData.VB_Invoke_Func = "T\n14"
MsgBox "Bar"
End Sub
Notice the Attribute Bar.VB_ProcData.VB_Invoke_Func = "T\n14" attribute, which wasn't visible in the VBIDE, but is persisted by VBA in the underlying source. The T in T\n14 is a case-sensitive key (which implies a Shift), and I think the \n14 must refer to the Ctrl key. By following the VB Attribute naming pattern and syntax, and including similar lines in your other procedures, you can assign shortcut keys in other procedures using the text editor, and then, when you're done, you can import the modified module back into the VBA project.
Note that once you import the modified module, you'll no longer be able to see the attribute lines, and you'll need to take care not to change the name or number of parameters in the procedure, as the VBIDE might delete the underlying attribute without warning you.
Alternatively, if you want to do it using VBA you can do something like:
Sub SetShortcutKeys()
With Application
.OnKey Key:="^+K", Procedure:="YourMacroGoesHere"
End With
End Sub

MS-Word VBA reference identification

I have a custom content control in Microsoft Word from a third party I am trying to resize the width and height of. Normal content control selection via VBA is not working because this control has no Title or Tag. However, if I manually select the object and resize it programmatically using "Selection.ShapeRange.Height = x" or ShapeRange.Width it does work. So to do it all programmatically I need to determine the name of the "selection" without having to manually select it.
Is there a way to "inspect" the complete reference to the currently selected object in word, so we can then get a starting point to work with it in VBA?
It's hard to know what type of object your dealing with. I tested this by inserting a blank ActiveX image control, selecting it and then running the macro. The code has two methods but one is commented out.
Sub FindName()
MsgBox (Selection.Fields.Item(1).OLEFormat.ClassType)
'MsgBox (Selection.InlineShapes.Item(1).OLEFormat.ClassType)
MsgBox (Selection.InlineShapes.Item(1).Field.Index)
MsgBox (Selection.InlineShapes.Item(1).AlternativeText)
'Show current name
MsgBox (Selection.Fields.Item(1).OLEFormat.Object.Name)
'Set new name
Selection.Fields.Item(1).OLEFormat.Object.Name = "Image5"
'Re-display name to show that it changed
MsgBox (Selection.Fields.Item(1).OLEFormat.Object.Name)
End Sub
The result was this:

Change both the code name and the shape name of an activex optionbutton control in Excel vba

Excel VBA:
I am trying to get to some activex option buttons through the OLEObjects object, but I am finding that even though I change the value of (Name) in the property window for the object, it still requires the "OptionButton1" default name as a key.
I know that some of the objects in Excel VBA have a code name and another name which is also the one used for the key to get to it from OLEObjects, but I don't know how I can change this "other" name.
I am passing in my object name as a parameter (basically) to a function, so I can't just do :
ActiveSheet.optMyNewName.Value
or whatever. I need to be able to do this:
ActiveSheet.OLEObjects("optMyNewName").Object.Value
but currently only this works:
ActiveSheet.OLEObjects("OptionButton1").Object.Value
If you pass a string into the OLEObjects collection, it uses the Caption property as the key. Pass the caption as the parameter and it should work.

Building Word fields

Apart from just inserting and parsing text into a blank Word field, is there any way to programmatically build user-defined fields and field codes into my own templates with VBA? Furthermore, is there a way to make these fields show up in the list of available fields?
I recently developed a solution that used Word's MACROBUTTON and ADDIN field types.
I found MACROBUTTON useful because the third whitespace-delimited entry inside the field (programmatically field.code.text) is displayed within Word. This allows my users to watch fields as they move around. { MACROBUTTON NoMacro * } would display an "*" in Word, e.g. And it would do nothing when the user double-clicked on it, because I have purposefully not defined a macro named "NoMacro".
The ADDIN field does not display (except when display field codes is turned on) and stores a hidden string in its field.data property. Using this field I could have a hidden field the contents of which could not be seen or modified by users (excepting that if they turn on "show field codes" they can see that it is an ADDIN field (but they cannot see/edit the "data" property), and that they can delete this field just like any other field.)
I found these pages useful:
Using MacroButton fields
Using Addin Fields
What had you in mind? It is possible to add custom document properties either manually or with VBA. These are the accessible as fields under DOCPROPERTY:
{ DOCPROPERTY "Test" \* MERGEFORMAT }
You can use a macro to ensure that the custom property is added to documents:
Sub AutoNew()
Dim objCustomProperties As DocumentProperties
Set objCustomProperties = ActiveDocument.CustomDocumentProperties
objCustomProperties.Add Name:="Test", _
Type:=msoPropertyTypeString, Value:="Blah", _
LinkToContent:=False
End Sub
Further Information
Automacros: http://msdn.microsoft.com/en-us/library/aa263747(office.10).aspx
Understanding Custom Document Properties in Microsoft Office Word 2003: http://msdn.microsoft.com/en-us/library/aa537154.aspx