Использовать ссылку на динамически создаваемый элемент управления в Word VBA

Я пишу форму в Word 2003, чтобы собрать несколько ответов на один вопрос. У меня есть макрос при нажатии кнопки, который дублирует различные поля ввода (раскрывающиеся списки, переключатели и т. Д.), Готовые для нового ответа.

Однако мне нужно изменить текст переключателей и установить событие OnChange в поле со списком, и я не могу найти для этого правильный синтаксис. Оба элемента управления находятся на панели инструментов «Панель инструментов управления».

Код макроса, который я должен продублировать для элементов управления, приведен ниже.

Private Sub CommandButton11_Click() 
Set Doc = ActiveDocument
Response = MsgBox("Add another response?", vbYesNo, "Confirm action")
    If Response = vbYes Then
        If Doc.ProtectionType <> wdNoProtection Then
          Doc.Unprotect
        End If

        Selection.MoveRight
        Selection.MoveDown
        Selection.TypeParagraph
        ''# keep the reference to this control and set the OnChange event handler
        Selection.InlineShapes.AddOLEControl ClassType:="Forms.ComboBox.1"
        Selection.MoveRight Unit:=wdCharacter, Count:=1
        Selection.TypeText Text:=vbTab
        Selection.TypeText Text:=vbTab
        ''# keep the reference to this control and set text
        Selection.InlineShapes.AddOLEControl ClassType:="Forms.OptionButton.1"
        Selection.MoveRight Unit:=wdCharacter, Count:=1

        Doc.Protect Type:=wdAllowOnlyFormFields, NoReset:=True
    End If
End Sub

person Community    schedule 24.11.2008    source источник


Ответы (1)


динамическое добавление обработчиков событий немного сложно.

Вы можете динамически добавлять код в ThisDocument. Это способ, описанный Microsoft: http://support.microsoft.com/?scid=kb%3Ben-us%3B246299&x=14&y=10. Однако, когда я попробовал этот Word 2007, вылетел.

Другой способ - добавить класс для обработки событий и создать экземпляр этого класса для каждого элемента управления. Поместите следующий код в модуль:

Option Explicit

Public objControls() As clsComboBox

Private Sub CommandButton11_Click()
    Dim objShape As InlineShape

    If ActiveDocument.ProtectionType <> wdNoProtection Then
        ActiveDocument.Unprotect
    End If

    Selection.MoveRight
    Selection.MoveDown
    Selection.TypeParagraph
    ' keep the reference to this control and set the OnChange event handler
    Set objShape = Selection.InlineShapes.AddOLEControl(ClassType:="Forms.ComboBox.1")
    With objShape.OLEFormat.Object
        .AddItem "Item 1"
        .AddItem "Item 2"
    End With

    Selection.MoveRight Unit:=wdCharacter, Count:=1
    Selection.TypeText Text:=vbTab
    Selection.TypeText Text:=vbTab
    ' keep the reference to this control and set text
    Set objShape = Selection.InlineShapes.AddOLEControl(ClassType:="Forms.OptionButton.1")
    With objShape.OLEFormat.Object
        .Caption = "My great option"
    End With
    Selection.MoveRight Unit:=wdCharacter, Count:=1

    ActiveDocument.Protect Type:=wdAllowOnlyFormFields, NoReset:=True

    ' we have to execute the creation of the event handlers with a delay
    ' to make it work (seems Word needs some time for object creation)
    Application.OnTime When:=Now + TimeValue("00:00:01"), Name:="prcCreateReference"

End Sub

Public Sub prcCreateReference()
    Dim objShape As InlineShape
    Dim intCount As Integer

    On Error Resume Next
    For Each objShape In ThisDocument.InlineShapes
        intCount = intCount + 1
        ReDim Preserve objControls(1 To intCount)
        If TypeOf objShape.OLEFormat.Object Is ComboBox Then
            Set objControls(intCount) = New clsComboBox
            Set objControls(intCount).ComboBox = objShape.OLEFormat.Object
        ElseIf TypeOf objShape.OLEFormat.Object Is OptionButton Then
            ' add event handlers for option buttons
        End If
    Next
End Sub

Этот код должен войти в модуль класса clsComboBox:

Option Explicit

Private WithEvents mobjComboBox As MSForms.ComboBox

Friend Property Set ComboBox(objComboBox As MSForms.ComboBox)
    Set mobjComboBox = objComboBox
End Property

Private Sub mobjComboBox_Change()
    MsgBox "Selection changed."
End Sub

Private Sub mobjComboBox_Click()
    MsgBox "Clicked."
End Sub

Обратите внимание, что переменная objControls должна иметь тип clsComboBox. Объявление этой переменной как объекта или варианта не сработало для меня (может ли кто-нибудь объяснить, почему ???).

person Dirk Vollmar    schedule 28.11.2008
comment
Хорошо сделано. Я обнаружил, что могу уйти с гораздо меньшей задержкой для звонка Application.OnTime. Я использовал: Application.OnTime VBA.Now + 0.000001, "prcCreateReference", что немного меньше 1/10 секунды. О, и я использую Word 2007. - person Hannah Vernon; 04.07.2014