I have several plain text content controls in a Microsoft Word 2010 document. Through VBA code, I am using the Document_ContentControlOnExit event to validate the information upon exiting each text box content control. The code for the first text content control works fine. However, when I use the same code to validate the other text content controls albeit substituting the appropriate function parameters, I get a VBA error of "Ambiguous Name Detected". A sample of my code appears below:
private sub Document_ContentControlOnExit(ByVal text1 as ContentControl, cancel as Boolean)
if text1.ShowingPlaceholderText Then 'Field is empty
msgBox "This field cannot be blank"
cancel = True
End if
End sub
text1 is the value for the tag property of first text box content control.
What am I doing wrong here? I appreciate any help given!
Ambiguous Name Detected usually means there's more than one function with the name. Search for Document_ContentControlOnExit and delete unwanted duplicates.
Using the default name for the content control parameter (or just "cc") instead of "text1" would be best since it's the current control that's referenced in the sub.
Here's a file with your code working
https://dl.dropboxusercontent.com/u/13440554/share/ContentControlOnExit.docm
Hope this helps
Related
Edit: I've updated the post with more info.
I have a Content Control inside a header in Word in which I have a date time picker. I'm trying to fire the _ContentControlOnExit event when the user leaves the focus (blurs) of the picker.
Let's suppose I've manually created a Content Control and I've assigned it a Date Picker. I've also tagged it with the value date.
I want that each time the date is changed, I perform a subroutine that will insert a text value to another ContentControl tagged tide-level. I tried the code below with no success.
Please, note that the date ContentControl is inside a header in the Word Document.
Private Sub ActiveDocment_ContentControlOnExit(ByVal ContentControl As ContentControl, Cancel As Boolean)
If (ContentControl.Type = wdContentControlDate) Then
MsgBox "Let's do it! Write the tide levels"
dateObj = ActiveDocument.SelectContentControlsByTag("tide-level")
dateObj.Range.Text = "wwwoohooo Tide Levels!"
Cancel = True
End If
End Sub
I remember reading somewhere that whenever you have content in the header, it seems things get problematic...
Any ideas?
P.S:
Currently using Word 365 - VBA
Based on the name of the procedure in the question - ActiveDocment_ContentControlOnExit - it appears the event handler was not generated automatically by Word and that it is therefore not in the ThisDocument class module of the document that contains the content controls. The name of the event handler (generated by the VBA editor) is usually Document_ContentControlOnExit.
The content control event handlers must be in ThisDocument. Theoretically, they could be typed manually, but Word doesn't always recognize manually typed event handlers. So it's better to use the VBA Editor's automatic "stub" generation to get the structures:
Open the ThisDocument module for the document that contains the content control.
In the code page window, at the top left, select "Document" from the drop-down.
from the top-right select the event to be inserted.
At this point, the VBA editor will create the "stub" for you - all that's needed is the code to be executed.
Note about the content control being in the header: This event does fire as long as focus when exiting remains in the header. If, however, the user double-clicks in the document body in order to exit the header the event doesn't fire. (At least, not in my tests.) If this is a problem you may want to put this field in the body of the document with a second, linked content control in the header to reflect the selection. Doing this is a bit complex (requires a Custom XML Part in the document to manage the linked information), but the version of Word you're using should have a tool for setting it up.
the macro name should be:
Docment_ContentControlOnExit
NOT:
ActiveDocment_ContentControlOnExit
I have a Microsoft Word document with .docm format. A first glance it does not contain any macros (as when clicking the following on the ribbon; View -> Macros -> View macros pops up a window having an empty list).
But when enabling the Developer ribbon tab, and clicking the Visual Basic icon there, and then selecting the Document and ContentControlonEnter from the dropdowns in the VB window the following code appears:
Private Sub Document_ContentControlOnEnter(ByVal ContentControl As ContentControl)
Dim i As Long, j As Long
With ActiveDocument
If ContentControl.Title = "Classification" Then
ContentControl.DropdownListEntries.Clear
For i = 1 To .ContentControls.Count
If Left(.ContentControls(i).Title, 5) = "Level" Then
j = j + 1
ContentControl.DropdownListEntries.Add Text:=j & " - " & .ContentControls(i).Range.Text
End If
Next
End If
End With
End Sub
Selecting the other options in the dropdowns give only "blank" code (that is they contain only function declarations followed by theEnd keyword).
My question is what is the code meant to do?
*
Details:
The Word document in question contains hyperlinks to parts of the same document and a couple of links to Word files and Excel files of the same folder. It also contains lots of content control boxes, which I'm guessing is the focus of the code (as the code contains the ContentControl keyword)
Content controls can trigger macros when the user enters and exits them. Microsoft made the design decision that all content controls should trigger the same "events" - Document_ContentControlOnEnter / Document_ContentControlOnExit - and that the code in the event needs to check which content control was entered / exited.
Content controls are considered as part of the Document because the Document can trigger events. That's why they're in (and MUST be in) the ThisDocument class module.
(Note: View Macros can only show you PUBLIC SUB procedures with no arguments that are located in "normal" code modules. Any Private Sub, any Function, anything that takes a parameter and anything in a class module will not appear in that list. So you can't use that list to determine whether a document contains any code.)
The If ContentControl.Title = "Classification" Then checks which content control was entered. (Note: it usually makes more sense to use Select Case rather than If, especially when the event needs to distinguis between multiple content controls.) What's inside the If only executes if it was a content control with the Title "Classification". (Note that more than one content control can have the same Title, so more than one content control could run the code.)
If another content control is entered, the event is still fired, but nothing happens (in this case).
Catalin Pop correctly explained that the code is, in essence, "resetting" the drop down list.
Legacy Form fields use a similar pattern - macros can fire when the user enters/exits an form field. But the design for that was you had to create a Public Sub and assign that to the form field in the Properties.
I think the logic here is quite simple.
Basically the code searches for a content control named Classification within the entire document.
After it finds it, it clears all of its drowdown entries - like a reset.
After the cleaning part it again searches through the entire document for all content control that start with word "Level" and it collect the text for those controls and their order in appearance.
With this info collected it then fills the dropdown optios for the classification control above. (e.g. 1 Level X, 2 Level Y.. - based on what it finds in the document for controls starting with Level in their name)
I am using Excel 2013. I have added an activex control to my spreadsheet. The control is a checkbox which I have named chkAD1. My spreadsheet is called "timeseries_AD".
I am trying to reference the checkbox to check its value however without any joy. I have tried the lines below,
worksheets("timeseries_AD").OleObjects("chkAD1").Value
This results in the error message "unable to get the OLEObjects property of the worksheet class".
I have read that an activex control has two names. One is the name of the shape that contains the control the other is the code name. I'm not sure which one I have changed. I clicked on my control and in the Name Box renamed it to "chkAD1". Is that the shape name or code name I have changed?
UPDATE - Apologies
Sorry the control I added is not an activex control it is actually a form control.
I tried this and it worked for me.
When I check the box I get a messagebox that says TRUE.
And when I uncheck it I get a messagebox that says FALSE
Private Sub CheckBox1_Click()
MsgBox CheckBox1.Value
End Sub
I currently have a form. The form contains a subform that displays a Query. The Form also has 2 Text Boxes and buttons for both Boxes. The first box acts as a filter for the query to filter specific record. The second box is intended to be used to hide columns in the query. My issue is that my code will not recognize the text box, or any outside source from my form as a Field Name to be found. Here is my current code:
Private Sub Command137_Click()
Forms![Vermont]![Query1 subform].Form.[Query1 Field Name].ColumnHidden = True
End Sub
Currently if I replace "Query1 Field Name" with any field name that exists in the query the column will hide. However if replaced with anything else I recieve the following error:
"Runtime Error '2465'
Microsoft Access Can't Find the Field '|' reffered to in your expression"
I am pretty sure that I am not referencing the Form Control correctly. I have tried replacing [Query1 Field Name] with the following:
[Text142.Text]
[=Text142]
[Text142]
[Forms![Vermont]![Text142]]
I am very new to VBA but I definitely feel as if this is an easy fix; if possible.
Thank you in advance for any help!
Subform references are always a bit weird. This should work, though:
Forms![Vermont]![Query1 subform]![Text142].ColumnHidden = True
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: