Delphi і word

Йтиметься про загальні властивості компонентів WordApplication і WordDocument, роботі з документами та встановлення "параметрів сторінки" документа - про те, що потрібно, щоб почати роботу з MS 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'а використовуємо метод


Властивості AutoConnect і AutoQuit, встановлені в True, дозволяють виробляти з'єднання з Word і від'єднання від нього автоматично. Тобто при запуску вашої програми автоматично визиватся метод Connect, а при виході з неї - Disconnect і Quit. Однак постійно тримати з'єднання з Word зазвичай не потрібно, тому за замовчуванням ці властивості встановлені в False.

Наявне у сервера Word властивість Visible визначає, чи буде видно MS Word під час нашої роботи з ним. Може приймати значення True і False - соотвественно видимий і немає. Зазвичай робота з документами проводиться в невидимому режимі, а потім показують на екрані вже готовий результат. Але на етапі налагодження зручніше бачити своїми очима, що робить програма. Втім, іноді з політичних міркувань можна залишити сервер видимим - коли сам собою відкривається Word і починає друкуватися документ, на неосвічені уми це справляє велике враження :))

Властивість Version дає можливість дізнатися версію встановленого на машині Word'а. наприклад:

Інша важлива властивість сервера 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);

Створення нового документа виглядає простіше:

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. Далі можемо працювати з зазначеним документом. Нумерація документів відбувається в порядку їх відкриття. Формально ми могли б записати


Але воно не працює. Взагалі, різних глюків зустрінеться багато, вже не знаю, кого тут звинувачувати - Borland або Microsoft.

Щоб Word не витрачав час даремно, корисно відразу відключити перевірку правопису і граматики:

WordApplication1.Options.CheckSpellingAsYouType: = False;
WordApplication1.Options.CheckGrammarAsYouType: = False;


Відповідно, присвоївши True, можемо знову включити.

Ну і для того, щоб вивантажити Word, викликаємо метод Quit:

Для роботи з документами призначений компонент WordDocument. Властивостей і методів у нього знову не густо, властивості його схожі з властивостями WordApplication, про які вже говорили. Як правило, властивості взагалі і не чіпають. Основне, що нам поки треба - з'єднання з потрібним документом. Для цього служить метод ConnectTo. Якщо відкритий тільки один документ, немає нічого простішого - єднаємося з "активним" документом, приклад див. Вище у відкритті документа. Якщо ж документів відкрито кілька, починаються складності. Формально можемо записати, наприклад:

var
vid: OleVariant;
begin
vid: = 2;
WordDocument1.ConnectTo (WordApplication1.Documents.Item (vid));

На практиці це спрацьовує чомусь тільки в перший раз. Якщо вставляємо рядок в документ. 2, при першому виклику вона буде вставлено саме туди. При наступних, який би номер документа не було зазначено, рядок потрапляє в перший документ. Тому при необхідності я використовую той перехід по "номеру вікна", який приводився в попередньому розділі, а взагалі намагаюся відкривати тільки за одним документом за раз.

Для збереження документа використовуємо метод Save:


Метод Save з параметром дозволяє зберегти документ під іншим ім'ям:

var
filename: OleVariant;
begin
filename: = 'd: \ test.doc';
WordDocument1.Save (filename);

Якщо хочемо записати документ не тільки під іншим ім'ям, але і в іншому форматі, використовуємо Save з двома параметрами:


де змінна 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 можемо викликати і без параметрів:


Але якщо в документ вносилися якісь зміни, буде виданий стандартний запит на їх збереження. Якщо 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 розмір паперу:


Це ми змінили абсолютно довільно висоту і ширину сторінки. Числа, які присвоюємо відповідним властивостям, типу 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;