Основы офисного программирования и язык VBA

         

Вопрос первый: "Как сохранить


Для выяснения сути проблемы обратимся к примеру, который я спроектировал специально для этой задачи.

Первым делом я спроектировал форму с двумя элементами управления, включив ее в состав тестового документа. На самом тестовом документе я разместил 4 кнопки, управляющие работой формы. Кнопки Show и Hide показывают и прячут форму. Кнопка "Add Controls to Form" программно добавляет элементы управления на период существования формы, то есть до тех пор, пока форма не будет закрыта. Наконец, кнопка "Add Design Controls" решает поставленную задачу, добавляя элементы управления, как теперь принято говорить, на постоянной основе. Вот как выглядит тестовый документ с командными кнопками:


увеличить изображение
Рис. П-1.  Тестовый документ с командными кнопками

А вот как выглядит сама форма при ее открытии в ответ на щелчок кнопки Show:


Рис. П-2.  Спроектированная форма при ее открытии


Главное, что для программиста это не требует никаких усилий, достаточно изменить значение одного свойства. Замечу, что в С++, по крайней мере, в версии 4 работа с немодальными окнами требовала профессиональных знаний, в частности, умения посылать сообщения операционной системе. Но вернемся к нашей задаче.
  • Элементы управления достаточно просто программным путем вставляются в форму в период выполнения программы, и я об этом рассказывал в главах, посвященных проектированию интерфейса. У объекта Form есть коллекция Controls, у которой есть метод Add, позволяющий добавить любой из элементов управления. В нашем примере мы уже спроектировали форму с двумя элементами управления - командной кнопкой и окном редактирования. В обработчиках события Click командной кнопки самой формы и командной кнопки "Add Controls to Form", встроенной в тестовый документ, вызывается процедура AddControls, которая добавляет в форму еще пару таких же элементов управления. Заметьте, поскольку наша форма не является модальной, то нажимать командные кнопки можно как в самой форме, так и вне формы. Вот текст процедуры, добавляющей в форму элементы управления:
    Public Sub AddControls() 'Эта процедура добавляет командную кнопку и окно редактирования в форму With UserForm1
    'Добавляем окно редактирования Set Mycmd = .Controls.Add("Forms.TextBox.1", "ProgramBox", True) Mycmd.Left = .TextBox1.Left Mycmd.Top = .TextBox1.Top + 100 Mycmd.Width = .TextBox1.Width Mycmd.Height = .TextBox1.Height Mycmd.Text = "New Control - " & Mycmd.Name
    'Добавляем командную кнопку Set Mycmd = .Controls.Add("Forms.CommandButton.1", "ProgramButton", True) Mycmd.Left = .CommandButton1.Left Mycmd.Top = .CommandButton1.Top + 100 Mycmd.Width = .CommandButton1.Width Mycmd.Height = .CommandButton1.Height Mycmd.Caption = "ProgramButton"
    End With
    End Sub
  • Вот как выглядит форма, после того как была нажата кнопка "Add Controls to Form" и ее обработчик вызвал процедуру AddControls:



    Рис. П-3.  Форма с программно добавленными элементами управления
  • Добавленные таким путем элементы управления живут в форме только до ее закрытия. Но, заметьте, если скрыть форму, вызвав метод Hide, то при повторном ее открытии элементы управления сохраняются.
  • Перейдем теперь непосредственно к ответу на первый поставленный вопрос. Для его решения потребуются средства, ранее не упоминавшиеся в книге. Нам понадобятся объекты класса VBComponent - компоненты VB-проекта (объекта класса VBProject). Чтобы можно было с ними работать, необходимо включить дополнительную ссылку на библиотеку VBIDE (Visual Basic Extensibility). Ну, а теперь отвечаю конкретно на первый поставленный вопрос. Можно программно добавить элементы управления так, чтобы они сохранялись в форме точно также как сохраняются элементы, созданные в период проектирования. Для этого нужно работать с объектом, представляющим форму в режиме проектирования, используя свойство Designer объекта VBComponent. Вот как это делается:

  • Public Sub AddDesignControls() 'Эта процедура добавляет командную кнопку и окно редактирования в форму Dim MyForm As UserForm 'Создаем форму этапа проектирования
    Set MyForm = ActiveDocument.VBProject.VBComponents("UserForm1").Designer With MyForm
    'Добавляем окно редактирования Set Mycmd = .Controls.Add("Forms.TextBox.1", "ProgramBox", True) Mycmd.Left = .TextBox1.Left Mycmd.Top = .TextBox1.Top + 100 Mycmd.Width = .TextBox1.Width Mycmd.Height = .TextBox1.Height Mycmd.Text = "New Control - " & Mycmd.Name
    'Добавляем командную кнопку Set Mycmd = .Controls.Add("Forms.CommandButton.1", "ProgramButton", True) Mycmd.Left = .CommandButton1.Left Mycmd.Top = .CommandButton1.Top + 100 Mycmd.Width = .CommandButton1.Width Mycmd.Height = .CommandButton1.Height Mycmd.Caption = "DesignButton"
    End With
    'Удаляем командную кнопку, вызывающую эту процедуру. 'Эта кнопка может работать лишь раз, по крайней мере, 'пока в режиме проектирования не будут удалены добавленные элементы. 'Заметьте, кнопку можно только удалить, но нельзя сделать ее невидимой.


    ActiveDocument.InlineShapes(4).Delete End Sub
    Обратите внимание, к нашей форме, рассматриваемой как объект класса VBComponent, мы добираемся через свойство VBProject нашего документа. Имея форму, в последний момент вызываем Designer, который и возвращает форму периода проектирования. Теперь добавление элементов управления будет постоянным. Само добавление делается, как и ранее, никаких изменений в этом процессе здесь нет.
    Однако есть некоторые естественные ограничения, на которые следует обратить внимание. Процедура AddDesignControls, добавляющая элементы периода проектирования, должна вызываться при закрытой форме и только один раз. Поэтому в конце этой процедуры добавлен текст, удаляющий из тестового документа командную кнопку (объект класса InlineShape), обработчик которой вызывал процедуру AddDesignControls.
    Вот как выглядит форма, открытая после окончания работы этой процедуры:

    Рис. П-4.  Форма с постоянно добавленными элементами

    Содержание раздела