MS Word - сервер, документы и параметры страницы
Автор: Василий Нестеров
WEB-сайт: www.is.svitonline.com
Здесь речь пойдет об общих свойствах компонентов WordApplication и WordDocument, работе с документами и установке "параметров страницы" документа - о том, что нужно, чтобы начать работу с MS Word.
Сервер Word
Поместив на форму компонет WordApplication, видим, что свойств и методов у него совсем мало. В первую очередь следует задать свойство ConnectKind. Оно может принимать значения:
- ckRunningOrNew Подключение к уже запущенному серверу Word, при его отсутствии сервер запускается.
- ckNewInstance Приложение обязательно запустит для своих целей собственный экземпляр сервера.
- ckRunningInstance Приложение подключается только к работающему экземпляру сервера. При его отсутствии возникает ошибка.
- ckRemote Соединение с сервером на удаленном компьютере.
Обычно вполне устраивает значение по умолчанию ckRunningOrNew. Это значит, что ваше приложение будет работать с уже выполняющимся на компьютере экземпляром Word'а, а если такового нет, запустит. Второй вариант ckNewInstance означает, что обязательно запустится еще один экземпляр Word'а, независимо от того, открыт Word или нет. Если установить значение ckRunningInstance, наше приложение будет работать только с уже запущенным Word, а если его не имеется, возникнет исключение EOleSysError. Для работы с Word на удаленном компьютере выбираем ckRemote, при этом в свойстве RemoteMachineName не забываем указать сетевое имя нужной машины.
За соединение с сервером Word отвечает метод Connect. Тип соединения задается только что рассмотреным свойством ConnectKind. Вот, например, код, при выполнении которого программа пытается соединиться с выполняющимся сервером Word, а при его отсутствии выдает сообщение. Тип соединения установим в ckRunningInstance.
try
WordApplication1.Connect;
except
Application.MessageBox('Приложение будет закрыто', 'Ошибка соединения', 0);
Application.Terminate;
end;
При желании можно было бы проверять возникновение конкретно данного исключения (потребуется руками подключить модуль comobj), но это вряд ли существенно. Главное, удачно прошло соединение или нет. Для отсоединения от Word'а используем метод
WordApplication1.Disconnect;
Свойства AutoConnect и AutoQuit, установленные в True, позволяют производить соединение с Word и отсоединение от него автоматически. То есть при запуске вашей программы автоматически вызыватся метод Connect, а при выходе из нее - Disconnect и Quit. Однако постоянно держать соединение с Word обычно не требуется, потому по умолчанию эти свойства установлены в False.
Имеющееся у сервера Word свойство Visible определяет, будет ли виден MS Word во время нашей работы с ним. Может принимать значения True и False - соотвественно видимый и нет. Обычно работа с документами производится в невидимом режиме, а потом показывают на экране уже готовый результат. Но на этапе отладки удобнее видеть своими глазами, что делает программа. Впрочем, иногда из политических соображений можно оставить сервер видимым - когда сам собой открывается Word и начинает печататься документ, на непросвещенные умы это производит большое впечатление:))
Свойство Version дает возможность узнать версию установленного на машине Word'а. Например:
Label1.Caption := WordApplication1.Version;
Если в метке '9.0', на компьютере Word 2000. Для XP и 97, честно говоря, не помню, но это несложно проверить. Можно сделать ему StrToFloat(), если меньше 9 - Word 97, если больше - Word XP.
Другое важное свойство сервера Word - коллекция Documents. Позволяет открыть документ или создать новый, обеспечивает доступ к уже открытым документам. Открытие документа (предварительно описываем переменную FileName типа OleVariant и присваиваем ей строку с именем файла):
WordApplication1.Connect;
WordApplication1.Documents.Open(FileName,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam);
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
Обратите внимание на количество параметров - "пустышек". Их число не совпадает с тем, что обычно приводится в книжках. Объясняется это тем, что "книжная" функция предназначена для MS Word 97, а такая запись для Word 2000 и Word XP. По моим наблюдениям, основная разница при работе с разными версиями Word заключается именно в открытии документа (или создании нового).
Создание нового документа выглядит проще:
WordApplication1.Connect;
WordApplication1.Documents.Add(EmptyParam, EmptyParam, EmptyParam, EmptyParam);
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
Здесь также ставим на пару "пустышек" больше - по тем же самым причинам. Если вы хотите создать новый документ на основании своего шаблона, вместо первого параметра ставите переменную типа OleVariant, которой предварительно присваиваете строку с путем к dot - файлу. При открытии документа несколько забежали вперед, про подсоединение компонента WordDocument еще поговорим в дальнейшем.
Когда у нас есть несколько открытых документов, можем переключаться между ними, но не прямо, а через "активное" окно Word'а:
var
vid: OleVariant;
begin
vid := 2;
WordApplication1.Windows.Item(vid).Activate;
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
При этом следует помнить, что переменная vid может принимать значения от 1 до WordApplication1.Documents.Count. Далее можем работать с указанным документом. Нумерация документов происходит в порядке их открытия. Формально мы могли бы записать
WordApplication1.Documents.Item(vid).Activate;
Но оно не работает. Вообще, разных глюков встретится много, уж не знаю, кого тут винить - Borland или Microsoft.
Чтобы Word не тратил время понапрасну, полезно сразу отключить проверку правописания и грамматики:
WordApplication1.Options.CheckSpellingAsYouType := False;
WordApplication1.Options.CheckGrammarAsYouType := False;
Соответственно, присвоив True, можем снова включить.
Ну и для того, чтобы выгрузить Word, вызываем метод Quit:
WordApplication1.Quit;
Документ Word
Для работы с документами предназначен компонент WordDocument. Свойств и методов у него снова не густо, свойства его схожи со свойствами WordApplication, о которых уже говорили. Как правило, свойства вообще и не трогают. Основное, что нам пока надо - соединение с нужным документом. Для этого служит метод ConnectTo. Если открыт только один документ, нет ничего проще - соединяемся с "активным" документом, пример см. выше в открытии документа. Если же документов открыто несколько, начинаются сложности. Формально можем записать, к примеру:
var
vid: OleVariant;
begin
vid := 2;
WordDocument1.ConnectTo(WordApplication1.Documents.Item(vid));
На практике это срабатывает почему-то только в первый раз. Если вставляем строку в документ № 2, при первом вызове она вставится именно туда. При последующих, какой бы номер документа не был указан, строка попадает в первый документ. Потому при необходимости я использую тот переход по "номеру окна", который приводился в предыдущем разделе, а вообще стараюсь открывать только по одному документу за раз.
Для сохранения документа используем метод Save:
WordDocument1.Save;
Метод Save с параметром позволяет сохранить документ под другим именем:
var
filename: OleVariant;
begin
filename := 'd:\test.doc';
WordDocument1.Save(filename);
Если хотим записать документ не только под другим именем, но и в другом формате, используем Save с двумя параметрами:
WordDocument1.SaveAs(FileName, FileFormat)
где переменная FileFormat типа OleVariant может принимать значения:
$00000000 - wdFormatDocument - Документ Word
$00000004 - wdFormatDOSText - Простой текст
$00000006 - wdFormatRTF - Файл RTF
Это самые насущные константы, а полный список можно найти в заголовочном файле, введя в строку поиска "Format".
Можно для сохранения использовать и метод Close. Для него указаваем, сохранить ли изменения при закрытии документа:
var
vschange: OleVariant;
begin
vschange := wdSaveChanges;
WordDocument1.Close(vschange);
Константа сохранения изменений может принимать значения
wdSaveChanges - $FFFFFFFF
wdDoNotSaveChanges - $00000000
wdPromptToSaveChanges - $FFFFFFFE
Первое значение сохраняет изменения, второе дает возможность выйти без сохранения изменений. Последняя константа вызывает при выходе стандартный диалог сохранения изменений.
Метод Close можем вызвать и без параметров:
WordDocument1.Close;
Но если в документ вносились какие-то изменения, будет выдан стандартный запрос на их сохранение. Если Word невидим, запроса также не видим, и такие документы могут висеть в фоновом режиме вплоть до выключения компьютера, когда и получим все вопросы. Самое интересное, что при работе через стандартные компоненты Word не отображается в списке активных приложений, потому на его закрытие и своевременное сохранение документов надо обращать внимание.
Часто перед работой с Word'ом возникает необходимость проверить, нет ли на машине открытых документов, сохранить их и закрыть во избежание порчи:
var
i, doccount: Integer;
begin
doccount := WordApplication1.Documents.Count;
for i := 1 to doccount do
begin
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
WordDocument1.Save;
WordDocument1.Close;
end;
Такой код сохраняет и закрывает все открытые на машине документы. Записав вместо последних двух строк цикла метод Close с параметрами, можем выйти из документов без сохранения. То есть последовательное подключение к активному документу просто перебирает их. Что интересно, переключаться между документами для работы таким способом не выходит.
"Параметры страницы"
Здесь речь пойдет о установках страницы - полях, разрывах страниц и печати текста в несколько колонок. Также можем программно переключать "размер бумаги" - альбомный или портрет. Но с последним надо соблюдать осторожность, дальше будет сказано, почему.
Размер бумаги и поля
Сначала о том, как определить или изменить установленный в Word размер бумаги:
WordDocument1.PageSetup.PageWidth:=200;
WordDocument1.PageSetup.PageHeight:=300;
Это мы изменили совершенно произвольно высоту и ширину страницы. Числа, которые присваиваем соответствующим свойствам, типа Single. Таким же образов можем и прочитать установленные в Word параметры страницы.
Теперь о полях. Изменение (чтение) ширины полей страницы:
WordDocument1.PageSetup.TopMargin:=100;
WordDocument1.PageSetup.BottomMargin:=90;
WordDocument1.PageSetup.LeftMargin:=90;
WordDcoument1.PageSetup.RightMargin:=50;
Числа, которые присваиваем ширине полей, опять-таки типа Single.
Кроме того, можем пользоваться большим набором "предопределенных" форматов бумаги. По умолчанию это обычно "а4", но можем выбрать и что-нибудь другое.
Колонки
Если есть желание вывести текст в несколько колонок, поступим так:
var
a, b, vwidth, vspace, vesp: OleVariant;
begin
vwidth := 210;
vspace := 10;
vesp := wdLineSpaceSingle;
WordDocument1.PageSetup.TextColumns.Add(vwidth, vspace, vesp);
Здесь мы добавили еще один столбец. Если начнем заносить в документ текст, он будет аккуратно распределяться в две колонки. Таким образом создаем столько колонок, сколько нужно. Первый параметр - ширина столбца, второй - расстояние между столбцами, третий - отступ между строчками. Может иметь значения:
wdLineSpaceSingle - $00000000
wdLineSpace1pt5 - $00000001
wdLineSpaceDouble - $00000002
Параметры столбцов можем поменять и задним числом. Столбцы образуют коллекцию TextColumns, нумеруются целым индексом от 1 до WordDocument1.PageSetup.TextColumns.Count:
var
i: Integer;
begin
i := 1;
WordDocument1.PageSetup.TextColumns.Item(i).Width := 100;
WordDocument1.PageSetup.TextColumns.Item(i).SpaceAfter := 10;
|