InfoCity
InfoCity - виртуальный город компьютерной документации
Реклама на сайте







Размещение сквозной ссылки

 

Парадная форма для Word


Антон Орлов, www.submarine.ru


В предыдущих номерах журнала мы уже познакомили вас в общих чертах с Visual Basic for Applications - прекрасным средством программирования, предназначенным для пакета Microsoft Office. Теперь же пришло время остановиться на более конкретных возможностях, изучив которые, вы увидите, какое практически безграничное поле деятельности откроется по созданию всяческих полезных программок.


Для создания формы необходимо из контекстного меню правой кнопки мыши в "Менеджере проектов" выбрать "Вставить"-"UserForm" (рис. 1).


 Рис. 1. Окно дизайна форм.

Форма состоит из элементов - различных средств ввода и отображения информации (командных кнопок, мест для ввода/вывода текста, переключателей, флажков и др.), которые могут на ней располагаться. У каждого элемента есть свойства (ширина, высота, цвет), особенности внешнего вида и поведения (более подробно об элементах форм рассказывалось в статье "Введение в программирование для Word" (ПЛ № 7, 2000).

Основное отличие программного кода, обслуживающего формы, от кода в обычных модулях заключается в принципе программирования. Программа на VBA работает последовательно, т. е. все ее команды выполняются одна за другой, и их порядок изменяется только в зависимости от операторов условного и безусловного перехода If и Goto, а форма "реагирует на события" - каждому ее элементу ставится в соответствие определенная программа, выполняющая требуемые действия. Большинство программ для Windows, да и сам текстовый редактор Microsoft Word, построены именно по такому принципу - они не работают сами по себе, а ждут от пользователя команд и "реагируют" на них: выполняют те или иные действия. Так и форма: программист должен разработать ее интерфейс - создать окно программы, расположить в нем элементы, определить их свойства. Затем написать программы обработки событий, поместив в каждой из них код, который должен быть выполнен, когда то или иное событие произойдет, т. е. будет нажата какая-нибудь кнопка на форме или клавиатуре, введен текст в соответствующее поле, выбран тот или иной флажок на форме и др.


 Рис. 2. Закон Джоуля-Ленца.

Для примера создадим форму, в которой будет производиться подсчет количества теплоты, выделяемой в проводнике при протекании через него тока. Согласно закону Джоуля-Ленца

Q = U2 * t * s/lop, где

Q - количество теплоты в джоулях;

U2 - напряжение в вольтах;

t - время в секундах;

p - удельное сопротивление материала проводника в омах на метр;

l - длина проводника в метрах;s - площадь поперечного сечения проводника в квадратных сантиметрах.

Его-то мы и запрограммируем в форме.

Сначала создадим саму форму и разработаем ее дизайн. В ней должно быть пять полей для ввода значений, одно поле для вывода значения и кнопка выхода. Но мы добавим еще кнопку - "Вставить значение в документ" (пусть при ее нажатии подсчитанные данные будут вставлены в текст активного документа). Не мешало бы еще поместить на форме текст о назначении данной программы и краткую инструкцию по ее использованию, а также сделать для формы приличный заголовок (свойство Caption элемента UserForm).

Для помещения на форму элемента управления достаточно перетащить его с "Панели элементов" на форму.

Получиться у вас должно примерно следующее (рис. 3).


 Рис. 3. Форма нашей программы.

Поля ввода параметров имеют имена TextBox1... TextBox5. Поле отображения результата получит имя TextBox6, кнопки - имена CommandButton1 и CommandButton2 соответственно сверху вниз. В элементы TextBox1, ... TextBox5 пользователь будет вводить текст. Желательно установить свойство Locked элемента TextBox6 как True (рис. 4), чтобы не допустить случайного ввода в него текста, хотя к сбою это и не приведет.


 Рис. 4. Установка свойства Locked элемента TextBox6 как True.

Разработка дизайна программы - ответственный момент, но не менее важным является формирование принципов ее работы. Можно сделать, например, так: пользователь вводит все значения, нажимает кнопку "Подсчитать" (надо будет добавить на форму...) и получает результат в соответствующем окне. Но в этом случае, во-первых, необходимо выполнять лишнюю операцию - нажатие на кнопку, а во-вторых, надо будет продумать систему защиты от неправильных действий пользователя: нельзя вводить нулевые и нечисловые значения в поля TextBox4 и TextBox5. Для этого придется либо выдавать сообщение о неправильном вводе, либо (это представляется более корректным) ставить в эти поля значения по умолчанию, как только пользователь сделает неправильный ввод и уберет курсор с поля ввода. Но... все же, как неудобно нажимать лишний раз кнопку, постоянно следить за тем, стоят ли в полях ввода нужные значения, а не значения по умолчанию (можно при вводе и случайно задеть соседнюю клавишу). Да и при программировании возни будет предостаточно: изволь предусмотреть все случаи и на каждый написать программу обработки... Не слишком ли много проблем? Так, может быть, надо сразу получше продумать проектирование программы?


Рис. 5. Так можно открыть окно программного кода формы.

Основной принцип здесь - сделай проще, но без ущерба функциям. Что нам надо? Чтобы был результат. Когда он возможен? Когда определены все значения в полях ввода и при этом два нижних - TextBox4 и TextBox5 - ненулевые. Желательно, чтобы результат в своем окне появлялся тогда (и только тогда), когда все эти условия выполнены; программа постоянно отслеживала ввод значений в поля ввода; как только будут введены все пять значений, из которых последние два ненулевые, а остальные числовые, - отобразился результат. Но есть ли такая возможность у языка VBA? Давайте проверим. Откроем окно программного кода формы: из контекстного меню правой кнопки мыши формы в "Менеджере проектов" выберем "Программа" (рис. 5) и из выпадающего списка в левом верхнем углу (рис. 6) выберем, например, TextBox1.


 Рис. 6. Выпадающий список в левом верхнем углу — навигатор по программам элементов формы.

Так... появился фрагмент кода:

Private Sub TextBox1_Change()
End Sub

Change - с английского "изменение". Код, написанный в этой части программы (она называется "обработчик события Change"), должен выполняться всякий раз, когда происходит это событие. Можно предположить, что оно происходит тогда, когда в поле ввода записывается какой-либо символ или удаляется оттуда. В таком случае это именно то событие, которое нам необходимо. Но то ли? Проверим. Напишем строчку:

Private Sub TextBox1_Change()
TextBox6.Text=TextBox1.Text
End Sub

Проведем эксперимент. Пусть при изменении текста в первом поле ввода произойдет изменение текста в поле отображения результата. Проверим, будет ли это работать, - нажмем F5 (запуск программы на выполнение) и введем текст в первое поле ввода. Прекрасно, в поле отображения результата появляется тот же текст! Значит, событие Change именно то, которое нам надо использовать в программе, чтобы после каждого нового ввода данных проверять условия возможности отображения результата и показывать его в случае их выполнения. Ну, а если бы оно не подошло, то пришлось бы перебирать все остальные события из выпадающего списка (вверху справа в окне программного кода формы) и для каждого проводить такое же исследование: помещать в обработчик этого события команду, выполняющую какое-либо действие, и наблюдать, будет ли она выполнена при вводе текста в первое поле ввода.

Проверка возможности подсчета результата и вывод его в случае соблюдения описанных выше условий должны происходить после каждого ввода какого-либо символа в любое из окон ввода, а также при удалении символа из любого такого окна. Писать пять одинаковых программ для каждого из окон ввода представляется нецелесообразным, поэтому лучше проверку возможности отображения результата и его подсчет вынести в отдельную подпрограмму-процедуру, и вызывать ее из каждого обработчика события Change полей ввода.

Переведем на язык VBA условие возможности отображения результата. Во-первых, все значения полей ввода должны быть числовыми. В VBA есть специальная функция для проверки того, является ли та или иная строка записью числа, - IsNumeric; например, легко найти ее описание в разделе "Поиск" справки по словам "строковое выражение числовое значение" (рис. 7).


 Рис. 7. Справка по функции IsNumeric.

Ее и используем. Ну, а для проверки отличия от нуля значений в последних двух полях ввода используем функцию Val. Итак, результат существует, если

IsNumeric(TextBox1.Text) =

True And IsNumeric(TextBox2.Text) = True And IsNumeric(TextBox3.Text) = True And IsNumeric(TextBox4.Text) = True And IsNumeric(TextBox5.Text) = True And Not Val(TextBox4.Text) = 0 And Not Val(TextBox5.Text) = 0.

В этом случае можно осуществить подсчет по формуле

rez = ((Val(TextBox1.Text)2)o Val(TextBox2.Text)oVal(TextBox3.Text))/(Val(TextBox4.Text)o Val(TextBox5.Text))

и отобразить его в поле вывода результата:

TextBox6.Text = Str$(rez).

Теперь можно написать процедуру вычисления результата и вызовы ее из всех обработчиков событий Change:

Private Sub TextBox1_Change()
Scet
End Sub
Private Sub TextBox2_Change()
Scet
End Sub
Private Sub TextBox3_Change()
Scet
End Sub
Private Sub TextBox4_Change()
Scet
End Sub
Private Sub TextBox5_Change()
Scet
End Sub
Private Sub Scet()
If IsNumeric(TextBox1.Text) = True And IsNumeric(TextBox2.Text) = True And IsNumeric(TextBox3.Text) = True And IsNumeric(TextBox4.Text) = True And IsNumeric(TextBox5.Text) = True And Not Val(TextBox4.Text) = 0 And Not Val(TextBox5.Text) = 0 Then
rez = ((Val(TextBox1.Text)2)o Val(TextBox2.Text)oVal(TextBox3.Text))/(Val(TextBox4.Text)o Val(TextBox5.Text))
TextBox6.Text = Str$(rez)
Else
TextBox6.Text = ""
End If
End Sub

В принципе программа уже почти закончена, но стоит еще разобраться с командными кнопками. Для кнопки "Отмена" обработчик события Click (нажатие на кнопку) прост - выход из программы:

Private Sub CommandButton2_Click()
Unload Me
End Sub

Но у нас есть еще вторая кнопка - "Вставить результат в документ". Пусть она вставит в документ не просто значение результата, а фразу, содержащую как результат, так и введенные параметры. Это можно сделать командой

Selection.Text = "При прохождении тока напряжением в " + TextBox1.Text + " вольт по проводнику длиной " + TextBox4.Text + " метров, сечением " + TextBox3.Text + " кв. мм и удельным сопротивлением " + TextBox5.Text + " ом на метр за " + TextBox2.Text + " секунд выделится" + TextBox6.Text + " джоулей теплоты."

Она сформирует фразу из значений полей ввода и вставит ее в активный документ. Проверим... так, действительно вставляет, но фраза остается выделенной. А значит, следующая фраза, выведенная с помощью нашей программы, сотрет предыдущую. Надо убедиться, нет ли в VBA функции снятия выделения. Посмотрим по выпадающему меню после точки Selection. Есть команда Collapse (Свернуть) (рис. 8).


 Рис. 8. Список методов объекта Selection.

Из справки по ней узнаем ее синтаксис:

Selection.Collapse Direction:=wdCollapseEnd.

Эта команда убирает выделение и помещает курсор в конец выделенного фрагмента.

Можно также вставить текст в активный документ "Selection.TypeText Text:="Мой текст" (двоеточие после слова Text обязательно). Тогда в специальном снятии выделения со вставленного текста не будет необходимости: оно делается автоматически.

А если вдруг пользователь вызовет программу, когда открытых документов в Word нет? Тогда возникнет ошибка программы. Но этого легко избежать, если проверить перед вставкой наличие открытых документов; при отсутствии таковых создать новый:

If Documents.Count =
0 Then Documents.Add

Осталась еще одна маленькая деталь. Кнопка "Вставить результат в документ" не должна работать, если результат вычислить нельзя (поле TextBox6 пусто). Как это сделать? Среди всего набора возможных свойств элемента CommandButton есть свойство Enabled (рис. 10); если его установить как False (ложно), то кнопка отобразится серым цветом и не будет реагировать на события (станет неактивной).


 Рис. 10. Свойство Enabled элемента CommandButton.

Это свойство можно задать и программно командой CommandButton1.Enabled = False. Поставим в процедуру вычисления результата пару команд, активизирующих кнопку, когда результат вычисляется и вставка его в текст возможна, и деактивирующих ее в противном случае. Зададим также в форме свойство Enabled этой кнопки как False, чтобы она была неактивной с самого начала, до того как в какое-либо окно ввода будут записываться символы и начнет срабатывать процедура вычисления результата с командами задания состояния кнопки.

Вот готовый код нашей программы:

Private Sub CommandButton1_Click()
If Documents.Count =
0 Then Documents.Add
Selection.Text = "При прохождении тока напряжением в " + TextBox1.Text + " вольт по проводнику длиной " + TextBox4.Text + " метров, сечением " + TextBox3.Text + " кв. мм и удельным сопротивлением " + TextBox5.Text + " ом на метр за " + TextBox2.Text + " секунд выделится" + TextBox6.Text + " джоулей теплоты."
Selection.Collapse Direction:=wdCollapseEnd
End Sub
Private Sub CommandButton2_Click()
Unload Me
End Sub
Private Sub TextBox1_Change()
Scet
End Sub
Private Sub TextBox2_Change()
Scet
End Sub
Private Sub TextBox3_Change()
Scet
End Sub
Private Sub TextBox4_Change()
Scet
End Sub
Private Sub TextBox5_Change()
Scet
End Sub
Private Sub Scet()
If IsNumeric(TextBox1.Text) =
True And IsNumeric(TextBox2.Text) = True And IsNumeric(TextBox3.Text) = True And IsNumeric(TextBox4.Text) = True And IsNumeric(TextBox5.Text) = True And Not Val(TextBox4.Text) = 0 And Not Val(TextBox5.Text) = 0 Then
rez = ((Val(TextBox1.Text)2)o Val(TextBox2.Text)oVal(TextBox3.Text))/(Val(TextBox4.Text)o
Val(TextBox5.Text))
TextBox6.Text = Str$(rez)
CommandButton1.Enabled = True
Else
TextBox6.Text = ""
CommandButton1.Enabled = False
End If
End Sub

Назначить форме кнопку или пункт меню для вызова из Word нельзя: это возможно только для модулей. Поэтому переименуем для облегчения восприятия (и для благозвучия) форму, например, в Teplotok (свойство Name объекта UserForm можно задать в окне свойств, выделив форму), и напишем модуль, в котором будет всего одна команда - вызов созданной нами формы:

Sub TeploCount()
Teplotok.Show
End Sub


 Рис. 11. Задание модулю нужного имени.

Зададим модулю подходящее имя, например Teplo, через свойство Name объекта "Модуль1" (рис. 11), если модуль для программы вызова формы был вставлен с помощью пункта "Вставить"-"Модуль" контекстного меню правой кнопки мыши в "Менеджере проектов", и назначим в Word кнопку для вызова макроса Normal.Teplo.TeploCount. Вот и все: наша программа готова! (рис. 12).


 Рис. 12. Окно готовой программы.

Теперь она вызывается на выполнение соответствующей кнопкой. При желании можно скопировать форму и модуль в отдельный шаблон и создать в нем панель инструментов с кнопкой вызова макроса. Тогда программа будет устанавливаться и на другие компьютеры путем переписывания шаблона с макросом в папку автозагружаемых файлов Word.

В заключение хочется сказать, что, составляя программы для Microsoft Word, вы сможете на опыте получить представление практически обо всех современных принципах программирования - как структурных, основанных на последовательном выполнении всех команд программы, так и событийных, согласно которым программа должна реагировать соответствующим образом на различные действия пользователя.

VBA может служить не только полноценной средой разработки приложений, функционирующих в Microsoft Office, но и как бы "учебным центром" по освоению принципов и различных приемов современного программирования. Если научитесь программировать на VBA, поймете принципы разработки алгоритмов и основные приемы программирования, освоите среду написания программ - редактор VBA, то для вас практически не составит труда начать создавать программы на Visual Basic for Windows.

Впрочем, мы не прощаемся с вами: в следующей статье порадуем полезными советами по программированию на VBA.


Реклама на InfoCity

Яндекс цитирования



Финансы: форекс для тебя








1999-2009 © InfoCity.kiev.ua