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

Orlov_VBA

.pdf
Скачиваний:
23
Добавлен:
13.03.2016
Размер:
7.79 Mб
Скачать

А теперь - программа расшифровки данных. Точно так же разберем ее по строкам.

Sub decrypt()

Dim a, b, c, d As String

Строка для расшифровки:

c = "003004016001018027082016021025007083017029029009"

Пароль:

b = "password"

Итог расшифровывания:

a = ""

Узнаем длины каждой из строк:

lentext = Len(c) lenpass = Len(b)

Собственно расшифровывание (попробуйте разобраться самостоятельно в структуре команды - это не так сложно):

For cn = 1 To lentext Step 3

a = a + Chr(Val(Mid(c, cn, 3)) Xor Asc(Mid(b, (Int(cn / 3) Mod lenpass)

+1, 1))) Next cn

Витоге в переменной a - расшифрованная строка, ее можно записать в любое место - в документ, к примеру:

Selection.TypeText Text:=a

End Sub

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

* * *

Открытый и закрытый коды

Наверняка все слышали такие фразы: "Шифрование с открытым ключом", "Шифрование с закрытым ключом", "Публичный ключ". О том, что они означают, можно писать большие книги, однако стоит вкратце описать ситуацию для полноты изложения.

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

Сгенерировав специальной программой пару таких последовательностей (называемых ключами), можно первую из них сообщить тому, от кого ждешь секретных посланий ("сообщить ему публичный

ключ"), а вторую оставить себе и хранить как зеницу ока ("оставить себе секретный ключ"). То, что будет зашифровано отправителем этим публичным ключом, даже сам отправитель расшифровать не сможет. Это сможет сделать только обладатель секретного ключа.

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

Именно на таком принципе работает механизм шифрования PGP.

* * *

Ответы на вопросы

Эта книга написана по мотивам цикла статей "Начала программирования на VBA", публиковавшегося в журнале "Мир ПК" в 2000-2001 годы. После публикации статей цикла мне пришло немало писем с различными вопросами о программировании. Ниже представлены ответы на наиболее интересные из них.

1.

"В документе я хочу защитить от изменений пользователем только рисунок. Могу ли я это сделать? Метод Protect, похоже, этого сделать не дает."

Нет. Microsoft Word делать это не позволяет.

Впрочем, можно пойти на хитрость. Создайте документ Doc1.doc и вставьте в него рисунок. Затем сохраните документ с рисунком, задав ему пароли на открытие и на изменения. Создайте документ Doc2.doc. В том месте, где должен быть рисунок, вызовите окно Вставка-Обьект-Создание из файла и укажите в пути файл doc1.doc, отметив предварительно пункт "Связь с файлом". Введите пароль на открытие - и рисунок в Вашем документе. Сохраните его.

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

2.

"Возможно ли в Word проводить сравнение двух документов по словам..."

Да, разумеется. Откройте один из сравниваемых документов, выберите пункт меню "Сервис"- "Исправления"-"Сравнить версии" и выберите в открывшемся диалоговом окне второй файл для сравнения. Все разночтения будут выделены, в зависимости от их характера - зачеркиванием, цветом и др.

3.

"Как можно узнать количество страниц в Word2000 из макроса?"

С помощью команды

p = ActiveDocument.ComputeStatistics(wdStatisticPages)

где в переменную p запишется количество страниц в активном документе.

4.

"Сделал документацию на свою VBA-программу в Word 97 в doc-файле. Включил в нее screenshot'ы, на которые наложил автофигуры Word - выноски, стрелки, скобки, надписи и проч., что разъясняло бы назначение частей рисунков. Теперь хочется поставлять документацию в формате HTML, но... при конвертации Word начисто игнорирует свои же автофигуры, оставляя в итоговых gif-файлах чистый рисунок. Как цивилизовано выйти из ситуации?"

Да, автофигуры Word97 при конвертации в HTML игнорируются. Для реализации желаемой Вами задачи выделите все автофигуры рисунка вместе с самим рисунком (инструментом "Выделение обьектов" панели "Рисование"), сгруппируйте их, вырежьте в Буфер обмена, а затем вставьте то, что в буфере, на то место, где был исходный рисунок, с помощью команды "Правка"-"Специальная вставка", используя в качестве формата вставляемого изображения "Точечный рисунок" или "Метафайл Windows", т.е. что угодно, кроме "рисунка MS Office". После этого у Вас в документе появится рисунок с всеми вставленными автофигурами, который, однако, спокойно конвертируется в GIF-формат при конвертации всего документа в HTML. Так следует поступить со всеми рисунками в документе. В Word2000 и Word2002 такой проблемы нет – там автофигуры сохраняются в самой генерируемой webстранице, но при просмотре ее в старых браузерах могут быть не видны.

5.

"Можно ли Word 2000 убрать автоматический запуск панели "Буфер обмена"?"

Вообще говоря, там встроен "интеллектуальный" механизм, который больше не отображает панель после того, как пользователь ее закроет несколько раз. Сделать так, как Вы желаете, можно, если использовать макросы.

Макрос для полного скрытия панели:

Sub clipboard_hide()

CommandBars("Clipboard").Enabled = False

End Sub

Макрос для показа панели:

Sub clipboard_show()

CommandBars("Clipboard").Enabled = True

CommandBars("Clipboard").Visible = True

End Sub

Назначьте этим макросам кнопки и используйте их.

К счастью, в Word XP эта рекомендация уже неактуальна - там Область задач с вкладкой "Буфер обмена" вызывается только тогда, когда дважды нажата комбинация клавиш Ctrl+C.

6.

"Как определить с помощью макроса в документе Word текущий номер страницы, где произошло при поиске вхожение заданной подстроки."

Существуют функции Selection.Information(wdActiveEndPageNumber), которая возвращает номер страницы по счету, на которой располагается конец выделения, и функция

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

При работе подпрограммы поиска каждое вхождение выделяется. Вот, к примеру, фрагмент кода макроса, который отображает в диалоговом окне номера страниц, на которых найден текст "text".

Selection.HomeKey Unit:=wdStory Dim a As String

a = "" Selection.Find.ClearFormatting

Selection.Find.Replacement.ClearFormatting With Selection.Find

.Text = "text"

.Forward = True

.Wrap = wdFindStop

End With

While Selection.Find.Execute = True

a = a + " " + Str(Selection.Information(wdActiveEndPageNumber))

Wend

MsgBox a

7.

"Открыт документ Word, хочу запустить в нем макрос, который в свою очередь запускает макрос Excel, обрабатывающий Excel-таблицу. После этого через Clipboard из Excel макрос пересылает в Word-документ заданную прямоугольную область таблицы. Макрос Word обрабатывает эту область и начинает в требуемой последовательности копировать в Word-документ через Clipboard фрагменты Excel-таблицы. По окончании копирования Word закрывает все ненужные макросы, включая макрос Excel. Как все это сделать, чтобы работало?"

Для работы из одного приложения Office с другим лучше всего использовать технологию ActiveX. Она основана на имеющейся в Office возможности представлять одну программу в другой как некий обьект, с которым можно работать теми же командами, что используются при непосредственной работе с этой программой.

Так, чтобы можно было из Word'ового макроса работать с Excel'ем, следует создать обьект Excel.Sheet (здесь "es" - простое наименование переменной, у вас может быть любым).

Dim es As Object

Set es = CreateObject("Excel.Sheet")

Если надо сразу открыть какой-либо файл Excel'а, то можно использовать команду GetObject:

Set es= GetObject("Путь к файлу Excel'а")

При желании можно сделать созданный обьект Excel видимым:

es.Application.Visible = True

Теперь можно этому обьекту es (т.е. просто запущенному Excel'у) посылать команды такие же, как и в макросах Excel'а (предваряя текстом "es.Application." те из команд, которые не требуют прямого указания обьекта, - так как надо дать понять программе, что работа идет именно с Excel'ем). Так, чтобы открыть файл Excel'а, можно также дать команду

es.Application.Workbooks.Open FileName:="Путь к файлу Excel'а"

а чтобы, например, поместить в первую ячейку открытой книги текст, используйте команду

es.Cells(1, 1).Value = "Это столбец A, строка 1"

В принципе я бы вам посоветовал поместить тот макрос, который Вы планировали для Excel'а, именно в исходный Word'овый, переписав его команды в соответствии с принципом связывания (т.е. управления одним приложением из другого - так, как описано выше).

Закрыть Excel можно командой

es.Application.Quit Set es= Nothing

Если работать с таблицей из Word почему-либо нельзя, и требуется именно вызвать Excel'евский макрос, то для вызова макроса следует использовать команду

es.Application.Run "имя макроса"

Также можно автоматически запустить какой-либо макрос при открытии файла Excel:

es.Application.Workbooks.Open FileName:="Путь к файлу Excel'а!имя макроса" (например, es.Application.Workbooks.Open FileName:="c:\book1.xls!macr1", точно так же,

разделяя имя файла и имя макроса восклицательным знаком - и в команде Shell)

В общем, есть простор для творчества. Про работу из Word'а с Excel'ем и т.д. почитайте разделы Справки VBA (для Microsoft Office 97 - по-русски): "Работа с приложениями", "Функция CreateObject", "Функция GetObject", "Программирование объектов".

8.

"Можно ли в Word при помощи гиперссылки вызвать команду меню, в частности команду "Найти"?"

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

Private Sub Label1_Click()

On Error Resume Next

Dialogs(wdDialogEditFind).Show

End Sub

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

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

К сожалению, с командой Dialogs… ничего сделать нельзя - так уж будет себя вести это диалоговое окно.

Однако можно использовать "финт ушами". В VBA есть функция SendKeys, которая передает активному окну нажатия клавиш - как если бы они были нажаты на клавиатуре. (Подробнее - смотрите в Справочной системе VBA.) Поэтому можно ее использовать:

Private Sub Label1_Click()

SendKeys "^f"

End Sub

предполагая, что комбинация клавиш Ctrl+f вызывает окно "Найти", как, впрочем, устанавливается по умолчанию. Список кодов функциональных клавиш - в Справке.

Если Вы используете функцию SendKeys, то вызванное ею окно будет вести себя абсолютно так же, как при ручном вызове. Однако помните, что если пользователь переопределит заложенную Вами в макрос комбинацию клавиш, то Ваша программа начнет работать некорректно.

* * *

Отличия новых версий Office

Отличия VBA в новых версиях Office в основном заключаются в добавлении новых функций, событий, процедур и объектов. Например, в Office 2000 появились события обьекта Application, позволяющие перехватить почти любое происходящее в документе событие. Так, событие

"DocumentBeforeClose" выполняется перед закрытием документа, "DocumentBeforePrint" - перед его печатью, "WindowBeforeRightClick" - сразу после клика правой кнопкой мыши в окне программы, "WindowSelectionChange" - при изменении выделения, смещении точки ввода (за исключением простого ввода текста).

ВOffice2000 изменилась система защиты от вирусов в макросах. Так, в Word2000 для того, чтобы иметь возможность запускать макросы, необходимо, чтобы в диалоговом окне "Сервис - Макросы - Безопасность" был установлен "Средний" или "Низкий" уровень защиты от макросов (лучше "Средний"

-тогда при открытии документов с макросами пользователю будет выдан запрос о необходимости разрешения исполнения макросов).

Также в Word2000 для того, чтобы пользователь имел возможность запускать макросы из шаблонов, установленных в папку автозагружаемых файлов Word, необходимо на вкладке "Надежные источники" диалогового окна "Сервис - Макросы - Безопасность" установить отметку в пункте "Доверять всем установленным надстройкам и шаблонам". Обо всем этом следует упомянуть в документации к разрабатываемой вами программе.

То же самое верно и для Office XP, однако отличия есть и здесь.

Во-первых, по умолчанию компоненты Office XP, отвечающие за запуск макросов, на жесткий диск не ставятся – таким образом, похоже, Microsoft пытается защитить наиболее неразумных пользователей от макровирусов. По большому счету, подобные ее действия обычно приносят больше вреда, чем пользы, для авторов же программ на VBA из этого следует, что в справочных файлах к своим программам им следует упоминать о необходимости доустановки компонентов Office перед началом использования макросов.

Во-вторых, для того, чтобы иметь возможность программно копировать модули и формы макросы между документами и шаблонами, необходимо, чтобы в диалоговом окне "Сервис - Макросы - Безопасность", на вкладке "Надежные источники" имелась отметка в пункте “Доверять доступ к Visual Basic Project”. Об этом тоже следует упомянуть в справке к программе.

Из появившихся новых событий в Office XP можно отметить возможность отслеживать изменение размеров окна приложения (обработчиком события WindowSize).

ВOfficeXP скопировать файл из одной папки в другую или удалить его посредством программного кода можно только при отключенной Службе индексирования (cсылка “Параметры поиска” на панели “Обычный поиск", рис.8.10). К сожалению, по умолчанию эта Служба включена, а программно ее отключить невозможно. Поэтому, несмотря на декларируемую "совместимость сверху вниз" версий Office, автору программ на VBA настоятельно рекомендуется тестировать свои программы во всех версиях Office и отлаживать их при необходимости.

Рис. 8.10. Если в OfficeXP вы хотите копировать и удалять файлы с помощью

VBA

– выключите здесь "Службу индексирования".

Более подробно о новшествах в Visual Basic for Applications в новых версиях Microsoft Office

читайте в разделах их Справочных систем, которые так и называются - "Whats New for Office Developers" и, для Word, "Whats New for Word Developers".

Опыт товарищей

* * *

О том, как создавать программы на встроенном в Microsoft Office языке программирования Visual Basic for Applications (VBA), было подробно рассказано в предыдущих главах. Но теория будет еще полезнее, если подкрепить ее практикой - примерами реально работающих программ, написанных на этом языке. А таких - немало. К сожалению, многие из них не такие уж и известные, но весьма интересные и полезные для очень многих пользователей.

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

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

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

"Untaco" - расшифровка чисел и их обновление

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

Однако программа Untaco (рис.9.1) серьезно отличается от своих аналогов одной особенностью. Дело в том, что Untaco умеет автоматически обновлять те расшифровки, которые вставлены с ее помощью. Если после вставления расшифровки числа вы измените его значение, то расшифровка тоже соответственно изменится при сохранении, печати документа или вызове специальной команды, и вам не придется вставлять ее повторно. При работе с деловыми документами, бухгалтерской отчетностью такая автоматическая синхронизация расшифровки числа с его значением весьма важна, так как любое несогласование здесь может вызвать серьезные последствия.

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

Рис.9.1. Untaco - многофункциональный конвертор "число-текст" с возможностью автоматического обновления расшифровок чисел

Рис.9.2. Untaco. Отличается богатством настроек - от языка до скобок.

В Untaco реализованы интересные технические решения, связанные с ра-ботой с переменными в документе, закладками, интеллектуальной обработкой текстовых строк, а также с операциями над самими макросами (их копирование и удаление). Также в Untaco показано, как осуществить подмену стандартных команд Word (например, "Сохранить", "Печать") макрокомандами. Простой и удобный инсталлятор демонстрирует возможность помещения компонентов программ в шаблон Normal.dot.

Программа Untaco доступна с адресов: http://antorlov.chat.ru или http://www.newtech.ru/~orlov.

TreeView - кнопка "Пуск" для Microsoft Word

Те, кто часто и много работают с текстовым редактором Microsoft Word, наверняка хранят на своем жестком диске множество наработанных документов. Со временем их количество все увеличивается, растет обьем, множатся папки с файлами. Ориентироваться в них становится все затруднительнее, и зачастую на поиск и открытие нужного файла уходит масса времени. Давно уже возникла необходимость в улучшении диалогового окна Word "Открыть…", так, чтобы можно было бы более свободно работать со своими документами. И вот, наконец, желания пользователей сбылись - появилась программа "TreeView".

Данная разработка способна серьезно облегчить труд тех, чей рабочий инструмент - Microsoft Office. Коротко можно сказать, что она - окно "Открыть файл", сделанное по образцу папки Internet Explorer'a "Избранное" (или меню Windows "Пуск"), - в виде выпадающего меню отображаются все документы в текущей папке и в любых других, указанных пользователем, что позволяет искать и открывать документы, не выходя из Word и не роясь в изрядно поднадоевшем окне Word "Открыть" (рис.9.3).

Рис.9.3. Меню программы TreeView.

После установки программы среди панелей Word появляются новые (рис.9.4).

Рис.9.4. Новые панели в Word.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]