none
How does one unselect or deselect the selected item in a dropdown list content control with VBA? RRS feed

  • Question

  • My document has a dropdown list content control. In certain situations, I want to unselect or deselect the selected item if the user has selected an item in the list. I am using VBA in Word 2010 and 2013. I need to do this programmatically. I know how to select an item programmatically. I just need to deselect the item also.

    I have tried simply deleting the value of the list, but the protection level does not allow me to do it, even if I unlock the control's contents and even the control itself.

    Thanks,

    Van

    Friday, May 23, 2014 12:42 PM

Answers

  • Clearing the DropdownListEntries does not, of itself, reset the display to the placeholder text. There are good reasons for that. If you want to both clear the list and re-set the display to the placeholder text, use:

    With ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).DropdownListEntries
      .Item(1).Select
      .Clear
    End With

    Note: Having done this there are 0 items in the dropdown list but the placeholder text, being the last selected item, remains on display.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by Marvin_Guo Friday, May 30, 2014 2:26 AM
    Sunday, May 25, 2014 4:15 AM

All replies

  • If all you wan to do is to reset the dropdown to the 'Choose an item' display (i.e. the placeholder text), use code like:

    ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).DropdownListEntries(1).Select

    where 'MyCCtrl' is the content control title. You could use and reference the tag instead, if you prefer.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Friday, May 23, 2014 11:46 PM
  • Thanks Paul,

    There seems (at least to me) to be a misunderstanding about the placeholder text in a dropdown list. The placeholder text is not the same as the first item in the DropDownListEntries. To see this, do the following:

    Place a dropdown list content control in a document. The placeholder text is Choose an item. Now double-click the word Choose and replace it with Select. The placeholder text is now Select an item.

    Now open the properties of the dropdown. The first item in the list is Choose an item, NOT Select an item. Thus, the first item in the list is NOT the placeholder text.

    DELETE this first item from the list and close the properties box. The placeholder text continues to display Select an item. If you exit design mode and try to select something from the dropdown, you will find that it has no entries.

    Furthermore, add some items to the list. If you programmatically CLEAR the DropDownListEntries, the dropdown list now contains no entries but continues to display the placeholder text Select an item.

    Thus, the placeholder text is distinct and separate from the first item in the list. I believe making the first item equal to the placeholder text provides a workaround for what I am trying to do, namely remove the selection from the list. But doing so, displays Choose an item in black text not gray, as is the placeholder text.

    Regards, Van

    Saturday, May 24, 2014 3:26 PM
  • On my system (Word 2010, Win 7), it is not possible to double-click on 'Choose' in the 'Choose an item' placeholder text for either a dropdown or combobox content control unless you're in design mode - which isn't how content controls are meant to be used. Design mode is for development only. When you're in design mode, you can change the placeholder text - which is what you're doing. You're not changing the selection, but what the placeholder text displays. You can see that quite plainly by running the following code after changing the 'Choose' to 'Select':

    MsgBox ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).PlaceholderText


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Saturday, May 24, 2014 9:55 PM
  • I guess I was not explicit in the steps I was doing. To change the placeholder text, one must be in design mode. However one changes the placeholder in design mode, that change remains when NOT in design mode. My main point remains - the placeholder text is NOT the first item in the dropdown list NOR identical to it.

    Regards, Van

    Saturday, May 24, 2014 11:50 PM
  • You seem to be continually shifting the goal posts. In you first post you said:
    I want to unselect or deselect the selected item if the user has selected an item in the list
    I showed you how to do that.

    Then you came back saying:
    The placeholder text is not the same as the first item in the DropDownListEntries.
    which is quite wrong, and proceeded to try to prove that by changing the placeholder text and claiming that, because the default placeholder text isn't returned by the code I provided, my code is therefore wrong. My code is perfectly OK; it's your understanding of the placeholder text that is wrong.

    As for:
    However one changes the placeholder in design mode, that change remains when NOT in design mode.
    well, of course it does. What else would you expect? And, contrary to your assertion, the placeholder text is the first item in the dropdown list. Otherwise the code I posted wouldn't work. You can prove it for your self with code like:

    Sub Demo()
    Dim i As Long, StrOut As String
    With ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).DropdownListEntries
      For i = 1 To .Count
        StrOut = StrOut & "Index: " & .Item(i).Index & vbTab & .Item(i).Text & vbCr
      Next
    End With
    MsgBox StrOut
    End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Sunday, May 25, 2014 12:55 AM
  • Paul,

    The shift in goalposts was in response to your first post. My assertion is still correct.

    Take the code you listed in your last post. Just before the With statement insert the line

    ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).DropdownListEntries.Clear

    What does the MsgBox display? Turn design mode on and check the properties of the list. The list is empty. IF the user had selected an item before running this Sub, that item name continues to display even though the list is empty. IF nothing was selected before running the Sub, the placeholder text displays even though the list is empty.

    Here is a repeat of part of an earlier post, but with some clarification. Turn the design mode ON. Place a dropdown list content control in a document. The placeholder text is Choose an item. Now double-click the word Choose and replace it with Select. The placeholder text is now Select an item.

    Now open the properties of the dropdown. The first item in the list is Choose an item, NOT Select an item. Thus, the first item in the list is NOT the placeholder text.

    DELETE this first item from the list and close the properties box. The placeholder text continues to display Select an item.

    Turn design mode OFF. Try to select something from the dropdown, you will find that it has no entries but continues to display the placeholder text.

    Regards, Van

    Sunday, May 25, 2014 3:50 AM
  • Clearing the DropdownListEntries does not, of itself, reset the display to the placeholder text. There are good reasons for that. If you want to both clear the list and re-set the display to the placeholder text, use:

    With ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).DropdownListEntries
      .Item(1).Select
      .Clear
    End With

    Note: Having done this there are 0 items in the dropdown list but the placeholder text, being the last selected item, remains on display.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by Marvin_Guo Friday, May 30, 2014 2:26 AM
    Sunday, May 25, 2014 4:15 AM
  • Thanks  Paul,

    That is sort of what I wanted to do; however, I bet the displayed text is in black, not the gray of the usual placeholder text.

    I would ask you to try one more thing in an attempt to convince you of my assertion about placeholder text.

    In an earlier post, you included the following code:

    Sub Demo()
    Dim i As Long, StrOut As String
    ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).SetPlaceholderText , , "Some other text"
    With ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1).DropdownListEntries
      For i = 1 To .Count
        StrOut = StrOut & "Index: " & .Item(i).Index & vbTab & .Item(i).Text & vbCr
      Next
    End With
    MsgBox StrOut
    End Sub

    I added one line, in bold. Does the MsgBox include "Some other text" OR "Choose an item"? Check the properties of the dropdown. Does the list include "Some other text" OR "Choose an item"?

     Regards, Van

    Sunday, May 25, 2014 4:02 PM
  • That is sort of what I wanted to do; however, I bet the displayed text is in black, not the gray of the usual placeholder text.

    How about trying it?

    As for changing the placeholder text and displaying it in the dropdown, use something like:

    Sub Demo()
    Dim StrTxt As String
    StrTxt = "Some new text"
    With ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1)
      .SetPlaceholderText Text:=StrTxt
      On Error Resume Next
      .DropdownListEntries(1).Text = StrTxt
      On Error GoTo 0
    End With
    End Sub

    That will preserve the original colouring. If you're happy to have the new entry in whatever the underlying font colour is, you could use:

    Sub Demo()
    Dim StrTxt As String
    StrTxt = "Some other new text"
    With ActiveDocument.SelectContentControlsByTitle("MyCCtrl")(1)
      .SetPlaceholderText Text:=StrTxt
      With .DropdownListEntries
        .Item(1).Delete
        .Add Text:=StrTxt, Index:=1
      End With
    End With
    End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Sunday, May 25, 2014 9:42 PM
  • Something that may be relevant to this discussion, but I have not seen mentioned:

    If you define an item in the dropdown's Properties as having a blank value (i.e. empty), then selecting that item (in the UI or programmatically) displays the placeholder text.

    By default, the first item has a blank value, and none of the other items can have a blank value. You can change that around, but by default that means that selecting the first value displays the placeholder.

    However, if you want all your items to have non-blank values, then selecting item 1 will not display the placeholder - it will display item 1. Or if you set the value of some other item to blank, you would have to select that item to see the placeholder.

    So in the situation where you want every item to have a non-blank value, you could I think use

    Sub showDDPlaceholder()
    Dim s As String
    With ActiveDocument.ContentControls(2)
      s = .DropdownListEntries(1).Value
      .DropdownListEntries(1).Value = ""
      .DropdownListEntries(1).Select
      .DropdownListEntries(1).Value = s
    End With
    End Sub
    In the situation where you don't know whether you had a blank value or not, you would have to iterate the items to see if one was blank, then decide what to do.



    Peter Jamieson

    Monday, May 26, 2014 10:13 AM
  • Peter,

    Your point is relevant, but I believe you are sidestepping the issue.

    Recall that each item in the list has two properties, Name and Value. When you add a dropdown content control to a document in design mode and then open its properties, Word sets the Name of the first item to the placeholder text and its Value blank. Selecting an item with a blank Value shows the placeholder text ONLY because the Name of that item has been set equal to the placeholder text NOT because the item has a blank Value.

    You can convince yourself by changing the placeholder text programmatically (SetPlaceholderText) but DO NOT change the Name of that blank Value item. Then select the blank Value item. The control displays the Name of the item (the original placeholder text), NOT the new placeholder text.

    Regards, Van

    Monday, May 26, 2014 1:20 PM
  • That isn't how it works in my experiments here. (Win 7, Word 2010). I'd already modified the placeholder text before, so I already had different placeholder and Item1 texts. Selecting item1 behaves as I described. Modifying the placeholder programmtically doesn't appear to make a difference, although I haven't actually tried setting it to a building block rather than a text or the text from a range.

    To me that suggests that there is something else going on, but it isn't obvious what. I haven't checked on Word 2013 yet - are you mostly using that for your testing?

    Edit:
    What is the protection level problem that you mentioned?


    Peter Jamieson


    Monday, May 26, 2014 2:45 PM
  • Just thinking on another tack, are you actually using a Combo Box, not a Dropdown List? A COmbo box would behave along the lines you describe.

    Peter Jamieson

    Monday, May 26, 2014 3:10 PM
  • It is a Dropdown list, not a combo box.

    Van

    Monday, May 26, 2014 5:08 PM
  • Perhaps you could step through the following VBA in the VBE and see if the things I have suggested are "Expected" are actually what (a) are listed in the Immediate Window and (b) are what appear in your List Box.

    You need to start with a blank document.

    Sub ddTestPart1()
    Dim cc As Word.ContentControl
    Set cc = ActiveDocument.ContentControls.Add(wdContentControlDropdownList)
    With cc
      ' Expect "Choose an item"
      Debug.Print "Default Placeholder text: " & .PlaceholderText
      ' Expect "Choose an item"
      Debug.Print "CC value A: " & .Range.Text
      ' Expect 0 (different from when you create the CC using the UI)
      Debug.Print "Count of list entries: " & .DropdownListEntries.Count
      ' create a different text from the default placeholder text
      .DropdownListEntries.Add Text:="Entry 1", Value:=""
      ' and 3 more
      .DropdownListEntries.Add Text:="Entry 2", Value:="Value 2"
      .DropdownListEntries.Add Text:="Entry 3", Value:="Value 3"
      .DropdownListEntries.Add Text:="Entry 4", Value:="Value 4"
      ' Expect "Choose an item"
      Debug.Print "CC value B: " & .Range.Text
      
      ' Select entry 3
      .DropdownListEntries(3).Select
      ' Expect "Entry 3"
      Debug.Print "CC value C: " & .Range.Text
      
      ' change the placeholder text
      .SetPlaceholderText Text:="new ptext"
      ' Expect "Entry 3"
      Debug.Print "CC value D: " & .Range.Text
      
      ' Select entry 1
      .DropdownListEntries(1).Select
      
      ' Expect "new ptext"
      Debug.Print "CC value E: " & .Range.Text
      .DropdownListEntries(1).Select
      
      ' Select entry 2
      .DropdownListEntries(2).Select
      ' Expect "Entry 2"
      Debug.Print "CC value F: " & .Range.Text
      
      ' modify entry 1's value to be non-empty
      .DropdownListEntries(1).Value = "abc"
      ' Expect "Entry 2"
      Debug.Print "CC value G: " & .Range.Text
      
      ' Select entry 1
      .DropdownListEntries(1).Select
      
      ' Expect "Entry 1"
      Debug.Print "CC value H: " & .Range.Text
        
      ' select entry 4
      .DropdownListEntries(4).Select
      ' Expect "Entry 4"
      Debug.Print "CC value I: " & .Range.Text
      
      ' modify entry 1's value to be empty
      .DropdownListEntries(1).Value = ""
      ' Expect "Entry 4"
      Debug.Print "CC value J: " & .Range.Text
     
      ' Select entry 1
      .DropdownListEntries(1).Select
      
      ' Expect "new ptext"
      Debug.Print "CC value K: " & .Range.Text
      .DropdownListEntries(1).Select
     
     End With
    Set cc = Nothing
    End Sub



    Peter Jamieson

    Monday, May 26, 2014 9:26 PM