(Окончание, начало см. МК № 1—2, 5, 8 (172—173, 176, 179))

Так как второй раскрывающийся список (MyControl_Cop) является копией первого раскрывающегося списка (MyControl), то он будет иметь те же свойства, в том числе свойство OnAction (вызова процедуры), — за исключением свойства Caption, которое было изменено на этапе создания объекта. При желании можно создавать новые копии объектов, но так как заполнение текстовой базы данных осуществлялось из рабочей книги Excel, то ограничение листа Excel в 65536 строк уже само по себе является ограничением размерности текстовой базы данных.

Следующая и самая сложная задача заключается в выделении из строки (элемента) раскрывающегося списка каждой порции данных для заполнения полей ввода-вывода. В данном случае в цикле обработки строки не обойтись без использования VB/VBA-функции InStr, которая возвращает значение, указывающее позицию первого вхождения одной строки внутри другой строки, и функции Mid, возвращающей строку, содержащую указанное число символов.

Синтаксис функции InStr в данной ситуации может быть такой:

InStr(start, MyString, vbTab)

где start — числовое выражение, задающее позицию, с которой начинается каждый поиск; MyString — строковое выражение, в котором выполняется поиск, а vbTab — искомое строковое выражение.

Синтаксис функции Mid

Mid(MyString, start, length)

содержит следующие именованные аргументы: MyString — строковое выражение, из которого извлекаются символы; start — позиция символа в строке MyString, с которого начинается нужная Рис. 1подстрока; length — количество возвращаемых символов.

В связи с ограничением размера статьи, приведу только пример практического использования функций Mid и InStr, без пояснений. В предлагаемой процедуре заполнения полей ввода-вывода третий аргумент функции представлен в виде выражения вычитания, что не меняет его назначения. Результат выполнения процедуры показан на Рис 1.

Dim MyString As String, Text_Pos As String Dim start As Integer, Pos As Integer, Pos_1 As Integer, n As Integer 'Передаем строковой переменной значение выбранного элемента раскрывающегося списка MyString = Application.CommandBars("Organizations").Controls(14).Text start = 1 n = 0 'Цикл Do Pos = InStr(start, MyString, vbTab) start = Pos + 1 Text_Pos = Mid(MyString, Pos) Pos_1 = InStr(start, MyString, vbTab) If Pos_1 = 0 Then Exit Do Text_Pos = Mid(MyString, start, Pos_1 — start) n = n + 1 If n = 1 Then Application.CommandBars("Organizations").Controls(8).Text = Text_Pos ElseIf n = 2 Then Application.CommandBars("Organizations").Controls(9).Text = Text_Pos ElseIf n = 3 Then Application.CommandBars("Organizations").Controls(10).Text = Text_Pos ElseIf n = 4 Then Application.CommandBars("Organizations").Controls(11).Text = Text_Pos ElseIf n = 5 Then Application.CommandBars("Organizations").Controls(12).Text = Text_Pos ElseIf n = 6 Then Application.CommandBars("Organizations").Controls(13).Text = Text_Pos End If Loop While Pos <> 0

Характеризуя контролы с индексами с 8 по 13 создаваемой панели инструментов, я их называл полями ввода-вывода. Помимо получения данных контрагентов, эти же поля можно использовать как поля для ввода данных в текстовую базу данных. В данном случае необходимо запрограммировать третью кнопку панели на добавление записи в текстовый файл в режиме Append, отличие которого от режима Output в том, что файл не переписывается заново, а в конец файла добавляется новая порция данных. Фрагмент кода представлен ниже:

FileNo = FreeFile Open "C:\Мои документы\Const.txt" For Append As #FileNo Print #FileNo, "********"; Now; "***********************" Print #FileNo, MyControl_Org.Text Print #FileNo, MyControl_Cod.Text Print #FileNo, MyControl_Bank.Text Print #FileNo, MyControl_MFO.Text Print #FileNo, MyControl_Account.Text Print #FileNo, MyControl_ForWhat.Text Close #FileNo MsgBox "Не забудьте обновить данные в панеле", vbInformation, "Записано..."

Управление открытием текстового редактора «Блокнот» из программного кода Шаблона не представляет особых трудностей:

Dim x As Double x = Shell("NotePad C:\Мои документы\Const.txt", vbNormalFocus)

В случае, если разработчиком будет поставлена задача открытия только одного экземпляра приложения, то без обращения к API-вызовам уже никак нельзя будет обойтись. Поэтому рекомендую поискать в цикле статей «Мышление в стиле VB …» информацию об использовании API.

Для данных, помещенных в объекты панели управления, можно написать код передачи строк в определенные части документа, но больший интерес представляет избирательная передача в буфер обмена, с дальнейшей возможностью вставки «скопированных» данных в любое место документа, а также других программ, поддерживающих обмен данными через буфер обмена.

Код вставки из буфера довольно прост:

Sub Past_Buf() Selection.Paste End Sub

Для запуска программы «Буфер обмена» с целью просмотра содержимого клипборда можно не использовать функцию Shell (синтаксис: y = Shell("CLIPBRD", vbNormalFocus)), а воспользоваться выражением VBA Application.Dialogs(wdDialogControlRun).Show или (.Display), не беспокоясь о названии запускаемой программы. В результате выполнения будет выдано диалоговое окно «Запуск» (рис. 2), позволяющее также осуществить запуск панели управления. Вещь весьма удобная — правда, до сих пор непонятно, почему Microsoft не повесил кнопку на какую-нибудь панель для вызова формы «Запуск». Кстати, свойство Dialogs имеет большое количество констант, значительно облегчающих Рис. 2работу в Word’е; проверить их назначение Вы можете из среды разработки (рис. 2).

Так как имеет смысл прописать всего одну процедуру для любого окна ввода-вывода панели, то в данном случае обращение к объекту будем осуществлять не по имени, индексу или свойству Caption, а используя свойство панели ActionControl (активный контрол). Естественно, нажимая ENTER при находящемся в объекте курсоре, мы будем делать данный объект активным и запускать процедуру, текст которой приведен ниже.

Sub Copy_Text() Dim MyData As DataObject, MyText As String Set MyData = New DataObject 'Передача текстового содержания активного ЭУ строковой переменной MyText = CommandBars.ActionControl.Text 'Отсечение всех пробелов в начале и в конце текста MyText = Trim(MyText) 'Копирование текста в DataObject MyData.SetText MyText 'Метод PutInClipboard заменяет содержимое Буфера обмена содержимым DataObject, который находится в формате Text. MyData.PutInClipboard End Sub

В случае, если Вам захочется «подвязать» предложенную процедуру для помещения буфер данных из раскрывающегося списка, придется подключить еще процедуру удаления символов табуляции, пример которой приводился ранее. Хотя, если подумать, символы табуляции могут пригодиться при трансформировании текста в таблицу. Все будет зависеть от потребностей разработчика. А можно написать процедуру, записывающую данные из каждого окна ввода-вывода в некую строковую переменную (речь касается операторов конкатенации &, используемых для слияния строковых выражений):

MyString = CommandBars("Organizations").Controls(8).Text & " " & CommandBars("Organizations").Controls(9).Text и т.д.

При рассмотрении процедур, вызываемых посредством кнопок созданной панели инструментов, были опущены процедуры очистки полей ввода-вывода и вызова справки.

В первом случае простейшим способом очистки поля будет задать свойству Text объект пустой строки "":

Application.CommandBars("Organizations").Controls(8).Text = "" ,

но в некоторых случаях окажется возможным и использование метода Clear:

Application.CommandBars("Organizations").Controls(8).Clear

Что касается вызова справки по использованию Ваших приложений, то он может иметь различные вариации:

• если вся Ваша справка вмещается в 255 символов, то вызов подсказки через MsgBox или через «Помощника» будет оправданно кратким.

Например:

Sub MyHelp( ) With Assistant.NewBalloon .Mode = msoModeModeless .Button = msoButtonSetNone .Heading = "Ваш заголовок" .Animation = msoAnimationWorkingAtSomething .Text = "Ваш текст" .Show End With End Sub

В противном случае придется на этапе разработки проекта указать путь к файлу справочной информации, причем если файл справки хранится в формате *.hlp или *.txt, то достаточно будет прописать путь к нему и открывать посредством функции Shell; но если справка является, допустим, документом MS Office, тогда придется использовать функцию VB GetObject, и это уже отдельная тема для разговора.

И последнее: для активизации созданной панели инструментов при создании нового документа на основе разработанного Шаблона используем зарезервированное имя Word:

Sub AutoNew — ) Call ActivPanel End Sub

Вместо послесловия

Безусловно, проблемы, затрагиваемые в статье, решались и в VB/VBA, и в других языках программирования, поэтому буду рад на email-диалог с читателями и рассчитываю на продолжение другими авторами темы VBA на страницах МК.