Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 Курс Информатика VBA(ЗО) / Книги / В.Д.Хорев - Самоучитель программирования на VBA в Microsoft Office

.pdf
Скачиваний:
2701
Добавлен:
31.05.2015
Размер:
21.66 Mб
Скачать

Из документа Word в таблицу Excel 91

End If

If .Words(N).Characters(1) >= "0" _ And _

.Words(N).Characters(1) <= "9" _

Then

S = S + .Words(N)

End If

If .Words(N).Characters(1).Bold _ Or _

.Words(N).Characters(1).Italic _

Then

S = S + .Words(N)

End If

Next N

End With

Count = 1

While EX.ActiveSheet.Cells(Count, 1).Value <> ""

Count = Count + 1

Wend

If ActiveDocument.Characters.Count < 300 Then

MaxChars = ActiveDocument.Characters.Count

Else

MaxChars = 300

End If

With EX.ActiveSheet

.Cells(Count, 3).Value = _

ActiveDocument.Range(0, MaxChars).Text

.Cells(Count, 2).Value = S

.Hyperlinks.Add .Cells(Count, 1), ActiveDocument.FullName

End With

EX.NewWindow

EX.Save

Set EX = Nothing

End Sub

ПРИМЕЧАНИЕ

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

92 Глава 3. Поверка гармонии Word алгеброй Excel

Усовершенствования анализатора содержимого Word-документа

Строка

ActiveDocument.SaveAs “C:\ARCHIVE\” + Str(Count)

сохранит текущий документ в каталоге C:\ARCHIVE под именем, представляющем собой номер строки в таблице документов. Чтобы добавить гиперссылку на архивную копию документа в текущую строку таблицы (например, в четвертый столбец), потребуется оператор вида:

EX.ActiveSheet.Hyperlinks.Add .Cells(Count, 4), _

ActiveDocument.FullName

Можно в значительной мере варьировать глубиной анализа, просматривая большее или меньшее число слов документа, подвергая просматриваемые слова большему или меньшему числу проверок. Опять же, многое здесь зависит от системных ресурсов. Для системы класса Pentium 3 даже просмотр нескольких сотен слов с выполнением десятков проверок не создаст скольконибудь значительной задержки при выполнении макроса, в то время как на компьютере класса 486 даже скромный по своим масштабам анализ “выльется” в продолжительную паузу.

Оптимизация кода анализатора Word-документа

Впрочем, скорость выполнения макроса можно значительно (во много раз) увеличить, если несколько оптимизировать его код. Дело в том, что ради хотя бы относительной простоты кода, в данном случае, в жертву была принесена его эффективность. В качестве примера рассмотрим одно из возможных направлений оптимизации.

Обращения к свойствам объектов (например, выражения типа

.Words(N).Characters(1)…) — это самая медленная операция в макросах VBA, в то время как в созданном коде выполняется многократное обращение к словам и символам документа при каждом проходе цикла For. Чтобы существенно ускорить работу макроса необходимо использовать объектные переменные, обращение к которым занимает гораздо меньше времени. Например, можно было бы объявить переменную-объект MyWord:

Dim MyWord as Object

см. также в приложении раздел “Объектные переменные”.

Затем, присвоив ей один раз значение в самом начале цикла For, можно получить объект MyWord, хранящий в себе анализируемое слово документа. Многократные обращения к этому объекту затем заняли бы гораздо меньше времени. Значения объектной переменной присваиваются при помощи оператора Set:

Set MyWord = .Words(N)

И тогда далее вместо ActiveDocument.Words(N) везде можно использовать MyWord. Точно таким же образом можно ускорить обращение к первому символу N-го слова, создав для

этого объектную переменную MyCharacter. Существуют и другие возможности для оптимизации кода макроса, которые сознательно не рассматриваются на этом этапе ради того, чтобы не усложнять и без того непростой исходный текст.

Обратно из таблицы Excel в документ Word

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

Обратно из таблицы Excel в документ Word 93

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

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

см. также в гл. 2 раздел “Второй способ формирования счета (макрос листа Excel работает с документом

Word)”.

Предположим, нам надо учитывать все выписанные таким способом счета. Нет смысла сохранять все сформированные документы, поскольку любой счет можно восстановить по его реквизитам. Значит, необходимо сохранять и учитывать только реквизиты, с чем прекрасно справится лист рабочей книги Excel. Любой документ при этом можно будет восстановить при помощи стандартной для данного вида документов заготовки и конкретного набора реквизитов. Как это можно сделать? Какие инструментальные средства Office помогут в решении этой задачи? Конечно, можно использовать VBA. Как уже отмечалось, макросы VBA в рабочей среде Office могут решить абсолютно любую задачу. Но могут не значит должны. Если существуют инструментальные средства, специально предназначенные для решения подобных задач, то зачем их игнорировать? Кроме того, совсем уж без макросов нам все равно не обойтись, но об этом позднее, сейчас самое время вспомнить о еще одном популярном словечке из лексикона пользователей MS

Office….

Еще одно “страшное” слово — OLE

Технология OLE (OLE Automation) — автоматизация при помощи связывания и внедрения объектов. Технология, которую теперь называют просто Automation, далеко не нова. В старых версиях MS Office также существовала возможность связывания объектов. В данном случае нас интересует именно связывание, поскольку требуется связать таблицу Excel с документом Word. Впрочем, почему именно Word? Технология OLE Automation не делает различий, — все объекты рабочей среды MS Office равны перед ней. Точно таким же образом можно связать между собой рабочие книги Excel, или, например, презентацию PowerPoint с базой данных Access — просто в этом примере речь идет о рабочей книге Excel, связанной с документом Word.

Постановка задачи

Предположим, что в офисе ООО “Универсал” имеют дело с несколькими видами документов, которые обладают точно определенной формой и отличаются от себе подобных лишь значениями реквизитов. Допустим, наряду с другими типами документов, к ним у нас относится банковское платежное поручение — платежка. Этот документ полностью определяется своими реквизитами и по своему содержанию отлично укладывается в строку таблицы. С другой стороны, фактуру платежки для вывода на печать нередко создают в форме документа Word.

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

Подготовка таблицы

Разумеется, это всего лишь пример для демонстрации принципа. Точно таким же образом можно работать с любыми другими документами, обладающими определенной формой. И вовсе не обязательно эти документы должны существовать в форме документа Word , как показано на рис. 3.10. С таким же успехом это могут быть, например, те же рабочие листы Excel.

94 Глава 3. Поверка гармонии Word алгеброй Excel

Рис. 3.10. Платежное поручение создано в форме документа Word

Рис. 3.11. Лист документной рабочей книги, предназначенный для хранения платежных поручений

Такой заготовки вполне достаточно для демонстрации рассматриваемого примера. Она будет играть роль универсальной формы для отображения платежных поручений. Сами же платежные поручения будут храниться на листе рабочей книги Excel. Назовем этот лист “Платежка” (рис.

3.11).

Нет необходимости хранить все реквизиты, поскольку, например, банковские реквизиты плательщика не меняются от платежки к платежке. Сведем в таблицу все меняющиеся реквизиты: номер, дата, сумма и так далее. Строка 1 будет играть роль заголовка, при этом каждый столбец необходимо отформатировать соответствующим образом. Столбец “Дата”, конечно, необходимо подготовить для ввода значений даты в одном из форматов даты, а “Сумма” — для ввода денежных значений. Для всех остальных столбцов, как минимум, для тех из них, где будут содержаться номера счетов, БИК, ИНН, необходимо задать формат “текстовый”. В противном случае Excel будет пытаться отобразить большое число в экспоненциальном формате и вид многоразрядного числа нарушится.

Строку 2 предполагается использовать в качестве “связующего звена” между таблицей и документом — ее ячейки будут связаны с документом Word при помощи технологии Automation, и в то же самое время они будут связаны с остальной таблицей посредством программного кода VBA. Как вскоре можно будет убедиться, комбинация VBA + OLE представляет собой весьма сильное

Обратно из таблицы Excel в документ Word 95

оружие. Без больших усилий она позволяет решать достаточно сложные задачи. Задачи, которые только силами OLE решить бы не удалось вообще, в то время как решение только силами VBA потребовало бы создания довольно больших и сложных макросов.

Вот, собственно, и вся подготовка. Никаких особенных требований к таблице не предъявляется. В конце концов, это может быть любая таблица Excel.

Связывание таблицы с документом

На экране должно быть открыто два окна: окно MS Word с платежкой (предположим, документ содержится в файле C:\Plategka.doc) и окно MS Excel с подготовленной таблицей. Необходимо связать ячейки строки 2 с соответствующим позициями в платежном поручении, которое отображается в окне Word. В этом примере слово “соответствующими” означает, что ячейка строки 2, которая находится, например, под заголовком, “Дата”, должна быть связана с той позицией в документе, где отображается дата документа. Если говорить о платежном поручении, изображенном на рис. 3.10, то позиция даты находится в начале группы символов “21.12.2000”, над надписью “Дата” в верхней части платежного поручения.

Задача состоит в том, чтобы последовательно, одну за другой, связать ячейки строки 2 с необходимыми позициями в документе. Продемонстрируем технику такого связывания на примере одной из ячеек. Пусть это будет первая ячейка строки, находящаяся под заголовком “Номер”. Аналогичные операции затем необходимо будет выполнить по отношению ко всем остальным ячейкам.

Как связать ячейку рабочего листа Excel с текстовой позицией в документе Word

1.Сделайте текущей ячейку, которую необходимо связать с документом (в нашем случае это ячейка A2).

2.Выберите в строке главного меню Excel команду Правка | Копировать.

3.Перейдите в окно MS Word с документом, подлежащим связыванию.

4.Поместите (щелчком мыши или при помощи клавиатуры) курсор ввода в необходимую пози-

цию: в данном случае это позиция перед символом “1” в начале номера “123” (после символа

“№”).

5.Удалите символы “123” при помощи клавиши [Del] — документ находится теперь в таком состоянии, что с клавиатуры можно было бы ввести номер документа, и при этом он оказался бы на своем месте.

6.Выберите в строке меню Word команду Правка | Специальная вставка. В результате откроется диалоговое окно Специальная вставка (рис. 3.12), где в области Источник (область в

левом верхнем углу) указаны координаты выделенной ячейки. Как видно из рисунка, речь идет о ячейке первого столбца (C1) второй строки (R2) рабочего листа “Платежка”.

Рис. 3.12. Диалоговое окно Специальная вставка

7.Установите переключатель в положение Связать (по умолчанию он находится в положении

Вставить).

8.Выделите в списке Как пункт Неформатированный текст.

96 Глава 3. Поверка гармонии Word алгеброй Excel

9.Закройте диалоговое окно щелчком мыши на кнопке OK.

Дело сделано, — установлена связь между текстовой позицией в документе Word и ячейкой рабочего листа Excel. Если ввести в ячейку A2 какое-нибудь число, оно немедленно отобразится в документе Word в позиции номера платежного поручения (на рис. 3.10 — позиция после символа

“№”).

Когда все запланированные ячейки строки 2 будут связаны с позициями соответствующих реквизитов документа, можно считать задачу наполовину решенной. Теперь, по крайней мере, одна строка таблицы стала фактически эквивалентна документу, — второе однозначным образом восстанавливается из первого. Остается сохранить документ и таблицу, чтобы закрепить установленные связи навсегда.

Конечно, сделано не более чем полдела — одна строка-документ, сама по себе, ничем нам не поможет. Чтобы распространить действие этого механизма на всю таблицу, нам потребуется помощь VBA.

И снова VBA...

Благодаря тому, что часть задачи уже решена средствами технологии Automation (OLE Automation), на долю макросов VBA остается немногое.

Постановка задачи

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

Вначале необходимо что-то сделать со строкой 2. Лучше всего ее было бы как-то скрыть — это чисто косметическая мера, которая, однако, упростит работу с таблицей и сделает механизм полностью скрытым от пользователя. К сожалению, просто скрыть строку посредством соответствующей команды меню Формат не удастся. В этом случае Automation будет передавать в документ Word значения из строки 3, которая станет второй по счету видимой строкой. Единственный выход заключается в том, чтобы при помощи форматирования ячеек строки 2 назначить для них черную заливку (рис. 3.13). В этом случае происходящие в строке изменения станут невидимыми, и не будут смущать пользователя.

Рис. 3.13. На листе “Платежка” помещаются реквизиты платежных поручений

Строки же, начиная со строки 3, можно теперь использовать для ввода реквизитов платежных поручений ООО “Универсал”.

Макрос, копирующий текущую строку в строку 2

Чтобы можно было воспользоваться конструкцией таблица + документ, остается лишь копировать текущую строку таблицы в строку 2 — об остальном позаботятся связи этой строки с документом Word.

Обратно из таблицы Excel в документ Word 97

Макрос, который решает подобную задачу, очень прост. Речь идет о процедуре обработки события SelectionChange. Это событие рабочего листа, которое возникает при любом изменении выделенной области, в том числе и в случаях, когда курсор ввода просто перемещается на другую ячейку. Неважно, как это происходит: при помощи мыши или клавиатуры. Достаточно при обработке этого события копировать значения из текущей строки в строку 2, и задача решена.

Надеемся, читатель сам уже в состоянии создать обработчик этого события, открыв контекстное меню рабочего листа щелчком правой кнопки мыши на ярлычке “Платежка” и выбрав команду Исходный текст, а затем выбрав в окне кода объект Worksheet и событие

SelectionChange.

Вот программный код, который должен содержаться в процедуре обработки события (листинг

3.4).

ЛИСТИНГ 3.4

Private Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)

Dim N As Integer

For N = 1 To 10

Cells(2, N).Value = Cells(ActiveCell.Row, N).Value

Next N

End Sub

При помощи цикла For и целочисленной переменной N копируются значения свойства Value из ячеек текущей строки в ячейки строки 2. В свойстве Value находится значение ячейки, то есть просто текст или число, которые в ней содержатся. Выражение ActiveCell.Row возвращает номер строки, к которой принадлежит текущая ячейка (ActiveCell). После щелчка мыши или перемещения курсора ввода при помощи клавиатуры это выражение вернет номер строки как раз той самой ячейки, которая только что стала текущей.

Определение границ для цикла For исходило из предположения, что каждая строка таблицы содержит десять обязательных реквизитов, — разумеется, эта величина должна меняться в каждом конкретном случае. Нет нужды делать этот макрос универсальным, ведь для каждого такого рабочего листа все равно потребуется собственный обработчик события SelectionChange. Однако, если бы такая необходимость на самом деле существовала, то выражение UsedRange.Columns.Count вернуло бы нам число столбцов, фактически использованных на листе.

Сразу после ввода исходного текста макроса его можно проверить в действии. Для этого необходимо вначале открыть окно Word с документом-заготовкой. Затем следует перейти в окно Excel и постараться изменить размеры обоих окон так, чтобы документ Word и таблица Excel были видны одновременно. Щелкните мышью на любой строке таблицы, — содержащиеся в ней значения реквизитов тотчас отобразятся в документе Word.

Еще пара макросов, необходимых для автоматического открытия и закрытия окна Word

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

Постановка задачи

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

98 Глава 3. Поверка гармонии Word алгеброй Excel

Обработчик события рабочего листа Activate

Для решения этих задач необходимо обрабатывать события рабочего листа Activate (лист становится текущим, то есть активным) и Deactivate (лист перестает быть текущим, то есть активным становится какой-то другой лист). Текст обработчика события рабочего листа Activate приведен на листинге 3.5.

ЛИСТИНГ 3.5

Dim WD As Word.Application

Private Sub Worksheet_Activate()

Set WD = CreateObject("Word.Application")

WD.Visible = True

WD.Documents.Open ("C:\Plategka.doc")

WD.ActiveDocument.Fields.Update

End Sub

Обратите внимание на тот факт, что объектная переменная WD, представляющая экземпляр приложения Word, объявлена вне текста процедуры. Это необходимо по той причине, что доступ к этой переменной должна иметь также и другая процедура, о которой речь пойдет ниже. Если бы переменная WD была объявлена внутри макроса Worksheet_Activate, в других процедурах она была бы не доступна.

Собственно код процедуры несложен, и многое в нем уже должно быть понятным без объяснений. Переменная WD, содержащая в себе запущенное приложение MS Word, делается видимой, то есть, окно Word появляется на экране, благодаря присваиванию значения True ее свойству Visible. При помощи метода Open (открыть) в семейство документов запущенного Word добавляется документ из файла C:\Plategka.doc. Наконец, вызовом метода Update для семейства полей (Fields) текущего документа достигается принудительное обновление полей. Fields — это семейство, обеспечивающее доступ вообще ко всем полям документа, а не только к полям, обеспечивающим OLE-связь. Благодаря этому, только что открытый документ сразу же будет отображать текущее состояние связей.

Обработчик события рабочего листа Deactivate

Затем, когда лист перестанет быть активным, произойдет событие Deactivate (листинг 3.6).

ЛИСТИНГ 3.6

Private Sub Worksheet_Deactivate()

On Error Resume Next

WD.ActiveDocument.Close

WD.Quit

Set WD = Nothing

End Sub

Вызовом метода Close активный документ закрывается, и приложение Word (переменная WD) завершает свою работу при помощи метода Quit. Переменной WD затем присваивается значение Nothing. Строка On Error Resume Next необходима на тот случай, когда пользователь сам закрыл окно MS Word и объект, заключенный в переменной WD, на момент выполнения макроса уже не существует. В этом случае, без этой строки, возникла бы ошибка выполнения процедуры.

см. также в этой главе раздел “Управление ошибками выполнения макроса”.

ПРИМЕЧАНИЕ

1.При совместном использовании макросов VBA и технологии Automation (OLE Automation) необходимо обязательно учитывать возможности системных ресурсов. Дело в том, что

Обратно из таблицы Excel в документ Word 99

Automation — ресурсоемкая технология. Если речь идет о всего лишь нескольких связанных объектах, то класс компьютера можно не принимать во внимание. Если же число используемых связей исчисляется десятками, то на системах класса 486 и ранних Pentium скорость работы связанных объектов будет, скорее всего, неприемлемо низкой. В такой ситуации, вероятно, стоит задуматься о других способах автоматизации.

2.Точно таким же образом, как описано выше, можно было бы связать документную таблицу с любым документом MS Office, а не только с документом Word. Например, очень часто бухгалтерские документы, особенно табличного характера, выполняют на листе рабочей книги Excel. Но как раз в случае Excel необходимости в связывании объектов при помощи технологии Automation (OLE Automation) на самом деле нет. Ничто не мешает, конечно, связать при помощи команд Копировать и Специальная вставка ячейки в строке таблицы документов с соответствующими ячейками на листе, играющем роль формы. Но, если на листе использованы макросы VBA, это будет пустой тратой времени, поскольку макрос рабочего листа может обращаться к ячейкам на другом рабочем листе напрямую, без какого-либо связующего механизма.

Глава 4

Практикум программирования на VBA для Excel и Word

Прежде чем оставить “территорию” таких наиболее широко используемых приложений, какими, без сомнения, являются Word и Excel, выполним ряд упражнений, которые помогут лучше разобраться в основах программирования на языке VBA в среде этих популярных приложений.

Сумма прописью

Во многих хозяйственных документах необходимо указывать денежную сумму прописью. Если решать задачи автоматизации, касающиеся таких документов, как платежное поручение или счет, то странно было бы заполнять поле “сумма прописью” вручную. В предыдущей главе в одном из столбцов рабочего листа Excel необходимо было указывать сумму документа, а в соседнем столбце — сумму прописью. При помощи VBA можно “научить” рабочий лист Excel заполнять столбец “сумма прописью” автоматически.

Можно было бы поместить соответствующий код непосредственно в процедуру обработки одного из событий рабочего листа. Например, можно было бы использовать событие Change, заключающееся в том, что изменилось содержимое одной из ячеек листа. По этому событию можно “отлавливать” изменения в необходимых ячейках (например, в ячейках одного из столбцов), и формировать строку суммы прописью в соответствующей ячейке другого столбца.

Однако этот случай представляется подходящим для того, чтобы освоить сразу две концепции VBA-программирования. Во-первых, познакомиться с механизмом модулей Visual Basic.

Модули Visual Basic

Программный код макросов VBA может размещаться в различных объектах. Если речь идет об Excel, то макрос может быть “приписан” к рабочей книге (например, если он обрабатывает события книги или приложения) или к рабочему листу (соответственно, если он обрабатывает одно из событий данного рабочего листа). Но могут существовать макросы, не являющиеся обработчиками событий. Процедуры, которые используются другими макросами, — куда их помещать? А где хранятся макросы, записанные при помощи макрорекордера и запускаемые при помощи сочетания клавиш или кнопки панели инструментов? Большинство программного кода такого типа находится в программных модулях. Процедура, созданная в модуле, не относится ни к какому объекту, но, в то же время, ею может воспользоваться любой из макросов. Есть простой практиче-

ский смысл в том, чтобы создать макрос “Сумма прописью” именно в модуле, поскольку в этом случае он будет доступен для всех объектов книги. Итак, вначале необходимо включить в состав рабочей книги программный модуль (тот же самый механизм действует и в других приложениях Office, например, в шаблоне или документе Word также можно создать программный модуль).

Как добавить к рабочей книге Excel программный модуль

1.Откройте окно редактора Visual Basic командой Сервис | Макрос | Редактор Visual Basic.

Соседние файлы в папке Книги