Faq работа с word через ole


Faq работа с word через ole

Имеется документ в формате rtf, в нем данные представлены в виде таблицы которая состоит из рамок с текстом (TextFrame).
Необходимо перебрать все эти «ячейки» и получить из них текст.
Кто-нибудь подскажет как это сделать? Пробовал через Frames и через TextFrames, что-то ничего не получается.

А если ActiveDocument.Tables и далее?

Так таблицы как таковой нет (в понятии Word»a), все из таких рамок слеплено.

Даю пример из компонента ( http://www.nstur.narod.ru/Delphi/index.html)
Смысл метода: ищет текст находящийся между символами указанными в ReplaceString (например |) и возвращает программе по событию, а там делай что хочешь.
procedure TNsWord.ExecuteReplace;
var
V: OleVariant;
ReplaceOk: boolean;
FindText, ReplaceText: string;
k: integer;
begin
if OpenedDocument then begin
with NsDocument.Application.Selection do begin
Find.ClearFormatting;
Find.Text:= ReplaceString[integer(ReplaceStyle)];
Find.Forward:= True;
Find.Wrap:= wdFindContinue;
Find.Format:= False;
Find.MatchCase:= False;
Find.MatchWholeWord:= False;
Find.MatchWildcards:= True;
Find.MatchSoundsLike:= False;
Find.MatchAllWordForms:= False;
repeat
OleVariant(Find).Execute;
<>
if Find.Found then begin
ReplaceOk:= False;
FindText:= Text;
if Length(FindText) > 2 then
FindText:= System.copy(FindText,2,Length(FindText)-2);
ReplaceText:= FindText;

if Assigned(FOnLocalReplace) then
FOnLocalReplace(ReplaceText);

ReplaceOk:= (ReplaceText <> FindText);
if NOT ReplaceOk then
if OtherEvents.Count > 0 then
for k:= 0 to pred(OtherEvents.Count) do
if AnsiUpperCase(FindText) = AnsiUpperCase(OtherEvents[k].Text) then
if Assigned(OtherEvents[k].FOnLocalReplace) then
OtherEvents[k].FOnLocalReplace(ReplaceText);

ReplaceOk:= (ReplaceText <> FindText);

if ReplaceOk then
Text:= ReplaceText;
end;//if
<>
if Find.Forward then begin
V:= wdCollapseEnd;
Collapse(V);
end
else begin
V:= wdCollapseStart;
Collapse(V);
end;
until NOT Find.Found;
EndDocument;
end;
end;
end;

TO Sergey SP © (14.10.03 14:56) [2]
Ага и на рамках этих данные написаны.

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

COM специфика работы с Word

Mr. Anderson

Новичок

kaster

Мой Аватар, он лучший самый

Mr. Anderson

Новичок
  • Автор темы
  • #3

Еще не понял что с этим можно делать, но в WinXP нашел интересную штуку:
Пуск — Выполнить — dcomcnfg
или
Win+R — dcomcnfg

Вроде бы и по делу, вроде и первоисточник (СОМ приложения системы), а что с этим делать не понятно. :whistle:

Garrett

Модератор

RUVATA

лучше один раз увидеть, чем десять раз услышать.

kaster

Мой Аватар, он лучший самый

RUVATA

лучше один раз увидеть, чем десять раз услышать.

и даже нужно .
Приступим:
С программами Microsoft Office Word, Excel и другими можно работать как с объектами автоматизации OLE. Этот подход существенно отличается от работы с этими программами как с серверами СОМ или от использования компонентов страницы Servers. Работа с объектами автоматизации может быть организована двумя способами: через библиотеки типов и через механизм автоматизации OLE.
Использование библиотеки типов имеет то преимущество, что обеспечивает проверку типов, но для работы с библиотекой типов надо сформировать соответствующий файл и разобраться в нем.
Использование автоматизации OLE применительно к Word и Excel проще, поскольку в эти программы встроена справка по VBA, содержащая описание всех объектов, свойств и методов.

Основные отличия при использовании автоматизации OLE от работы с серверами СОМ заключаются в следующем:

1)Для работы с серверами COM не обязательно чтобы приложение было запущено, но для этого необходимы определенные приготовления, которые требуют специфических знаний а так-же углубленного представления о работе технологии COM, как впрочем и в дальнейшем в процессе разработки.
Работа с серверами OLE требует от разработчика лишь возможность получить ссылку на COM-объект, запущенного приложения(OLE-сервер выдающий эту ссылку позиционирует себя как «Excel.Application»)

2) В серверах автоматизации OLE при вызове методов не требуется задание значений необязательных параметров, что существенно упрощает многие операторы.
Параметры методов можно задавать в форматах «имя := значение», причем последовательность задания параметров безразлична. (по правилам VBA)
Это дополнительное удобство, так как не требуется помнить последовательность параметров в объявлении метода.

3) Еще одним преимуществом серверов автоматизации OLE является то, что вызываемые методы очень близки к их описанию в справке по VB соответствующей программы Microsoft Office. В серверах СОМ в некоторых случаях наблюдаются отличия.

4) Что касается OLE, то ряд условностей в реализации IDE, как и выбранного языка программисрования влияют так или иначе на наличие подсказок, возможность/невозможность использования констант с чем COM сервер чаще не имеет проблем. OLE-сервер как-бы сам отвечает за соответсвующющее приведения типов, когда при работе с COM-сервером предварительно приведение типов (обязательно).

Теперь следут сказать о том, что несмотря на простоту использования OLE-сервера, и множество тонкостей работы с COM-сервером, их вообще не следует сравнивать так, как используют их для разного рода задачь.
OLE-сервера всецело выполняют роль автоматизации конкретного запущенного приложения,
в то время как COM сервера реализуют саму идеологию COM и предоставляют возможность работать непосредственно с комполнентами, и не неуждаются в комбинорованном приложении, возможности COM более широки, а для большей ясности:
например широко применялась практика использования модулей MS Word «проверка орфографии» для проверки содержимого текстовых полей программ написанных на том-же C# или vb.NET, даже видел реализацию на Java (хотя там на этот счет есть более лаконичные решения). основана на взаимодействии с COM сервером, и для этого требуется только чтобы Word был установлен в системе — не запущен

И все-таки в целом, как мне представляется, использовать серверы автоматизации OLE в большинстве случаев проще, чем работать с серверами СОМ.

Faq работа с word через ole

Сегодня:

Последние:
— 29.11, 09:46 / #6691
— 29.03, 23:32 / #6682
— 30 апреля 2012

Сейчас онлайн:
На сайте — 15
На IRC-канале — 2

«Delphi 4: Автоматизация приложений MS® Office® для эффективного анализа результатов»

    Содержание:

  • Глава 1: Работа с MS Excel.
    • Часть 1: Создание, отображение и удаление экземпляра Excel.
    • Часть 2: Лучшее решение — шаблоны.
    • Часть 3: Создание или открытие книги.
    • Часть 4: Работа с листами и ячейками.
    • Часть 5: Передача данных разного типа.
    • Часть 6: Передача данных используя буфер обмена и DDE.
    • Часть 7: Пример обмена данными с Excel используя VCL и OLE.
  • Глава 2: Работа с MS Word.
    • Часть 1: Управление Word-ом через OLE.
    • Часть 2: Подсчет статистики обычного текста, сносок и колонтитулов в документах.
    • Часть 3: Открытие документа используя VCL.
    • Часть 4: Работа с таблицами.
    • Часть 5: Работа с текстом, рисунками и списками.
  • Автор статей: Василий Нестеров.

    Глава 2. Работа с MS Word.

    Часть 1. Управление Word-ом через OLE.

    Здесь мы рассмотрим пример того, как управлять объектами Word-а (Excel — аналогично) из программ на Delphi.

    а) Для чего это нужно ?

    Задачи могут быть самые разные, в общем случае это использование возможностей Word-а в своей программе, н-р: проверка текста на орфографию; печать текста, графики; экспорт отчетов в Word или изначальное создание их там и т.д.

    б) Подготовительные работы.

    На самом деле существует несколько способов сделать это, мы рассмотрим только один (пример кроме Delphi 5, в Delphi 5 для этого есть компоненты на закладке Servers переименуете в программе типы на соответствующие компоненты, дальше так же).

    Для начала начнем новый проект File, New Application; File, Save All. Создадим отдельную папку для проекта и сохраним Unit1 как Main, а Project1 как WordWriter.

    Далее для работы с Word-ом нам потребуется библиотека типов Word-а, это делается так:

    Project, Import Type Library, Add, далее переходим в папку, где стоит Word ( у меня это — «c:\program files\microsoft office»), заходим в папку Office и выбираем файл — msword8.olb (цифра -? версии Word-а — у Вас может отличаться ) или excel8.olb (для Excel). Нажимаем Оk. Delphi создаст 2 файла — Word_tlb.pas и Office_tlb.pas, их надо включить в раздел uses модуля Main нашего проекта:

    в) Теперь займемся непосредственно программированием.

    В разделе var опишем следующие переменные:

    Далее проектируем форму:

    1. Поместим вверх нашей формы кнопку — button1 типа TButton, поменяем заголовок (св-во Caption) на ‘Старт’;

    2. Под кнопкой разместим панель — panel1 типа TPanel. Внутри панели поместим компонент — bevel1 типа TBevel, поменяем св-во Align на alClient (при этом рамка растянется на всю панель);

    3. Сверху панели (далее все компоненты будут размещаться внутри этой панели) разместим метку — label1 типа TLabel, поменяем значение св-ва Caption на ‘Передать в ячейку’;

    4. Ниже слева поместим метку — label1 типа TLabel, св-во Caption поменяем на ‘X=’;

    5. Правее метки помещаем компонент Edit1 типа TEdit, св-во Text меняем на ‘1’;

    6. По правой границе Edit1 помещаем компонент UpDown1 типа TUpDown, в списке св-ва ‘Associate’ выбираем Edit1, св-во ‘Position’ приравниваем ‘1’;

    7. Чуть отступаем вправо и повторяем шаги 4-6, заменив Edit1 на Edit2, UpDown1 на UpDown2, Label1 на Label2 соответственно;

    8. Ниже размещаем еще одну метку — label4 типа TLabel, меняем св-во ‘Caption’ на ‘Новое значение ячейки:’;

    9. Ниже размещаем компонент Edit3 типа TEdit, св-во Text меняем на ‘0’;

    10. И, наконец, в самом низу панели размещаем кнопку BitBtn1 типа TBitBtn, меняем св-во ‘Kind’ на ‘bkOk’.

    Теперь напашем обработчики — именно в них и заключается вся функциональность программы:

    1. Назначим обработчик OnClick компоненту Button1 :

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    // если заголовок ‘Выход’, то закрываем программу
    if button1.caption=’Выход’ then
    begin
    Application.Terminate;
    exit
    end
    // иначе (при первом начатии, когда у нас заголовок ‘Старт’)
    //переименовываем заголовок в ‘Выход’
    else button1.caption:=’Выход’;

    panel1.Visible:=true;
    // создаем экземпляр ворда
    WordApp:=CoApplication_.Create;
    // делаем его видимым
    WordApp.Visible:=true;
    // шаблон
    template:=’Normal’;
    // создать шаблон
    OpenAsTemplate:=false;
    // что-то типа оператора with, можно было и напрямую обратиться
    Docs:=WordApp.Documents;
    // добавляем документ
    Doc:=Docs.Add(template,OpenAsTemplate);

    // выделить все
    ARange:=Doc.Range(EmptyParam,EmptyParam);
    // массив параграфов
    pars:=doc.Paragraphs;
    // переменная — параметр
    template:=arange;
    // новый параграф
    par:=pars.Add(template);
    // цвет зеленный
    par.Range.Font.ColorIndex:=11;
    // вставляем текст
    par.Range.InsertBefore(‘Привет . ‘);
    // переменная — параметр
    template:=par.Range;
    // новый параграф, чтобы таблица не потерла текст
    par:=pars.Add(template);
    // цвет черный
    par.Range.Font.ColorIndex:=0;
    // вставляем текст
    par.Range.InsertBefore(‘Переключившись в программу, можно программно менять текст ячеек !’);
    // переменная — параметр
    template:=par.Range;
    // новый параграф, чтобы таблица не потерла текст
    par:=pars.Add(template);
    // выделяем параграф
    arange:=par.Range;

    // шрифт — жирный
    ARange.Font.Bold:=1;
    // шрифт — рукописный
    ARange.Font.Italic:=1;
    // получить массив таблиц
    tabls:=aRange.Tables;
    // добавляем новую таблицу размером 5 на 5
    tabl:=tabls.Add(arange,5,5);
    // в цикле
    for i:=1 to 5 do
    // задаем значение ячеек
    tabl.Cell(i,1).Range.Text:=inttostr(i);

    2. Зададим обработчик формы :


    procedure TForm1.FormDestroy(Sender: TObject);
    var
    // для параметров
    SaveChanges:olevariant;
    begin
    // если Word не закрыт
    if not VarIsEmpty(WordApp) then begin
    < а можно сохранить автоматом:
    // имя файла в оле
    template:=’Имя.doc’;
    // если не сохранен, то
    if doc.Saved=false then
    // сохраняем
    Doc.SaveAs(template, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
    EmptyParam, EmptyParam, EmptyParam, EmptyParam);

    короче, пишешь имя объекта, ставишь точку и нажимаешь
    ‘ctrl’+’ ‘ и изучаешь существующие методы и св-ва
    >
    //изменения не сохранять
    SaveChanges:=false;
    // то закрыть сначала документ
    Doc.Close(SaveChanges,EmptyParam,EmptyParam);
    // а потом и ворд
    WordApp.Quit(SaveChanges,EmptyParam,EmptyParam)
    end;
    end;

    3. Назначим обработчик OnClick компоненту Bitbtn1 :

    в) В общем-то, это все .

    Часть 2: Подсчет статистики обычного текста, сносок и колонтитулов в документах.

    В данном небольшом материале рассматривается вопрос подсчета статистики файлов *.doc и *.rtf. Такой вопрос у меня возник, когда пришлось сделать небольшую базу данных по учету документов, куда надо было заносить и статистику документа — число знаков, слов и т.п. Открывать каждый раз Word, считать статистику и забивать ее в форму ввода было лень, так что пришла в голову мысль это дело автоматизировать. Информации по данному вопросу найти так и не удалось, так что основным источником знаний служили заголовочный файл Word2000.pas и справка по Visual Basic for Applications. Ну и, конечно, множество разных экспериментов.

    Сразу оговорюсь, что я не профессиональный программист, так что в тонкости интерфейсов вникать не будем — сам в них не особо разбираюсь. Потому, не мудрствуя лукаво, просто поместим на форме компоненты WordApplication и WordDocument с палитры Servers. Для работы используются свойства и методы этих компонентов.

    Встроенная статистика Word подсчитывает статистику обычного текста, обычных и концевых сносок. Для подсчета статистики используется метод компонента WordDocument ComputeStatistic(). Он имеет один параметр, характеризующий, что именно считать, представляющий из себя шестнадцатеричную константу. Константы описаны в заголовочном файле Word2000.pas, он лежит обычно в /Delphi/Ocx/Servers.

    Шестнадцатеричная Символьное обозначение Смысл
    $00000000 wdStatisticWords Количество слов
    $00000001 wdStatisticLines Количество строк
    $00000002 wdStatisticPages Количество страниц
    $00000003 wdStatisticCharacters Знаки без пробелов
    $00000004 wdStatisticParagraphs Количество разделов
    $00000005 wdStatisticCharactersWithSpaces Знаки с пробелами

    Это было основное, что надо знать. Ну а теперь по порядку.

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

    Первым делом откроем документ. Предварительно надо объявить переменную FileName, она будет типа OleVariant, которой присвоим строку с именем файла.

    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.

    Обычный текст.

    Объявив нужное количество переменных типа LongInt (в очень большом файле или при суммировании по нескольким документам в принципе может оказаться больше знаков, чем пределы обычного целого типа), можем уже и приступать к подсчету. Например, посчитаем число слов, знаков с пробелами и без пробелов обычного текста, а также количество страниц в документе. Результаты сохраним соответственно в «длинных» переменных WCount, SCount, CCount, и PCount.

    Открыв нужный документ в Word’е и вызвав диалог подсчета статистики, нетрудно увидеть, что значения переменных равны параметрам вордовской статистики со сброшенным флажком «Учитывать все сноски».

    Сноски.

    обычные и концевые. То есть если первые располагаются внизу данной страницы, то концевые — строго в конце документа. Кроме того, они могут отличаться и нумерацией — автоматической или заданной пользователем. Начнем с обычных сносок как с самого простого. В терминологии объектной модели Word — Footnotes. Сначала надо вычислить количество самих сносок:

    Подсчет статистики текста в сноске производится так:

    Здесь ifoot — целое число, «нумерующее» сноску. Для того, чтобы учесть сами номера сносок, сделаем так:

    Это мы посчитали для примера количество слов в сноске с номером ifoot и ее метке — при пользовательской нумерации в качестве «номера» может быть целое предложение. Далее начинаем перебирать их одну за другой. При этом следует учесть, что кроме статистики сносок необходимо получить и статистику их «номеров». То есть:

    Прибавление единицы появляется оттого, что сумма статистики сносок и номеров не совпадает с тем, что выдает встроенная статистика Word. Между номером сноски и текстом сноски Word ставит пробел, который почему-то не учитывается. Условный оператор определяет, как пронумерована данная сноска — по умолчанию или нет. В последнем случае следует проверить количество слов в обозначении сноски. Такая схема дает результат, совпадающий со показаниями встроенной статистики. Кроме того, цикл у нас идет от 1 — так начинается нумерация сносок в MS Word, да и практически всех остальных объектов тоже.

    Теперь перейдем к концевым сноскам. Теоретически все то же самое, только вместо слова «Footnotes» пишем «Endnotes». И тут наталкиваемся на сюрприз — почему-то оно считает неточно. Я в данном случае поступил так: сохраняю документ под другим именем, переконвертирую концевые сноски в обычные и далее все, как сказано выше. Сохранение документа:

    где в скобках стоят два параметра типа OleVariant — имя файла и шестнадцатеричная константа, задающая формат файла. Некоторые константы:

    Шестнадцатеричная Символьное обозначение Смысл
    $00000000 wdFormatDocument Документ Word
    $00000004 wdFormatDOSText Простой текст
    $00000006 wdFormatRTF Файл RTF

    Полный список констант формата можно найти все в том же файле Word2000.pas. И еще один интересный момент — если просто поставить в скобки обе константы, работать не будет. Следует предварительно объявить две переменных, присвоить им соответствующие значения и только потом сохранять.

    Ну, а теперь, собственно, можем вернуться к сноскам. Конвертирование концевых сносок в обычные происходит так:

    Теперь мы имеем документ, в котором содержатся только обычные сноски. С ними никаких проблем не возникает, пример, как с ними работать, см. выше. Если интересует статистика отдельно разных типов сносок, считаем предварительно статистику обычных сносок, сохраняем ее в «буферных» переменных и считаем еще раз после конвертирования. Разница даст статистику концевых сносок по отдельности. Сложив статистику сносок и простого текста, получаем статистику документа с учетом сносок так, как ее дает сам Word.

    Колонтитулы.

    Тут по традиции несколько покритикуем Microsoft. Как оказалось, Word показывает не все, что содержится в документе. Не принимаются в расчет колонтитулы. А ведь в них может содержаться изрядный кусок текста, особенно в справках, бланках и т.п. Оказывается, Word их на самом деле считает, но нам не показывает. Вот и посмотрим, как же его можно заставить это сделать.

    Колонтитулы в документе тесно связаны с несколько загадочной штукой под названием «разделы» — Sections. Каждый раздел может иметь верхние и нижние колонтитулы. Потому первым делом определяем количество абзацев.

    Здесь у нас целые переменные isectct, icofct, icohct обозначают соответственно количество разделов как таковых, количество нижних и верхних колонтитулов данного раздела. Переменная isec служит «номером» раздела, переменные icof, icoh «нумеруют» соответственно нижние и верхние колонтитулы в пределах данного раздела. Количество колонтитулов в разделе определяем так:

    Теперь уже можем «достать» текст из колонтитула:

    В данном случае мы для примера посчитали число слов, содержащихся в нижнем колонтитуле под номером icof, принадлежащем разделу под номером isec. Теперь можем написать «двойной» цикл для подсчета статистики верхних и нижних колонтитулов. Полностью это будет выглядеть так:

    isectct:=WordDocument1.DefaultInterface.Sections.Count;
    for isec:=1 to isectct do begin

    for icof:=1 to icofct do begin
    CBWCount:=CBWCount+
    WordDocument1.DefaultInterface.Sections.Item(isec).Footers.Item(icof).Range.ComputeStatistics($00000000);
    CBCCount:=CBCCount+
    WordDocument1.DefaultInterface.Sections.Item(isec).Footers.Item(icof).Range.ComputeStatistics($00000003);
    CBSCount:=CBSCount+
    WordDocument1.DefaultInterface.Sections.Item(isec).Footers.Item(icof).Range.ComputeStatistics($00000005);
    end;

    for icoh:=1 to icohct do begin
    CHWCount:=CHWCount+
    WordDocument1.DefaultInterface.Sections.Item(isec).Headers.Item(icoh).Range.ComputeStatistics($00000000);
    CHCCount:=CHCCount+
    WordDocument1.DefaultInterface.Sections.Item(isec).Headers.Item(icoh).Range.ComputeStatistics($00000003);
    CHSCount:=CHSCount+
    WordDocument1.DefaultInterface.Sections.Item(isec).Headers.Item(icoh).Range.ComputeStatistics($00000005);
    end;

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

    Часто использующиеся для рисования схемок текстовые вставки с панели рисования также представляют интерес. Сам Word формально считает их «картинками», не имеющими никакой статистики — видимо, по географическому расположению в панели инструментов. В объектной модели — Shapes. Вот тут начинается самое интересное. Во-первых, все, что находится на панели рисования, является Shapes. То есть в принципе для Word’а все едино, текстовая вставка, объект WordArt или геометрическая фигура. Вместе с тем смотрится довольно нелогично, что этот самый Shape можно переконвертировать, на выбор, во Frame или InlineShape. Они уже обладают статистикой, так что, казалось бы, все в порядке. Но коварству Microsoft, кажется, вообще нет предела. Во-первых с удивлением обнаруживаем, что Shapes нумеруются индексом типа OleVariant. Что с ним дальше делать, неясно. Если просто присваивать индексу целое число, при конвертации каждого второго Shape во Frame получаем ошибку. А если обработать исключение, то будем таки иметь статистику половины вставок. Видимо, есть какие-то тонкости с четными и нечетными индексами. Во-вторых, InlineShape штука и вовсе загадочная. Никаких ошибок при конвертации не возникало, но и количество InlineShapes неизменно оказывалось нулевым. Подсчитать статистику вставок удалось только сохранив файл как RTF и расковыряв его код, но это стоит описать отдельно. Приводился же последний абзац в надежде, что кто-то с таким сталкивался и нашел способ работы с Shapes «встроенными» способами.

    Ну, вот практически и все. Суммируя все, что мы получили, имеем статистику документа даже точнее встроенной. Еще пара замечаний. Перед подсчетом Word стоит «спрятать», чтобы он не маячил на экране:

    При подсчете статистики, особенно если в документе содержится что-то кроме простого текста, считается, что в файл внесены изменения. Потому напоследок сохраняем и закрываем документ:

    Ну и, конечно, делаем серверу Word Disconnect, когда он станет нам уже не нужен.

    А теперь предупреждение тем, кто заинтересовался данным вопросом и хочет поэкспериментировать сам. Офис слишком тесно связан с Windows, потому на сбои в его работе система реагирует крайне остро. При отладке программ подсчета статистики у меня после ошибки часто появлялся «голубой экран». То же самое происходило, если после разбора RTF — файла в поисках Shapes и превращения их в обычный текст в Word загружался неправильно «собранный» файл. Так что очень рекомендуется предварительно сохранить важные данные или поставить систему понадежнее. У меня стоит WindowsXP, который к таким сбоям оказался нечуствителен. Кроме того, пока приведенное здесь не было отлажено, после ошибок частенько летел сам офис. Так что имейте под рукой дистрибутив для запуска диагностики офиса и устранения повреждений.

    Часть 3. Открытие документа используя VCL.

    Каждый, наверное, хоть раз сталкивался с необходимостью выдачи отчета. В Delphi имеются для этого специальные компоненты, но они налагают на нас достаточно строгие ограничения на форму представления данных. Одним из выходов может служить использование программы MS Word. Здесь не будем подробно обсуждать простейший вопрос, как открыть документ и добавить в него нужную строку текста, это есть практически в каждом учебнике по Delphi, приведем только самые необходимые сведения. А из литературы на эту тему особенно рекомендуется найти книжку А.Я. Архангельского «Язык SQL в Delphi 5». Но что может придать отчету такую читабельность, как представление результатов в систематизированном табличном виде? В данной статье и обсуждается вопрос программной работы с таблицами документа Word.

    Тут могут быть два пути. Первый — если мы знаем заранее структуру данных отчета, можем приготовить шаблон, куда в ячейки таблицы затем просто занесем нужные данные. И второй — создаем отчет с нуля, рисуем в документе таблицу, заполняем ее. При этом мы можем программно добавить или удалить строки и столбцы, объединить или разбить ячейки — почти все, что мы делаем в самом Word’e. Все, что понадобится — компоненты WordApplication и WordDocument с палитры Servers.

    Теперь все по порядку — открываем файл и приступаем. Предварительно объявляем переменную FileName, типа OleVariant, которой присваиваем строку с именем файла.

    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 не тратил время понапрасну:

    По окончании работы нам надо сохранить или распечатать наш отчет:

    где переменная в скобках типа OleVariant, ей присваиваем строку с именем файла.

    Объект Range.

    В документе нас пока больше всего интересует объект Range, который нам понадобится при создании таблицы. Он представляет из себя кусок текста, который может включать в себя как весь текст документа, так и любую его часть. То есть:

    Первый наш объект включает в себя весь текст документа, у второго мы ограничили пределы 5-м и 15-м символами, третий представляет из себя весь последующий текст документа, начиная с 5-го символа. Объект имеет несколько полезных методов, например, с его помощью можем добавить текст в документ:

    Это мы вставили текст после выделенного Range. Точно также можем вставить текст и перед ним, для этого служит метод InsertBefore(). Текст, заключенный в объекте Range, можем получить так:

    Кроме того, с помощью Range можем изменить шрифт в пределах объекта. Пример:

    Если хотим отменить выделение жирным шрифтом, присваиваем 0. Аналогично можно сделать шрифт курсивом, подчеркнутым — наберите WordDocument1.Range.Font., и среда сама подскажет, какие могут быть варианты. Методы Select, Cut, Copy и Paste работают как в обычном тексте. С помощью Paste можем на место выбранного Range вставить не только строки, но и рисунок, находящийся в буфере обмена.

    Часть 4. Работа с таблицами.
    Работа со столбцами, строками и ячейками.

    Таблицы в документе Word образуют коллекцию Tables. Их количество можем узнать так:

    к отдельной таблице обращаемся по ее номеру:

    где i — целое число. В данном случае мы обращаемся к первой таблице, а вообще i может принимать значения от 1 до WordDocument1.Tables.Count. Если нам необходимо создать таблицу самим, следует поступить так:

    Эта таблица — единственное, что будет в документе, так как она заменяет собой указанный в числе параметров объект Range. В данном случае получаем таблицу на i строк и j столбцов. Если уже еcть какой-то текст, который надо сохранить, совершенно аналогичным образом можем указать пределы объекта Range:

    Переменные a и b должны быть объявлены как OleVariant.

    Ну вот, теперь у нас есть таблица. Неважно, содержалась она уже в документе или мы создали ее сами. Посмотрим, что же мы с ней можем сделать. Число столбцов и строк узнаем так:

    Здесь мы опять обратились к первой таблице, но можем работать с любой — надо только правильно указать ее номер. Теперь изменим ширину столбцов или высоту строк:

    Аналогично можем задавать размеры отдельных строк и столбцов:

    Здесь j — опять таки целое число, начинается от 1. Можем обратится к отдельной ячейке, прочитать или изменить содержащийся в ней текст:

    Здесь j и k целые переменные, изменяются от 1 до числа строк или столбцов соответственно. Присвоив данной величине строковое выражение, увидим, что оно появилось в ячейке (j,k). Несколько непривычно, но в таблицах Word на первом месте стоит именно номер строки. Можем также задать программно отступы от края ячеек, как для всей таблицы сразу, так и для отдельной ячейки:

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

    Кроме того, можем подогнать размеры ячеек по содержимому. Для этого вызываем метод AutoFit:

    Добавить строку или столбец также не представляет сложностей:

    Мы добавили строку внизу и столбец справа. Теперь вставим столбец в определенном месте таблицы:

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

    Теперь про объединение ячеек. Довольно просто:

    Мы объединили две соседние по горизонтали ячейки (j,k) и (j,k+1). При этом получается, что большая ячейка как бы имеет два «адреса». Аналогично надо действовать и при объединении по вертикали. Все точно так же, но с нумерацией ячеек после объединения двух соседних по вертикали начинается путаница и при попытке заполнить таблицу возникают ошибки.

    Теперь разобьем ячейки.

    Здесь мы разбили ячейку (j,k) на две по горизонтали. Переменные varcol и varrow типа OleVariant, это количество столбцов и строк, на которые разбивается данная ячейка. Здесь снова с нумерацией начинается чехарда, так что этот вопрос разбиения и объединения ячеек представляет скорее чисто теоретический интерес. В таких случаях лучше заранее приготовить шаблоны.

    Теперь для примера удалим из таблицы второй столбец или третью строку:

    Внешний вид таблицы.


    Простейшая таблица, конечно, смотрится не очень. Теперь посмотрим, как мы можем ее приукрасить. При желании все сделать посимпатичнее можем использовать текстуру. Выглядеть это будет так:

    Совершенно аналогично можем сделать текстуру в целом столбце или строке:

    Текстура задается шестнадцатеричной константой, список констант можно найти заголовочном файле Word2000.pas. Можно их использовать как в шестнадцатеричном, так и в символьном виде. Чтобы не загромождать материал, значения констант будут выноситься в «Приложение» в конце статьи. Сразу оговорюсь, что заливка будет черно-белая или в шкале серого. Заливку определенным цветом пока так и не удалось обнаружить. Самая первая константа означает отсутствие заливки. Ее можно использовать, чтобы отменить текстуру.

    Чтобы выделить что-нибудь важное, можем изменить шрифт текста в определенной ячейке. Для этого воспользуемся свойствами объекта Selection:

    В данном примере мы сделали цвет текста в ячейке (1,2) красным, выделили его курсивом и изменили размер на 16. Кроме того, можем сделать шрифт подчеркнутым, перечеркнутым и т.п.

    Еще один способ изменить внешний вид таблицы — использовать стилевые шаблоны Word’a. У таблицы имеется метод AutoFormat, который меняет внешний вид таблицы в соответствии с некими предопределенными стилями. В заголовочном файле он описан следующим образом:

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

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

    И еще об одном способе создания таблиц.

    Людям, интересующимся работой с MS Word, возможно, тоже попадались в интернете компоненты, превращающие в таблицу соответствующим образом отформатированный текст. Вот мы как раз и разберемся, как же они устроены. Здесь нам опять надо вспомнить про объект Range, а именно про имеющийся у него метод ConvertToTable. В заголовочном файле это выглядит так:

    Здесь опять видим все те же константы применения стиля, что и в автоформате. Только в отличие от него тут они ошибок не вызывают. Правда, есть у меня жуткое подозрение, что они все равно не работают и можем со спокойной совестью поставить вместо них «пустышки» — всех, кроме опять-таки, первых двух параметров «применения изменений». Теперь по порядку. Первый параметр у нас задает символ, которым будут отделяться ячейки одной строки нашей будущей таблицы, второй — число строк таблицы, третий — число столбцов, затем идет ширина столбцов. Следующая группа параметров задает стиль таблицы и особенности его применения, необходимые значения констант есть в таблице «Приложения». Последние три параметра задают подгонку размера ячеек по содержимому, но на самом деле не работают. Так что ставим вместо них EmptyParam. И, наконец, практический пример. Предположим, мы открыли новый документ и занесли в него нужный текст:

    Такую операцию повторим трижды, и у нас будет заготовка для таблицы на 4 столбца и 3 строки. Будущие столбцы отделяются символами табуляции, а строки — переходами на новую строку. Теперь выделяем объект Range — в данном случае это весь текст документа, и превращаем его в таблицу:

    var tsepar, tnumrows, tnumcols, tincolw, tformat,
    tappbrd, tappshd, tappfnt, tappclr, tapphr, tapplr,
    tappfc, tapplc: OleVariant;
    .
    tsepar:=wdSeparateByTabs;
    tnumrows:=3;
    tnumcols:=4;
    tincolw:=150;
    tformat:=wdTableFormatNone;
    tappbrd:=wdTableFormatApplyBorders;
    tappshd:=wdTableFormatApplyShading;
    tappfnt:=wdTableFormatApplyFont;
    tappclr:=wdTableFormatApplyColor;
    tapphr:=wdTableFormatApplyHeadingRows;
    tapplr:=wdTableFormatApplyLastRow;
    tappfc:=wdTableFormatApplyFirstColumn;
    tapplc:=wdTableFormatApplyLastColumn;

    WordDocument1.Range.ConvertToTable(tsepar, tnumrows, tnumcols, tincolw, tformat,
    tappbrd, tappshd, tappfnt, tappclr, tapphr, tapplr,
    tappfc, tapplc, EmptyParam, EmptyParam, EmptyParam);

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

    Проделав все это, обнаруживаем, что наш текст превратился в таблицу. Все это несколько напоминает создание таблиц в HTML.

    Список некоторых констант.

    Смотрите файл Word2000.pas

    Описание Символьное обозначение Шестнадцатеричное
    Текстуры
    Некоторые константы текстур — откройте Word2000.pas в «блокноте», введите в диалог поиска «texture», и получите полный список.
    wdTextureNone $00000000
    wdTexture2Pt5Percent $00000019
    wdTexture7Pt5Percent $0000004B
    wdTexture35Percent $0000015E
    wdTexture62Pt5Percent $00000271
    wdTextureSolid $000003E8
    wdTextureDarkHorizontal $FFFFFFFF
    wdTextureCross $FFFFFFF5
    Формат таблицы
    Константы формата таблицы. Необходимы при использовании автоформата и преобразовании текста в таблицу.
    wdTableFormatNone $00000000
    wdTableFormatSimple1 $00000001
    wdTableFormatSimple3 $00000003
    wdTableFormatClassic1 $00000004
    wdTableFormatClassic3 $00000006
    wdTableFormatColorful1 $00000008
    wdTableFormatColumns1 $0000000B
    wdTableFormatGrid1 $00000010
    wdTableFormatGrid3 $00000012
    wdTableFormatList1 $00000018
    wdTableFormat3DEffects1 $00000020
    wdTableFormat3DEffects2 $00000021
    wdTableFormat3DEffects3 $00000022
    wdTableFormatContemporary $00000023
    wdTableFormatElegant $00000024
    wdTableFormatProfessional $00000025
    wdTableFormatSubtle1 $00000026
    wdTableFormatWeb3 $0000002A
    Стили таблицы
    Константы «применения изменений» стиля таблицы. В идеале предполагается, что можно задавать отдельно, изменять ли стиль границ, текста, цвета и т.д. В автоформате работают, мягко выражаясь, невразумительно, все время возникают какие-то непонятные ошибки.
    wdTableFormatApplyBorders $00000001
    wdTableFormatApplyShading $00000002
    wdTableFormatApplyFont $00000004
    wdTableFormatApplyColor $00000008
    wdTableFormatApplyAutoFit $00000010
    wdTableFormatApplyHeadingRows $00000020
    wdTableFormatApplyLastRow $00000040
    wdTableFormatApplyFirstColumn $00000080
    wdTableFormatApplyLastColumn $00000100
    Разделители
    Константы разделителей для конвертации текста в таблицу.
    wdSeparateByParagraphs $00000000
    wdSeparateByTabs $00000001
    wdSeparateByCommas $00000002
    wdSeparateByDefaultListSeparator $00000003

    Часть 5. Работа с текстом, рисунками и списками.
    Текст.

    Сначала о самом простом — добавлении в документ Word нужной строки текста. Поместим на форму компоненты WordDocument, WordApplication и WordParagraphFormat с палитры Servers. Нас интересуют в первую очередь свойство Range компонента WordDocument и свойство Selection компонента WordApplication. Классики утверждают, что они являются ссылкой на объекты Range и Selection. Range представляет из себя, проще говоря, кусок текста, это может быть как весь текст документа, так и любая его часть. Его пределы задаются двумя (или меньше) параметрами типа OleVariant. Например:

    Илон Маск рекомендует:  Что такое код cpdf_rotate_text

    Первый наш объект включает в себя весь текст документа, у второго мы ограничили пределы 5-м и 15-м символами, третий представляет из себя весь последующий текст документа, начиная с 5-го символа. Объект имеет несколько полезных методов, например, с его помощью можем добавить текст в документ:

    Это мы вставили текст после выделенного Range. Точно также можем вставить текст и перед ним, для этого служит метод InsertBefore(). Текст, заключенный в объекте Range, можем получить так:

    Кроме того, с помощью Range можем изменить шрифт в пределах объекта. Пример:

    Если хотим отменить выделение жирным шрифтом, присваиваем 0. Аналогично можно сделать шрифт курсивом, подчеркнутым — наберите WordDocument1.Range.Font., и среда сама подскажет, какие могут быть варианты. Методы Select, Cut, Copy и Paste работают как в обычном тексте. С помощью Paste можем на место выбранного Range вставить не только строки, но и рисунок, находящийся в буфере обмена.

    С помощью Range можем найти в документе нужную строку. Пусть в тексте содержится слово «picture». Например, нам на его место надо будет вставить рисунок.

    Такая процедура находит и выделяет нужный кусок текста.

    Теперь про Selection, представляющий из себя выделенный фрагмент документа. Если выделения нет, это текущая позиция курсора в документе. С его помощью можем вставить что-либо на место выделенного фрагмента, сделать выравнивание, изменить шрифт. Он также имеет методы InsertAfter() и InsertBefore():

    Форматирование выделенного текста происходит аналогично Range, например:

    Для выравнивания проще воспользоваться компонентом WordParagraphFormat. Сначала только нужно «подключить» его к выделенному фрагменту текста:

    Значения его свойства Alignment может принимать значения wdAlignParagraphCenter, wdAlignParagraphLeft, wdAlignParagraphRight, смысл которых очевиден. Имеются и методы Cut, Copy и Paste, которые в пояснениях вряд ли нуждаются:

    Убираем выделение с помощью метода Collapse. При этом необходимо указать, в какую сторону сместится курсор, будет ли он до ранее выделенного фрагмента или после:

    При этом выделение пропадет, а курсор займет позицию перед фрагментом текста. Если присвоить переменной значение wdCollapseEnd, то курсор переместится назад. Можно просто поставить в скобках «пустышку»:

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

    Рисунки.

    Логично было бы предположить, что рисунки документа будут представлять из себя коллекцию, аналогичную таблицам, и мы, обратившись к конкретной картинке, сможем менять ее свойства — обтекание, размер и т.д. Однако ничего подобного в WordDocument не обнаруживается. Потому возможности управления встраиваемыми в документ изображениями сильно ограничены.

    Простейший метод вставить в документ рисунок — по упомянутым причинам он же и единственный — скопировать его в Word из буфера обмена. Предположим, рисунок у нас находится в компоненте DBImage. Сначала нужно загнать его в буфер обмена:

    Теперь для его вставки следует воспользоваться методом Paste объектов Range или Selection: WordApplication1.Selection.Paste или WordDocument1.Range(a,b).Paste. Оставить для рисунка достаточное количество пустых строк и попасть в нужное место — это уже наша забота. Если он попадет посреди текста, вид будет довольно противный — при такой вставке обтекание текстом рисунка происходит как-то странно. Можно приготовить для отчета шаблон, где заменяем рисунком какое-либо ключевое слово. О том, как найти в документе нужный текст, см. выше.

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

    «Рамки» образуют коллекцию Frames, нумеруются целым индексом, пробегающим значения от 1 до WordDocument1.Frames.Count. Добавим в документ рамку, изменим ее размер и вставим рисунок:

    Здесь для простоты предполагается, что размер DBImage равен размеру самой картинки, а также что до этого рамок у нас в документе не было. Обратить внимание следует на несколько моментов. Размер рамки надо задавать до того, как копировать в нее рисунок. Иначе она будет иметь размер по умолчанию, под который замасштабируется и наша картинка. При попытке изменить размер рамки задним числом размер картинки уже не изменится. Кроме того, параметр Range при добавлении рамки часто никакой роли не играет. Рамка изначально все равно появится в левом верхнем углу документа, а указанный кусок текста при этом не пострадает. Но это только в том случае, если он не выделен. Если в документе есть выделение, рамка появится вместо выделенного фрагмента. Таким образом можем ее вставить в нужное место взамен какого-то ключевого слова.

    При желании можем ее подвигать в документе и «вручную». Для этого служат свойства горизонтального и вертикального позиционирования, которые задают ее отступ от левого верхнего «угла» документа:

    Отступ между краями рамки и текстом задается следующим образом:

    А теперь о масштабировании. Для этого достаточно длину и ширину рамки умножить на одно и то же число. Например:

    При этом наша картинка в полтора раза пропорционально растянется. Точно также можно и уменьшить, но делить, как и множить, следует на одно число. Растягивать длину и ширину по-разному у меня лично не получалось. Задавать размер опять-таки надо еще до вставки рисунка. Ну и, наконец, удаление рамки:

    Списки.

    Списки в документе образуют коллекцию Lists, к отдельному списку обращаемся WordDocument1.Lists.Item(i), где i целое число от 1 до WordDocument1.Lists.Count . на этом все. Нет методов, позволяющих не то что создать новый список, а даже добавить пункт к уже существующему. Ничего страшного, настоящие герои всегда идут в обход:)) Сейчас мы все же проделаем и то, и другое. Все что нам понадобится — свойство Range отдельного списка, то есть его текст без разделения на пункты, а также возможность его выделить:

    Для этого в любом случае потребуется заготовка. Неважно, вставлена она в общий шаблонный документ или хранится в отдельном файле. Заготовку делаем так: выбираем в меню Формат/Список, и сохраняем, если это отдельный шаблон списка. У нас появляется пустой список без текста с одним маркером. Далее вспоминаем, как мы делали списки вручную — писали текст, нажимали «Enter», появлялся новый элемент списка. Теперь то же самое, только программно. Предположим, у нас уже открыт документ с заготовкой, и мы хотим внести в список пункты «Item 1» и «Item 2»:

    То есть мы вставляем в документ текст первого пункта списка, он попадает на свое место. Потом посылаем в Word символ перехода строки, он честно переходит и тем самым сам создает нам второй пункт списка, куда и вставляем нужную строку. Ну и так далее, нужное количество раз. Последние две строки нужны, если список заготовлен в отдельном файле — после их выполнения список оказывается в буфере обмена. Здесь выгода в том, что можем иметь заготовки списков разных стилей и по ходу дела выбирать, какой список создать. Затем открываем документ, где должен быть список, выделяем с помощью Range нужный кусок, копируем из буфера обмена через WordDocument1.Range(a,b).Paste. Чтобы не испортить файл с заготовкой, можем сразу после открытия пересохранить его под другим именем, а можем просто выйти из него без сохранения изменений:

    Константа сохранения изменений может принимать значения

    Шестнадцатеричная Символьное обозначение
    $FFFFFFFF wdSaveChanges
    $00000000 wdDoNotSaveChanges
    $FFFFFFFE wdPromptToSaveChanges

    Первое значение сохраняет изменения, второе дает возможность выйти без сохранения изменений. Последняя константа вызывает при выходе стандартный диалог сохранения изменений. Можем сделать и несколько по-другому. Хотя мы не можем создать новый элемент списка, но текст в уже существующем изменить можно:

    Так что можно с помощью переходов строки создать нужное количество элементов, а затем их заполнить:

    Это было в предположении, что у нас один элемент списка в заготовке уже есть. Ну вот, в общем-то, и все про текст, списки и картинки.

    Статья добавлена: 9 мая 2006

    Зарегистрируйтесь/авторизируйтесь,
    чтобы оценивать статьи.

    Статьи, похожие по тематике

    Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:

    Ссылка для форумов (BBCode):

    Быстрая вставка ссылки на статью в сообщениях на сайте:
    <> (буква a — латинская) — только адрес статьи (URL);
    <<статья:11>> — полноценная HTML-ссылка на статью (текст ссылки — название статьи).

    Поделитесь ссылкой в социальных сетях:

    Комментарии читателей к данной статье

    Пока нет комментариев к данной статье. Оставьте свой и он будет первым.

    Оставлять комментарии к статьям могут только зарегистрированные пользователи.

    Пример работы с Word через OLE. Часть 2. Редко используемые элементы.

    Не ленитесь ставить плюсики. Вам все равно — а мне приятно, и повергает еще что-нибудь полезное написать.

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

    Для отображения закладок включите эту опцию в настройках вашего Word’а.

    В моем примере я заранее создал новый пустой документ, путь к документу и картинке прописан в тексте. Не забудьте указать свои пути.

    Тестировалось на Office 2007.

    Частично текст повторяет предыдущий пример. Некоторые переменные переименованы по стандарту Office: Text Selection. Doc ThisDocument.

    Вот текст модуля:

    Процедура ВыполнитьОбработку () Экспорт

    //Объект = ПолучитьCOMОбъект(ПутьКФайлу);
    Объект = ПолучитьCOMОбъект ( «C:\Users\NKrylov\Desktop\Тест.docx» );
    // Покажем документ.
    Объект . Application . Visible = 1 ;
    Word = Объект . Application ;

    ThisDocument = Word . Documents ( 1 );
    ThisDocument . Activate ();

    // Отключим проверку грамматики и вывод информации о грамматических ошибках.
    ThisDocument . GrammarChecked = 0 ;
    ThisDocument . ShowGrammaticalErrors = 0 ;

    // Готовим переменную в которой будет содержимое документа (текст).
    Selection = Word . Selection ;

    // Очистим документ
    // Ctrl-A
    Selection . WholeStory ();
    // Del
    Selection . Delete ( 1 , 1 );

    // Уменьшим междустрочный интервал.
    Selection . ParagraphFormat . LineSpacingRule = 0 ; // 1 по умолчанию
    Selection . ParagraphFormat . SpaceAfter = 0 ; // 10 по умолчанию

    // Разметим документ. Это можно сделать и предварительно в макете
    ThisDocument . Bookmarks . Add ( «Закладка1» , Selection . Range ());
    Selection . TypeParagraph ();
    Selection . TypeText ( «34r3 » );
    Selection . HomeKey (, 1 );
    ThisDocument . Bookmarks . Add ( «Закладка2» , Selection . Range ());
    Selection . EndKey ();
    Selection . TypeParagraph ();
    ThisDocument . Bookmarks . Add ( «Закладка3» , Selection . Range ());
    Selection . TypeParagraph ();
    ThisDocument . Bookmarks . Add ( «Закладка4» , Selection . Range ());
    Selection . EndKey ();

    // Так можно работать с текстом только в конкреной области документа — это и будет замена метода Find-Execute.
    ThisDocument . Bookmarks ( «Закладка3» ). Range . Select ();
    Selection = Word . Selection ;

    Bookmark = ThisDocument . Bookmarks ( «Закладка3» );
    Table = ThisDocument . Tables . Add ( Bookmark . Range (), 1 , 5 , 1 , 2 );
    Table . Rows ( 1 ). Cells ( 1 ). Range . Text = 1 ;
    Table . Rows ( 1 ). Cells ( 2 ). Range . Text = 2 ;
    Table . Rows ( 1 ). Cells ( 3 ). Range . Text = 3 ;
    Table . Rows ( 1 ). Cells ( 4 ). Range . Text = 4 ;
    Table . Rows ( 1 ). Cells ( 5 ). Range . Text = 5 ;


    // После вывода таблицы, появится «лишняя строка», удалим ее
    // в результате курсор встанет в область закладки 4
    Selection . MoveDown (, 1 );
    Selection . Delete ( 1 , 1 );

    // Этот текст будет выведен не с последней позиции курсора, а в активной области.
    // в данном случае — в области закладки 2
    ThisDocument . Bookmarks ( «Закладка2» ). Range . Select ();
    Selection = Word . Selection ;
    Text = Selection . Range . Text ;
    Selection . TypeText ( Text + » sdcsdcs» );
    // При выводе текста закладка «сбросилась». Восстановим.
    // «Победить» эту проблему я так и не смог((
    // Хотя на практике, закладка больше и не понадобится.
    // Дважды выводить текст в одну и ту же область — не имеет смысла.
    Selection . HomeKey (, 1 );
    ThisDocument . Bookmarks . Add ( «Закладка2» , Selection . Range ());
    Selection . EndKey ();

    // В области закладки 4 сформируем нумерованный список
    ThisDocument . Bookmarks ( «Закладка4» ). Range . Select ();
    Selection = Word . Selection ; // активная (выделенная) область будет начинаться
    // от закладки 4)

    // Добавим текст «для опытов»
    // 1
    Selection . TypeText ( «sdcsdcsdcsdc» );
    Selection . TypeParagraph ();
    // 2
    Selection . TypeText ( «sdcsdcsdcsdc» );
    Selection . TypeParagraph ();
    // 3
    Selection . TypeText ( «sdcsdcsdcsdc» );
    Selection . TypeParagraph ();
    // 4
    Selection . TypeText ( «sdcsdcsdcsdc» );
    Selection . TypeParagraph ();
    // Выделяем введенный текст
    Selection . MoveUp (, 4 , 1 );

    // Настроим шаблон объекта галереи списков
    // Галереи списков бывают несккольких типов, 2 — нумерованные списки
    ListTemplate = Word . ListGalleries ( 2 ). ListTemplates ( 1 ). ListLevels ( 1 );
    // Формат нумератора списка — точка после символа нумерации
    ListTemplate . NumberFormat = «%1.» ;
    // стиль нумератора — арабские цифры
    ListTemplate . NumberStyle = 0 ; // wdListNumberStyleArabic
    // 4 — маленькие латинские буквы.
    // 2 — маленькие римские цифры.
    // 58- меленькие русские буквы.
    // Font = Template.Font; // можно указать форматирование текста списка

    // Применим шаблон к выделенному тексту
    Selection . Range . ListFormat . ApplyListTemplateWithLevel ( Word . ListGalleries ( 2 ). ListTemplates ( 1 ));

    // Перейдем в конец текста
    Selection . EndKey ( 6 );

    // Добавим картинку
    // Параметры: путь к файлу, создавать ссылку на картинку, сохранять с файлом
    Picture = Selection . InlineShapes . AddPicture ( «C:\Users\NKrylov\Desktop\Новый.bmp» , Ложь, Истина);
    // Зададим размер
    Picture . Height = 100 ;
    Picture . W >= 150 ;

    // Чтобы установить обтекание текста, конвертируем рисунок в фигуру
    Shape = Picture . ConvertToShape ();
    Shape . WrapFormat . Type = 0 ; // по контуру.

    Использование OLE-объектов в документах Microsoft Word как средство распространения вредоносных программ. Методы защиты от них

    Рубрика: Информационные технологии

    Дата публикации: 21.12.2020 2020-12-21

    Статья просмотрена: 1589 раз

    Библиографическое описание:

    Рудниченко А. К., Кошелев С. О. Использование OLE-объектов в документах Microsoft Word как средство распространения вредоносных программ. Методы защиты от них // Молодой ученый. — 2020. — №29. — С. 36-38. — URL https://moluch.ru/archive/133/37122/ (дата обращения: 12.11.2020).

    В данной статье рассказывается, что такое OLE интерфейс, его простейшее применение. Также рассматривается, как с помощью него распространяются вредоносные программы в виде документов Microsoft Word на различные предприятия. Предлагается список мер, которые помогут уменьшить риск получения заражённого файла на компьютеры организации.

    Ключевые слова: Microsoft Office, Word, OLE интерфейс, OLE объекты, информационная безопасность, вредоносные программы

    В настоящее время в мире существует множество программ, разработчики которых относят свои продукты к разряду офисных. Наибольшую популярность набрал Microsoft Office. Самым массовым продуктом из этого набора является Microsoft Word. Им пользуются практически все как на домашних компьютерах, так и на компьютерах на предприятиях.

    Microsoft Word (MS Word) — многофункциональная система обработки текстов, обладающая полным набором средств, необходимых для быстрого создания и эффективной обработки документов практически любой степени сложности. Но на редактировании текста его функционал не ограничивается. Расширяются возможности офисных программ семейства Microsoft с помощью различных дополнений, таких как Visual Basic для приложений, OLE объекты, ActiveX объекты и другие. Таким образом, MS Word — не только текстовый редактор, а ещё средство для выполнения самых разных алгоритмов, написанных на Visual Basic или запуска и связывания с документом различных программ.

    Интерфейс OLE (Object Linking and Embedding — связывание и внедрение объектов) поддерживается множеством различных программ и используется для помещения документа, созданного в одной программе, в другую программу. Например, можно вставить документ MS Word в книгу MS Excel. Задача интерфейса OLE проста — создание промежуточного звена между программами для упрощения работы с различным программным обеспечением, поэтому OLE чаще всего используется тогда, когда обрабатываются составные документы с различными между собой системами. В данный момент OLE интерфейс используется в виде OLE объектов, которые зачастую представляют собой различные мультимедийные данные.

    Алгоритм вставки объекта, который содержит ссылку на содержимое из другой программы очень прост:

    1. Открыть MS Word и определить место, где будет помещён OLE объект;
    2. На вкладке «Вставка» в группе «Текст» щёлкнуть «Объект»;
    3. Открыть вкладку «Создание из файла»;
    4. В поле «Имя файла» ввести имя файла или нажать кнопку «Обзор» для выбора файла из списка.

    Существует два режима вставки объектов:

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

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

    В качестве OLE объекта может быть вставлен не только документ из линейки продукта Microsoft Office. Например, возможно вставить ссылку на простейший текстовый документ, изображение или PDF-документ. Особое внимание стоит уделить тому, что функционал OLE интерфейса позволяет вставлять таким же образом и исполняемые файлы, которые могут нанести вред операционной системе или отдельным файлам.

    Таким образом, OLE объект и сам документ, созданный в Microsoft Word, может содержать в себе вредоносный код, который не будет детектироваться антивирусным программным обеспечением. Отсутствие каких-либо замечаний со стороны защищающих программ обуславливается тем, что вредоносный код создан полностью легальными средствами, а также потому что конечным результатом является документ формата «*.doс» или «*.docx» соответственно.

    Вредоносный код, содержащийся в OLE объекте, выполняется не сразу. Для запуска исполняемого файла из документа MS Word необходимо кликнуть два раза по вставленному объекту. На данном этапе злоумышленники пытаются доказать жертве отсутствие подозрительного контента: рисунок стандартного объекта заменяется на изображение какой-либо таблицы, а над ней пишется просьба о том, что необходимо кликнуть на таблицу дважды (например, «Для просмотра таблицы кликните дважды на таблицу»). Для запуска исполняемого файла пользователь должен согласиться с запуском в вполне стандартном окне запуска. Пример вредоносного документа с OLE объектом представлен на рисунке 1.

    Рис. 1. Демонстрация вредоносного документа с OLE объектом

    Для убедительности такие документы с вредоносным кодом посылаются по электронной почте под видом письма от государственных органов (например, налоговой службы) с помощью замены заголовка письма. Таким образом, сотрудник, открывающий письмо, не видит настоящего адреса отправителя. Он замаскирован (например, под noreply@nalog.ru), и визуально определить, настоящий это адрес или изменённый заголовок, зачастую невозможно.

    В рамках любого предприятия неосведомлённые сотрудники могут пропустить предупреждение об открытии исполнительного файла, так как оно выглядит стандартно и пользователем нарочно пропускается в силу привычного интерфейса окна. Формату Microsoft Word чаще всего доверяют и не подозревают от него никакой вредоносной активности, что «играет на руку» злоумышленникам. Исходя из этого, шанс того, что сотрудник организации откроет документ и осуществит запуск вредоносного программного обеспечения, достаточно велик.

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

    – Использование аппаратных или программных средств защиты для фильтрации трафика электронной почты. Таким образом, письма с изменёнными заголовками будут отсеиваться или помечаться статусом «Подозрительно»;

    – Своевременное и регулярное обучение сотрудников организации, а также их информирование о сценариях заражения, так как распространение вредоносных документов допустимо и без использования электронной почты;

    – Использование относительно новой версии пакета Microsoft Office (2010 и выше). Последние версии данного продукта имеют в своём функционале «Защищённый просмотр», что уменьшает шанс того, что сотрудник откроет OLE объект. «Безопасный режим» позволяет открывать файлы и просматривать их в более безопасной среде (без использования макросов и дополнительных объектов).

    Таким образом, стандартные легитимные средства редактирования документов могут служить распространителями различных программ без ведома пользователей. OLE объекты — это относительно новая ветвь развития в сфере вредоносных программ для предприятий. В конце 2020 года в адрес некоторых организаций уже начинают поступать такие документы, так как они отлично подходят для «доставки» вирусов-шифровальщиков или других вредоносных программ на компьютер жертвы руками обычных пользователей. А отследить, откуда пришло письмо с загадочным документом, зачастую не предоставляется возможным.

    Delphi: работа с MS WORD (стр. 1 из 4)

    Delphi : работа с MS WORD

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

    Сначала о самом простом — добавлении в документ Word нужной строки текста. Поместим на форму компоненты WordDocument, WordApplicationи WordParagraphFormat с палитры Servers. Нас интересуют в первую очередь свойство Range компонента WordDocument и свойство Selection компонента WordApplication. Классики утверждают, что они являются ссылкой на объекты Range и Selection. Range представляет из себя, проще говоря, кусок текста, это может быть как весь текст документа, так и любая его часть. Его пределы задаются двумя (или меньше) параметрами типа OleVariant.

    var range1, range2, range3, a, b : OleVariant;

    Первый наш объект включает в себя весь текст документа, у второго мы ограничили пределы 5-м и 15-м символами, третий представляет из себя весь последующий текст документа, начиная с 5-го символа. Объект имеет несколько полезных методов, например, с его помощью можем добавить текст в документ:

    Это мы вставили текст после выделенного Range. Точно также можем вставить текст и перед ним, для этого служит метод InsertBefore(). Текст, заключенный в объекте Range, можем получить так:

    Кроме того, с помощью Range можем изменить шрифт в пределах объекта. Пример:

    Если хотим отменить выделение жирным шрифтом, присваиваем 0. Аналогично можно сделать шрифт курсивом, подчеркнутым — наберите WordDocument1.Range.Font., и среда сама подскажет, какие могут быть варианты. Методы Select, Cut, Copy и Paste работают как в обычном тексте. С помощью Paste можем на место выбранного Range вставить не только строки, но и рисунок, находящийся в буфере обмена.

    С помощью Range можем найти в документе нужную строку. Пусть в тексте содержится слово «picture». Например, нам на его место надо будет вставить рисунок.

    vara, b, vstart, vend: OleVariant;

    j, ilengy: Integer;

    for j:=0 to ilengy-8 do begin

    if WordDocument1.Range(a,b).Text=’picture’ then begin

    Такая процедура находит и выделяет нужный кусок текста.

    Теперь про Selection, представляющий из себя выделенный фрагмент документа. Если выделения нет, это текущая позиция курсора в документе. С его помощью можем вставить что-либо на место выделенного фрагмента, сделать выравнивание, изменить шрифт. Онтакжеимеетметоды InsertAfter() и InsertBefore():

    Форматирование выделенного текста происходит аналогично Range, например:

    Для выравнивания проще воспользоваться компонентом WordParagraphFormat. Сначала только нужно «подключить» его к выделенному фрагменту текста:

    Значения его свойства Alignment может принимать значения wdAlignParagraphCenter, wdAlignParagraphLeft, wdAlignParagraphRight, смысл которых очевиден. Имеются и методы Cut, Copy и Paste, которые в пояснениях вряд ли нуждаются:

    УбираемвыделениеспомощьюметодаCollapse. При этом необходимо указать, в какую сторону сместится курсор, будет ли он до ранее выделенного фрагмента или после:

    var vcol: OleVariant;

    При этом выделение пропадет, а курсор займет позицию перед фрагментом текста. Если присвоить переменной значение wdCollapseEnd, то курсор переместится назад. Можно просто поставить в скобках «пустышку»:

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

    Логично было бы предположить, что рисунки документа будут представлять из себя коллекцию, аналогичную таблицам, и мы, обратившись к конкретной картинке, сможем менять ее свойства — обтекание, размер и т.д. Однако ничего подобного в WordDocument не обнаруживается. Потому возможности управления встраиваемыми в документ изображениями сильно ограничены.

    Простейший метод вставить в документ рисунок — по упомянутым причинам он же и единственный — скопировать его в Word из буфера обмена. Предположим, рисунок у нас находится в компоненте DBImage. Сначала нужно загнать его в буфер обмена:

    Теперь для его вставки следует воспользоваться методом Paste объектов Range или Selection: WordApplication1.Selection.Paste или WordDocument1.Range(a,b).Paste. Оставить для рисунка достаточное количество пустых строк и попасть в нужное место — это уже наша забота. Если он попадет посреди текста, вид будет довольно противный — при такой вставке обтекание текстом рисунка происходит как-то странно. Можно приготовить для отчета шаблон, где заменяем рисунком какое-либо ключевое слово. О том, как найти в документе нужный текст, см. выше.

    А теперь о несколько ином способе вставки рисунка, который устраняет проблемы с обтеканием и дает нам возможность перемещать его по документу, масштабировать и задавать отступы между рисунком и текстом. Способ, собственно, тот же — копируем из буфера обмена, но не прямо в документ, а в «рамку» — текстовую вставку. В ней может находиться не только текст, но и картинка, чем и воспользуемся.
    «Рамки» образуют коллекцию Frames, нумеруются целым индексом, пробегающим значения от 1 до WordDocument1.Frames.Count. Добавим в документ рамку, изменим ее размер и вставим рисунок:

    Здесь для простоты предполагается, что размер DBImage равен размеру самой картинки, а также что до этого рамок у нас в документе не было. Обратить внимание следует на несколько моментов. Размер рамки надо задавать до того, как копировать в нее рисунок. Иначе она будет иметь размер по умолчанию, под который замасштабируется и наша картинка. При попытке изменить размер рамки задним числом размер картинки уже не изменится. Кроме того, параметр Range при добавлении рамки часто никакой роли не играет. Рамка изначально все равно появится в левом верхнем углу документа, а указанный кусок текста при этом не пострадает. Но это только в том случае, если он не выделен. Если в документе есть выделение, рамка появится вместо выделенного фрагмента. Таким образом можем ее вставить в нужное место взамен какого-то ключевого слова.
    При желании можем ее подвигать в документе и «вручную». Для этого служат свойства горизонтального и вертикального позиционирования, которые задают ее отступ от левого верхнего «угла» документа:

    Отступ между краями рамки и текстом задается следующим образом:

    А теперь о масштабировании. Для этого достаточно длину и ширину рамки умножить на одно и то же число. Например:

    При этом наша картинка в полтора раза пропорционально растянется. Точно также можно и уменьшить, но делить, как и множить, следует на одно число. Растягивать длину и ширину по-разному у меня лично не получалось. Задавать размер опять-таки надо еще до вставки рисунка. Ну и, наконец, удаление рамки:

    Списки в документе образуют коллекцию Lists, к отдельному списку обращаемся WordDocument1.Lists.Item(i), где i целое число от 1 до WordDocument1.Lists.Count . на этом все. Нет методов, позволяющих не то что создать новый список, а даже добавить пункт к уже существующему. Ничего страшного, настоящие герои всегда идут в обход:)) Сейчас мы все же проделаем и то, и другое. Все что нам понадобится — свойство Range отдельного списка, то есть его текст без разделения на пункты, а также возможность его выделить:

    Для этого в любом случае потребуется заготовка. Неважно, вставлена она в общий шаблонный документ или хранится в отдельном файле. Заготовку делаем так: выбираем в меню Формат/Список, и сохраняем, если это отдельный шаблон списка. У нас появляется пустой список без текста с одним маркером. Далее вспоминаем, как мы делали списки вручную — писали текст, нажимали «Enter», появлялся новый элемент списка. Теперь то же самое, только программно. Предположим, у нас уже открыт документ с заготовкой, и мы хотим внести в список пункты «Item 1» и «Item 2»:

    То есть мы вставляем в документ текст первого пункта списка, он попадает на свое место. Потом посылаем в Word символ перехода строки, он честно переходит и тем самым сам создает нам второй пункт списка, куда и вставляем нужную строку. Ну и так далее, нужное количество раз. Последние две строки нужны, если список заготовлен в отдельном файле — после их выполнения список оказывается в буфере обмена. Здесь выгода в том, что можем иметь заготовки списков разных стилей и по ходу дела выбирать, какой список создать. Затем открываем документ, где должен быть список, выделяем с помощью Range нужный кусок, копируем из буфера обмена через WordDocument1.Range(a,b).Paste. Чтобы не испортить файл с заготовкой, можем сразу после открытия пересохранить его под другим именем, а можем просто выйти из него без сохранения изменений

    COM специфика работы с Word

    Mr. Anderson

    Новичок

    kaster

    Мой Аватар, он лучший самый

    Mr. Anderson

    Новичок
    • Автор темы
    • #3

    Еще не понял что с этим можно делать, но в WinXP нашел интересную штуку:
    Пуск — Выполнить — dcomcnfg
    или
    Win+R — dcomcnfg


    Вроде бы и по делу, вроде и первоисточник (СОМ приложения системы), а что с этим делать не понятно. :whistle:

    Garrett

    Модератор

    RUVATA

    лучше один раз увидеть, чем десять раз услышать.

    kaster

    Мой Аватар, он лучший самый

    RUVATA

    лучше один раз увидеть, чем десять раз услышать.

    и даже нужно .
    Приступим:
    С программами Microsoft Office Word, Excel и другими можно работать как с объектами автоматизации OLE. Этот подход существенно отличается от работы с этими программами как с серверами СОМ или от использования компонентов страницы Servers. Работа с объектами автоматизации может быть организована двумя способами: через библиотеки типов и через механизм автоматизации OLE.
    Использование библиотеки типов имеет то преимущество, что обеспечивает проверку типов, но для работы с библиотекой типов надо сформировать соответствующий файл и разобраться в нем.
    Использование автоматизации OLE применительно к Word и Excel проще, поскольку в эти программы встроена справка по VBA, содержащая описание всех объектов, свойств и методов.

    Основные отличия при использовании автоматизации OLE от работы с серверами СОМ заключаются в следующем:

    1)Для работы с серверами COM не обязательно чтобы приложение было запущено, но для этого необходимы определенные приготовления, которые требуют специфических знаний а так-же углубленного представления о работе технологии COM, как впрочем и в дальнейшем в процессе разработки.
    Работа с серверами OLE требует от разработчика лишь возможность получить ссылку на COM-объект, запущенного приложения(OLE-сервер выдающий эту ссылку позиционирует себя как «Excel.Application»)

    2) В серверах автоматизации OLE при вызове методов не требуется задание значений необязательных параметров, что существенно упрощает многие операторы.
    Параметры методов можно задавать в форматах «имя := значение», причем последовательность задания параметров безразлична. (по правилам VBA)
    Это дополнительное удобство, так как не требуется помнить последовательность параметров в объявлении метода.

    3) Еще одним преимуществом серверов автоматизации OLE является то, что вызываемые методы очень близки к их описанию в справке по VB соответствующей программы Microsoft Office. В серверах СОМ в некоторых случаях наблюдаются отличия.

    4) Что касается OLE, то ряд условностей в реализации IDE, как и выбранного языка программисрования влияют так или иначе на наличие подсказок, возможность/невозможность использования констант с чем COM сервер чаще не имеет проблем. OLE-сервер как-бы сам отвечает за соответсвующющее приведения типов, когда при работе с COM-сервером предварительно приведение типов (обязательно).

    Теперь следут сказать о том, что несмотря на простоту использования OLE-сервера, и множество тонкостей работы с COM-сервером, их вообще не следует сравнивать так, как используют их для разного рода задачь.
    OLE-сервера всецело выполняют роль автоматизации конкретного запущенного приложения,
    в то время как COM сервера реализуют саму идеологию COM и предоставляют возможность работать непосредственно с комполнентами, и не неуждаются в комбинорованном приложении, возможности COM более широки, а для большей ясности:
    например широко применялась практика использования модулей MS Word «проверка орфографии» для проверки содержимого текстовых полей программ написанных на том-же C# или vb.NET, даже видел реализацию на Java (хотя там на этот счет есть более лаконичные решения). основана на взаимодействии с COM сервером, и для этого требуется только чтобы Word был установлен в системе — не запущен

    И все-таки в целом, как мне представляется, использовать серверы автоматизации OLE в большинстве случаев проще, чем работать с серверами СОМ.

    Объект Word.Application

    Лекция 10. Тема: Методы и свойства объектов Microsoft Word.

    Общая структура объектов Word выглядит так, как показано на рис. 10.1.

    На практике для решения большинства программных задач достаточно знать всего лишь пять объектов (с сопутствующими коллекциями):

     объект Document (с коллекцией Documents);

     объект Bookmark (с коллекцией Bookmarks).

    Рис. 10.1. Главные объекты Word

    Как работать с объектом Application

    Объект Application — это само приложение Microsoft Word. Все остальные объекты Word «вложены» в него. Создать этот объект — значит, запустить Word на вашем компьютере. Как правило, это нам и необходимо (если мы создаем документ в формате Word из другого приложения, например из Access). Но не забудьте — если вы запускаете Word из другого приложения Office, то необходимо добавить в ваш проект ссылку на библиотеку Microsoft Word 11.0 Object Library.

    Код запуска Word очень прост:

    Dim oWord As New Word.Application

    Однако, выполнив его из другого приложения, вы, скорее всего, даже не заметите, что у вас чтото произошло. Причины просты:

    1. По умолчанию Word запускается в скрытом окне.

    2. Если в нем не открыт ни один документ, он тут же закрывается (после того, как завершается создавшая его процедура).

    Сделать Word видимым очень просто:

    Однако может возникнуть вопрос: а нужно ли его делать видимым? Некоторые разработчики утверждают, что не нужно. Пусть Word работает в скрытом окне, создавая требуемый документ. Когда пользователю потребуется, он этот документ откроет. Если вы работаете с Word в скрытом окне, не забудьте после выполнения необходимых действий его закрыть (иначе он так и останется в оперативной памяти, видимый только через Task Manager). Для закрытия Word нужно вызвать его метод Quit().

    Чтобы Word не закрывался сам собой, в нем достаточно создать новый документ. Подробно об этом будет рассказано в следующем разделе, но самый простой вариант создания нового документа Word выглядит так:

    Dim oWord As New Word.Application

    Если Word уже был открыт на компьютере, то можно получить на него ссылку, например, при помощи такого кода:

    Set oWord = GetObject(, «Word.Application»)

    Однако на практике, кроме очень специальных случаев (активизация объектов OLE), такой подход по сравнению с открытием нового экземпляра Word ничего не дает. Наоборот, появляется дополнительный риск нечаянно испортить открытый в существующем экземпляре созданный пользователем документ или закрыть его без сохранения пользовательских документов. Поэтому лучше создавать новый экземпляр Word.

    Если же ваш код VBA выполняется в Word (т. е. Word уже запущен), объект Application создавать не надо. В этой ситуации он будет автоматически доступен в любой момент (чтобы в этом убедиться, достаточно впечатать в окне редактора кода Application и добавить точку). Более того, если не указано, к какому объекту относится то или иное свойство или метод, компилятор VBA в Word автоматически считает, что это свойство или метод принадлежит объекту Application. Поэтому следующие два фрагмента кода функционально одинаковые:

    Илон Маск рекомендует:  Set - Ключевое слово Delphi

    Application.Selection.TypeText «Мой текст»

    Selection.TypeText «Мой текст»

    Еще один важный момент, который связан с объектом Application в Word. Для него предусмотрено большое количество удобных в использовании событий (открытие документа, выход из Word, щелчок правой кнопкой мыши, изменение документа, печать документа, сохранение документа и т. п.) Однако по умолчанию все эти события не видны. Чтобы они появились, необходимо в разделе Declarations кода формы (а не модуля!) объявить объект Application с ключевым словом WithEvents, например так:

    Public WithEvents App As Word.Application

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

    10.2. Свойства, методы и события объекта Application

    Далее приведены самые важные свойства, методы и события объекта Application.

     ActiveDocument — возвращает объект активного документа в данном экземпляре Word. Это свойство используется очень активно, обычно без упоминания объекта Application, например:

    Свойство доступно только для чтения, поэтому чтобы сделать какойнибудь документ активным, придется вызывать для его объекта метод Activate().

     CapsLock — позволяет проверить, включен ли режим CapsLock на клавиатуре. Изменить этот режим при помощи данного свойства нельзя (только для чтения), для этого есть другие средства (связанные с использованием Windows API). Аналогично работает свойство NumLock.

     Caption — позволяет заменить текст «Microsoft Word» в заголовке окна на другой, например «Мое приложение».

     CheckLanguage — возвращает True, если Word определяет в автоматическом режиме язык, на котором производится ввод текста. Если в системе установлено несколько языков ввода, то по умолчанию автоматическая проверка установлена. При помощи этого свойства можно изменить режим работы Word.

     CustomizationContext — свойство, которое позволяет указать шаблон или документ, на который будут распространяться внесенные вами изменения в меню, панели инструментов и клавиатурные комбинации. Например, код:

    говорит о том, что все изменения, которые вы будете вносить, начиная с этого момента, будут сохраняться в шаблоне Normal.dot (и, таким образом, будут применяться ко всем документам).

     Dialogs — возвращает коллекцию Dialogs, представляющую из себя все возможные диалоговые окна Word. При помощи этой «ветви» объектной модели Word вы можете открыть любое из сотен диалоговых окон Word и определить действия, которые будут предприняты при выборе пользователем тех или иных параметров в данном диалоговом окне. К сожалению, эта «ветвь» очень плохо документирована, и при использовании объектов диалоговых окон приходится заниматься самостоятельными исследованиями (при помощи макрорекордера и окна Locals), чтобы определить нужные свойства и их значения. По моему опыту, обычно бывает проще создать свою форму VBA, которая будет выполнять необходимые действия, чем заниматься такой исследовательской работой. Пример использования диалогового окна открытия файла может выглядеть так:

    Dim oDlg As Dialog

    Set oDlg = Application.Dialogs(wdDialogFileOpen)

    If oDlg.Display = -1 Then

    MsgBox «Вы выбрали файл: » & _

    Appliction.Options.DefaultFilePath _ (wdCurrentFolderPath) & «\» & oDlg.Name

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

     DefaultSaveFormat — определяет формат сохранения файлов Word по умолчанию (тот, который будет предлагаться пользователь в диалоговом окне Save As). Можно настроить на сохранение в формате обычного текста TXT, текста Unicode, RTF и т. п.

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

     DisplayAutoCompleteTips — включает или отключает подсказки для автозавершения текста. Чаще всего необходимо отключить.

     Documents — самое важное свойство. Возвращает коллекцию документов.

     FeatureInstall — еще одно свойство, которое позволяет не раздражать пользователя попытками Office доустановить еще не установленные компоненты. Для этого нужно установить это свойство в значение msoFeatureInstallNone.

     FileDialog — возвращает объект FileDialog, т. е. окно выбора файла, каталога, открытия файла или сохранения. Для открытия этого окна необходимо воспользоваться методом Show() этого объекта.

     FileSearch — возвращает объект FileSearch, который может использоваться для поиска файлов по определенным параметрам.

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

     IsObjectValid — очень удобное свойство для всевозможных проверок (открыт ли документ, находится ли указатель в таблице и т. п.). Проверяет, существует ли еще объект, к которому мы хотим обратиться. Позволяет уберечь от ошибок, когда, например, документ или объект в документе был удален пользователем.

     KeyBindings — очень удобное во многих ситуациях свойство. Оно возвращает коллекцию KeyBindings — привязок клавиатурных комбинаций. Проще говоря, при помощи этого объекта и его подобъектов вы можете назначить любую команду Word или любой макрос любому сочетанию клавиш (в том числе и тем, которые уже заняты служебными командами, например + ). Общая последовательность действий при этом выглядит так:

    • определяем свойство CustomizationContext объекта Application, т. е. где будут сохраняться наши изменения: в шаблоне Normal.dot, в текущем документе или в шаблоне, прикрепленном к текущему документу;

    • при помощи метода Application.BuildKeyCode() определяем цифровой код для нашей клавиатурной комбинации;

    • при помощи метода KeyBindings.Add() добавляем новое назначение, при этом определяем все необходимые параметры.

    Application.KeyBindings.Add wdKeyCategoryMacro, _

    «Normal.NewMacros.DataLoad», BuildKeyCode(wdKeyAlt, wdKeyD)

     Language — еще одно свойство, которое позволяет определить, установлена ли на компьютере пользователя локализованная версия Word (точнее, это свойство определяет язык пользовательского интерфейса). Для русского языка будет возвращаться значение 1049, для английского — 1033. Более подробную информацию (о языке помощи, языке программы установки и т. п.) можно получить при помощи свойства LanguageSettings.

     MacroContainer — очень полезное свойство для программистов. Позволяет в ходе выполнения макроса определить, откуда был запущен текущий программный код (обычно проверяются два варианта — Normal.dot или текущий документ).

     NewDocument — одна из возможностей создать новый документ Word. Возвращает объект NewDocument. Для создания нового документа используется метод Application.NewDocument.Add().

     NormalTemplate — это свойство позволяет получить ссылку на объект Template, представляющий Normal.dot, для внесения в него изменений.

     Option — возвращает объект Option с огромным количеством свойств. Через этот объект программным способом можно настроить значения на всех вкладках окна Параметры (меню Сервис | Параметры).

     Path — возвращает путь к программным файлам Word на диске.

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

     Selection — еще одно важнейшее свойство. Возвращает объект Selection — то место, в котором находится указатель вставки.


     ShowStartupDialog — определяет, показывать или нет Task Panel (панель задач в правой части документа) при запуске Word. Чаще всего используется для отключения показа. Есть еще несколько свойств с префиксом Show. значения которых очевидны.

     SpecialMode — позволяет проверить, не находится ли Word в специальном режиме копирования и вставки (для перехода в этот режим нужно выделить текст и нажать или + , а потом переместить курсор и нажать ).

     StatusBar — еще одно очень полезное свойство. Позволяет вывести текст в Status Bar (строка состояния), т. е. в строке в нижней части окна приложения, где выводится информация о страницах, столбцах, языке, режимах работы и т. п.

     System — возвращает одноименный объект System, предназначенный для получения информации из операционной системы (региональный настройки, тип курсора мыши, разрешение экрана, тип процессора и т. п.). Позволяет также подключать сетевые диски и запускать приложение Microsoft System Information.

     Tasks — возвращает одноименную коллекцию Tasks с объектами Task, представляющими все работающие в системе процессы. При помощи этих объектов можно программным способом найти работающее в системе приложение и чтонибудь с ним сделать (сделать видимым или невидимым, активизировать, закрыть, передать в его окно сообщение Windows, как при работе с Windows API и т. п.). Опытные разработчики активно используют этот набор объектов для работы с внешними приложениями. Запускать внешние приложения лучше всего при помощи специального объекта Shell.

     UserControl — очень важное свойство (оно есть и в Excel). Это свойство позволяет определить, как именно был запущен Word — пользователем вручную или программным образом. На основе этого можно, например, сделать вывод, нужно ли его программным образом закрывать.

     Visible — позволяет спрятать окно Microsoft Word очень качественно — Word исчезает и c рабочего стола, и из панели задач.

     Windows — возвращает информацию об одноименной коллекции Windows, содержащей объекты Window. Эти объекты представляют окна документов Word.

     WindowsState — позволяет свернуть, развернуть или восстановить окно Word.

    10.3. Методы объекта Application.

    Самые важные методы объекта Application приведены далее.

     Activate() — просто активизирует окно Word с текущим документом. Обычно нужно активизировать определенный документ, поэтому этот метод используется для объекта Document.

     CheckGrammar() и CheckSpelling() — позволяют проверить грамматику и орфографию для передаваемых символьных значений. Чаще всего используются аналогичные методы для объектов Document и Range.

     CleanString() — очень полезный метод. Позволяет «чистить» передаваемое символьное значение (полученное, например, от объектов Selection или Range) от специальных символов Word и превращает их в обычный текст, как будто он был набран в блокноте.

     GoBack() — этот метод обеспечивает переход на последнее место редактирования в документе. Word сохраняет с документом три последние точки редактирования, так что открыть последний документ в Word и перейти на точку, где вы остановились, можно очень просто:

     GoForward() — обеспечивает переход вперед по точкам сохранения.

     KeyBoard() — очень полезный метод. Позволяет программным способом переключать раскладку клавиатуры в Word, уберегая таким образом пользователей от ошибок. Переключение на русский язык выглядит так:

    а на английский:

    Если этому методу ничего не передавать, он вернет текущую раскладку клавиатуры.

     KeyString() — метод, обратный BuildKeyCode(). Если BuildKeyCode() возвращает уникальный идентификатор клавиатурной комбинации, то этот метод возвращает клавиатурную комбинацию для данного уникального идентификатора.

     ListCommands() — метод, не похожий на другие. Он создает новый документ и выводит в нем в виде таблицы справочник по методам и клавиатурным комбинациям Word, как стандартным, так и назначенным вами.

     OnTime() — очень интересный метод. Он позволяет выполнить макрос Word либо в указанное вами время, либо по прошествии какого-то времени. В Word одновременно может работать только один таймер. При помощи этого метода можно выполнять ресурсоемкие операции в автоматическом режиме.

     OrganizerCopy() — еще один полезный метод. Позволяет скопировать макрос, панель инструментов, запись автотекста или стиль из одного документа в другой. Для удаления и переименования этих элементов предусмотрены методы OrganizerDelete() и OrganizerRename().

     PrintOut() — метод, который принимает огромное количество параметров (все необязательные) и позволяет вывести на печать весь документ или его часть. Может использоваться для объектов Application, Document и Window.

     Quit() — метод, который используется, видимо, чаще всех. Позволяет закрыть Word с сохранением или без сохранения документов.

     Repeat() — просто повторяет последнюю выполненную команду указанное вами количество раз.

     ResetIgnoreAll() — снять метку со всех фрагментов текста, помеченных как «без проверки» в ходе проверки орфографии.

     Run() — еще один очень важный метод. Позволяет запустить процедуру/макрос из открытого шаблона или документа с передачей параметров.

     ScreenRefresh() — обновляет окно приложения. Обычно используется после того, как автоматическое обновление было отключено при помощи свойства ScreenUpdating.

     ShowClipboard() — отображает панель буфера обмена Word (если вы работаете с несколькими буферами).

    Остальные методы относятся к работе протокола DDE, преобразованию различных единиц измерений и т. п.

    У объекта Application есть множество событий: открытие, закрытие, сохранение и печать документа, щелчки мышью, активизация, выход из приложения и т. п. Единственное, что следует еще раз отметить — события объекта Application по умолчанию не отображаются в редакторе Visual Basic. Чтобы они появились, в раздел Declarations нужно поместить следующую строку кода:

    Public WithEvents App As Word.Application

    В этом случае в списке объектов в окне редактора кода для форм появится объект App со всеми необходимыми событиями.

    10.4. Коллекция Documents и объекты Document

    Как работать с коллекцией Documents

    На одну ступень ниже объекта Application в объектной модели Word (и по логике использования в приложениях) находятся коллекция Documents и объекты Document, из которых она состоит. При программировании в Word без них обычно не обойтись.

    Чаще всего в программах нам нужно:

    1. Запустить Word.

    2. Создать или открыть документ.

    3. Что-то с этим документом сделать (например, впечатать в нужные места этого документа значения, полученные из базы данных или от пользователя).

    Запуск Word производится при помощи объекта Application, с которым вы уже знакомы. Для выполнения различных действий с документом используются объекты Selection, Range и Bookmark. А вот второй пункт — создание или открытие документа, проверка, открыт уже документ или нет, сохранение документа и т. п. — реализуется при помощи коллекции Documents и объекта Document.

    Самый простой вариант создания документа выглядит так:

    Dim oDoc As Word.Document

    Set oDoc = Application.Documents.Add()

    При этом мы создали обычный пустой документ (на основе шаблона Normal.dot) и получили ссылку на него в объектную переменную oDoc. Далее в документ можно программно вводить нужную нам информацию.

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

    Например, в нашей ситуации нам вначале нужно набрать текст договора, оставив пустые места для изменяемых данных, и сохранить его с расширением dot (предположим, что он сохранен на диске C: с именем dog_blank.dot). Тогда создать документ на основе этого шаблона можно так:

    Dim oDoc As Word.Document

    Set oDoc = Application.Documents.Add_ («C:\dog_blank.dot»)

    А далее при помощи объектов Bookmark и Range вводим текст в оставленные пустые места.

    Часто возникает потребность программным способом не создавать новый документ, а открыть уже имеющийся и что-то сделать с ним. Открыть документ проще всего при помощи метода Open() коллекции Documents. Самый простой вариант применения этого метода выглядит так:

    Dim oDoc1 As Word.Document

    Set oDoc1 = Documents.Open(«c:\doc1.doc»)

    Если документ уже открыт, то по умолчанию просто создается ссылка на этот открытый документ, вместо открытия его заново.

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

    Сохранять документы лучше при помощи методов Save() и SaveAs() объекта Document. В коллекции Documents есть также свой метод Save(), который позволяет сохранить сразу все открытые документы Word, но обычно это менее удобно.

    Заметим, что из Word можно открывать не только документы Word разных версий, но и документы десятков других различных форматов, про которые знает Word — TXT, HTML, XML и т. п. Сохранять файлы также можно в одном из десятков встроенных форматов или использовать свой собственный пользовательский формат (при помощи объекта FileConvertor). За счет этого программным образом при помощи макросов можно очень удобно преобразовывать большое количество документов, которые могут находиться, например, в разных каталогах на файловых серверах, или в общих папках Exchange Server, или в базе данных SharePoint Portal Server. Для прохода по дереву каталогов удобнее всего использовать объект FileSystemObject из библиотеки Microsoft Scripting Runtime, которая есть на любом компьютере Windows.

    Свойства и методы коллекции Documents

    Коллекция Documents, как уже говорилось ранее, представляет все документы Word, открытые в настоящий момент. Нумерация документов в коллекции начинается с 1. Из свойств этой коллекции интерес может представлять только свойство Count — количество открытых документов. Гораздо важнее методы коллекции Documents. Про некоторые из них мы уже говорили в предыдущем разделе, но здесь для справки приведем информацию о них еще раз.

     Add() — этот метод позволяет создать и сразу же открыть новый документ (и вернуть ссылку на его объект). Это наиболее распространенный способ создания новых документов в Word. Полный синтаксис этого метода выглядит как:

    Add(Template, NewTemplate, DocumentType, Visible)

    Здесь Template — это шаблон для создания нового документа, NewTemplate (True/False) — делать ли новый документ шаблоном, DocumentType — тип документа, может принимать значения: wdNewBlankDocument, wdNewEmail-Message, wdNewFrameset или wdNewWebPage (по умолчанию новый чистый документ), Visible — будет ли новый документ видимым (по умолчанию) или невидимым. Все эти параметры являются необязательными. Если не указать ни один из них, будет просто создан новый документ на основе шаблона Normal.dot (как будто вы создали новый документ при помощи меню Файл | Создать).

     Open() — еще один важнейший метод коллекции Documents. Позволяет открыть документ с диска и добавить его в коллекцию. Этот метод принимает множество параметров, из которых обязательным является только один — имя документа (вместе с путем к нему). Самый простой вариант применения этого метода выглядит так:

    Dim oDoc1 As Document

    Set oDoc1 = Documents.Open(«c:\doc1.doc»)

     Item() — позволяет найти нужный документ в коллекции по его индексу. Обычно для получения ссылки на нужный документ используется конструкция For. Next с проверкой значения какоголибо свойства документа через If. Then. Чаще всего это свойство — Name:

    Dim oDoc1 As Word.Document

    For i = 1 To Documents.Count

    Set oDoc1 = Documents.Item(i)

    If oDoc1.Name = «doc1.doc» Then

    Set oDoc1 = Nothing

    Этот код возвращает ссылку в виде переменной oDoc1 на документ doc1.doc, если он есть в коллекции. Если его нет, то во избежание ошибок нужно реализовывать дополнительные проверки. На практике можно было бы перед сравнением привести имя документа в нижний регистр, если учитывать регистр букв при поиске вам не нужно.

    Через метод Item() можно получить доступ к объекту документа напрямую. Например, в этом примере мы получаем имя первого документа в коллекции Documents:

     Save() и Close() — позволяют соответственно сохранить или закрыть все документы в коллекции.

     CanCheckOut() (можно ли «забрать» документ в монопольный доступ) и CheckOut() (забрать документ в монопольный доступ) — эти методы можно применять, если документ находится в документной библиотеке в базе данных SharePoint Portal Server.

    10.5. Свойства и методы объекта Document

    После того, как мы при помощи объекта Application запустили Word, при помощи коллекции Documents создали (или открыли, или нашли среди уже открытых) нужный нам документ, можно выполнять с этим документом различные действия, реализованные при помощи свойств, методов и событий объекта Document. У этого объекта десятки свойств и методов, и здесь мы рассмотрим только наиболее важные и часто используемые.

    Обратите внимание, что к объекту Document можно обращаться и не создавая специальную объектную переменную. Существует еще, по крайней мере, три способа получения доступа к объекту Document:

     работать с документом как с элементом коллекции Documents. Формат обращения может выглядеть, например, как Documents.Item(1);

     использовать специальное ключевое слово ThisDocument. При помощи него можно получить ссылку на объект документа, которому принадлежит исполняемый программный модуль, например:

     использовать свойство ActiveDocument объекта Application. Это свойство возвращает нам объект активного документа:

    Самые важные свойства объекта Document представлены далее.


     ActiveWritingStyle — текущий активный стиль (заголовок определенного уровня, обычный текст, гиперссылка и т. п.). Рекомендуется проверять это свойство перед вводом текста.

     Background — возвращает объект Shape, представляющий фоновый рисунок (фоновые рисунки видны только в режиме Web-документ).

     BuiltInDocumentProperties — позволяет получить ссылку на коллекцию DocumentProperties с одноименными объектами, представляющими встроенные свойства документа (название, автор, категория, комментарии и т. п.);

     Characters — возвращает коллекцию объектов Range, каждый из которых представляет один символ. Это свойство есть не только у объекта Document, но и у объектов Selection и Range. Может использоваться, например, для выполнения операция поиска и замены или статистических подсчетов (например, если переводчику платят за количество символов);

     Content — свойство, возвращающее объект Range, представляющий собой главную цепочку документа (main document story). Если говорить проще, то это просто текст документа, без колонтитулов, сносок, комментариев и т. п.

     CustomDocumentsProperty — свойство, возвращающее коллекцию объектов DocumentProperties, представляющих пользовательские свойства документа. Можно использовать для сохранения вместе с документом любых значений переменных. Очень удобно, например, для подсчета количества открытий документа, флажков печатался/не печатался, сколько раз вызывалась та или иная функция, на каких компьютерах и каким пользователем открывался и т. п.

     Fields — позволяет получить ссылку на коллекцию Fields одноименных объектов. Это свойство очень полезно при работе с полями. Поле в Word — это место в документе, отведенное для подстановки изменяемых данных: формул, даты, информации об авторе, размере документа и т. п. При работе с документом Word средствами обычного графического интерфейса добавить новое поле можно при помощи меню Вставка | Поле.

     Footnotes — возвращает коллекцию сносок.

     Свойства с префиксом Formatting. — определяют, что показывать в списке стилей панели инструментов Форматирование.

     FormFields — аналогично Fields, но в этом случае возвращается ссылка на поля в формах.

     FullName — возвращает полное имя объекта (вместе с путем к нему в файловой системе или Web). Доступно только для чтения.

     GrammarChecked — помечает весь документ, как проверенный с точки зрения грамматики (фактически отключает проверку грамматики для данного документа). Такое же свойство существует и у объекта Range. Коллекцию ошибок, выловленных при проверке грамматики, можно получить при помощи свойства GrammaticalErrors, а выделить ошибки зеленым волнистым подчеркиванием (если этого не сделано) — при помощи свойства ShowGrammaticalErrors. Для орфографических ошибок существуют аналогичные свойства SpellingChecked, SpellingErrors и ShowSpellingErrors.

     HasPassword — проверяет, назначен ли пароль для указанного документа. Другое свойство Password назначает пароль. По причине крайней слабости защиты пароли в Word, Excel и Access использовать не рекомендуется.

     Indexes — возвращает коллекцию индексов (т. е. предметных указателей) для документа.

     Name — имя документа (без пути к нему).

     OpenEncoding — возвращает кодовую страницу, которая использовалась для открытия документа. Для русского языка по умолчанию это 1251.

     PageSetup — позволяет получить ссылку на одноименный объект. Используется в основном при реализации печати.

     Paragraphs — возвращает ссылку на коллекцию абзацев в данном документе.

     Path — возвращает путь к документу в файловой системе (без имени). Это свойство может пригодиться, чтобы создать еще один файл в том же каталоге.

     Saved — очень важное свойство. Позволяет определить, изменялся ли документ со времени последнего сохранения.

     SaveEncoding — позволяет явно указать (или получить) кодировку, которая будет использоваться при сохранении документа.

     SaveFormat — позволяет получить информацию о формате документа (DOC, RTF, TXT, HTML и т. п.). Доступно только для чтения.

     Sections — возвращает коллекцию разделов документа. Sentences — то же самое для предложений. Аналогично работают свойства Shapes, Styles, Subdocuments, Tables, Windows и Words.

     Type — возвращает тип документа (обычный, шаблон или Web-страница с фреймами).

     Variables — еще одно очень удобное свойство. Можно использовать для сохранения своих служебных данных вместе с документом, как и пользовательские атрибуты (custom attributes), но, в отличие от пользовательских атрибутов документа, пользователям эти свойства не будут видны.

    Теперь рассмотрим самые важные методы объекта Document.

     Activate() — этот метод позволяет сделать указанный вами документ активным (например, для ввода текста).

     AddToFavorities() — позволяет добавить ссылку на документ в каталог Избранное. Может быть полезным, если пользователь будет работать с этим документом постоянно.

     CheckSpelling() и CheckGrammar() — запускают проверку орфографии и грамматики соответственно.

     Close() — закрывает документ. Можно закрыть с сохранением (по умолчанию), а можно без (если указать соответствующий параметр).

     Compare() — сравнивает документ с другим и генерирует редакторские пометки в местах, где обнаружены различия.

     DetectLanguage() — определяет язык текста. Проверка производится по предложениям, на основе сверки слов со встроенными словарями. Такая проверка производится автоматически во время ввода текста или при открытии нового документа. Чтобы заново провести проверку языков, свойство LanguageDetected нужно перевести в False.

     FitToPages() — очень интересный метод. Размер шрифта автоматически меняется таким образом, чтобы текст стал занимать на одну страницу меньше. Можно использовать для устранения «висячих страниц» и других проблем верстки.

     FollowHyperlink() — открывает указанный вами документ в соответствующем приложении (если HTML, то в Internet Explorer).

     GoTo() — очень мощный метод. Для объектов Document и Range он возвращает объект Range, для объекта Selection — просто перемещает указатель ввода текста на нужное место. Возвращаемые объекты в зависимости от параметров, которые были переданы этому методу, могут указывать на начало страницы, на определенные строки, закладки, комментарии, таблицы, секции, поля, ссылки, формулы и т. п. Может переходить на определенный номер такого элемента в документе, первый, последний, следующий и т. п. Очень удобно использовать для установки указателя в нужное место для автоматического ввода текста.

     Merge() — позволяет произвести слияние двух документов. Метод очень сложный и мощный, основывается на применении редакторских пометок.

     PresentIt() — открывает данный документ в PowerPoint.

     PrintOut() — очень сложный метод, который позволяет вывести на печать весь документ или его часть.

     PrintPreview() — переводит документ в режим предварительного просмотра.

     Protect() — ограничивает внесения изменений в документ при помощи пароля или нового средства управления правами на доступ к данным, которое называется IRM. Те же возможности на графическом экране доступны через меню Файл | Разрешения.

     Range() — очень важный метод. Возвращает объект Range, принимает в качестве параметров номер начального символа диапазона и номер конечного символа.

     Redo() — повторяет последнее действие. В качестве параметра принимает количество последних действий, возвращает True, если повтор был произведен успешно.

     Repaginate() — выполняет переразбивку документа на страницы. Обычно используется, если автоматическая разбивка была ранее отключена (например, на вкладке Общие диалогового окна Параметры (меню Сервис | Параметры) или программно при помощи объекта Options).

     Save() — смысл этого метода очевиден. Если документ ранее не сохранялся, открывается диалоговое окно Сохранить как.

     SaveAs() — очень мощный и сложный метод. Можно определить путь для сохраняемого документа, его формат, кодировку, пароли на открытие и изменение документа, вставку шрифтов и многое другое. Очень удобно использовать, например, для автоматической конвертации документов.

     Select() — позволяет просто выделить весь документ. Этот метод существует для очень большого количества объектов, в том числе для Selection и Range.

     TransformDocument() — исключительно мощный метод, но только для программистов, которые хорошо разбираются в XML и XSLT. Позволяет применить к документу таблицу преобразований стилей (Extensible Stylesheet Language Transformation, XSLT), при помощи которой можно поменять все, что угодно.

     Undo() — отменяет определенное количество последних действий. По синтаксису и принципам работы — полный аналог метода Redo().

     UndoClear() — очищает буфер отмены изменений, чтобы пользователь не смог откатить произведенные действия.

     UnProtect() — снимает защиту с документа (определенную методом Protect() или в графическом интерфейсе). Может быть очень полезным перед программным внесением изменений в защищенный документ.

    Часто используемых событий у объекта Document всего три: New (можно определить только для шаблона, срабатывает, когда на основе этого шаблона создается новый документ), Open и Close. Все эти события очевидны и изначально доступны в окне редактора кода Visual Basic.

    10.6. Материал для самостоятельного изучения.

    Свойства объекта Word.Application.

     ActivePrinter — позволяет получить или настроить активный принтер в ходе работы программы. Также используется очень активно, например, если результаты работы вашего приложения необходимо печатать на определенном сетевом принтере. Свойство доступно как для чтения, так и для записи.

     AutomationSecurity — определяет уровень безопасности при программном открытии файлов. По умолчанию установлено значение msoAutomationSecurityLow — открывать с включенными макросами. Можно также использовать значения msoAutomationSecurityForceDisable (отключить макросы) и msoAutomationSecurityByUI (то, что настроено на графическом интерфейсе).

     BackgroundPrintingStatus — определяет, сколько заданий Word стоит в очереди на печать.

     Browser — свойство, которое возвращает объект Browser (малозаметный набор из трех кнопок, который прячется под вертикальной полосой прокрутки). С программной точки зрения интересно его свойство Target, которое может принимать одно из 12 значений (комментарий, сноска, таблица, рисунок, заголовок, страница и т. п.). Затем при помощи методов Next() и Previous() для этого объекта мы можем перемещаться между этими элементами.

     Build — возвращает версию и номер сборки Word. Очень полезно для проверки на совместимость, если ваше приложение работает только под определенными версиями Word.

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

     EmailOptions — возвращает очень сложный и насыщенный свойствами объект EmailOptions, который используется для настройки Word как редактора почтовых сообщений Outlook.

     EnableCancelKey — это свойство определяет, сможет ли пользователь прервать выполнение любого макроса при нажатии клавиш +
    . Если установить для этого свойства значение wdCancelDisabled, то это приведет к тому, что макрос, вошедший в бесконечный цикл, можно будет закрыть только вместе с Word — через Task Manager.

     StartUpPath — предоставляет возможность просмотреть/определить путь к каталогу автозапуска. Те шаблоны и встраиваемые приложения, которые находятся в этом каталоге, Word при запуске открывает автоматически. По умолчанию каталог автозапуска находится в профиле пользователя. Путь к нему выглядит как \application data\Microsoft\Word\startup.

     UserInitials и UserName — позволяет получить или определить информацию об инициалах или имени пользователя. Инициалы используются в исправлениях, а имя пользователя — в свойствах документа.

     VBE — это свойство возвращает недокументированный, но очень интересный объект VBE, представляющий редактор Visual Basic. Обычно используется для программного внесения изменений в проекты VBA, например, добавление ссылок.

     Version — свойство возвращает версию Word (менее подробную, чем свойство Build). Для Word 2003 значение этого свойства равно 11.0.

    Методы объекта Application.

     BuildKeyCode() — позволяет узнать уникальный номер для клавиатурной комбинации в Word. Пример использования этого метода был приведен ранее при рассмотрении свойства Application.KeyBindings.

     ChangeFileOpenDirectory() — этот метод позволяет изменить каталог, который по умолчанию открывает Word при работе с документами (по умолчанию задан, конечно, каталог Мои документы);

     DefaultWebOptions() — возвращает одноименный объект, при помощи которого можно определить множество свойств, используемых при сохранении документа Word в формате HTML (кодировка, работа с изображениями, CSS, с какими браузерами обеспечивать совместимость и т. п.).

    Объект Document, основные свойства и методы.

     AttachedTemplate — предоставляет возможность подключить шаблон (со всеми макросами, стилями, записями автотекста и т. п.) или проверить, какой шаблон подключен (вручную это можно сделать через меню Сервис | Шаблоны и надстройки).

     DefaultTabStop — определяет отступ по умолчанию при использовании символа табуляции. По умолчанию задано 35 пунктов, что равно примерно 1,25 см.

     DisableFeatures — отключает возможности, которые понимают только последние версии Word (для совместимости с пользователями, у которых на компьютерах стоят старые версии). Обычно само свойство DisableFeatures просто включает такой режим, а конкретный уровень совместимости задается при помощи свойства DisableFeaturesIntroducedAfter.

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

     EmbedTrueTypeFonts — очень полезное свойство, если вы работаете с документом в месте, где используются экзотические шрифты (например, в издательстве). Вставка шрифтов truetype гарантирует, что получатели документа будут видеть его точно таким же, как и создатель.

     Envelope — позволяет получить ссылку на специальный объект Envelope, который используется для создания почтовых конвертов.

     Permission — позволяет получить доступ к объекту Permission, который управляет системой внутренних разрешений документа Word (но не разрешений файловой системы).

     PrintRevisions — определяет печатать или нет пометки редактора (исправления) вместе с документом. По умолчанию — печатать.

     ProtectionType — проверяет защиту данного документа (разрешено все, или только комментарии, чтение, изменения в полях форм и т. п.). Сама защита устанавливается при помощи метода Protect().

     ReadOnly — определяет, можно ли вносить изменения в документ или он доступен только для чтения. Это свойство само доступно только для чтения, поскольку соответствующий атрибут устанавливается в файловой системе.

     RemoveDateAndTime и RemovePersonalInformation — удаляют информацию о дате и времени произведенных изменений и всю информацию о пользователе из документа (включая свойства документа). Могут быть полезными при создании файлаобразца.

    Не нашли то, что искали? Воспользуйтесь поиском:

    Лучшие изречения: При сдаче лабораторной работы, студент делает вид, что все знает; преподаватель делает вид, что верит ему. 9337 — | 7293 — или читать все.


    188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

    Отключите adBlock!
    и обновите страницу (F5)

    очень нужно

    Илон Маск рекомендует:  Raise возбудить сигнал

    Faq работа с word через ole

    Программирование на Delphi. Word

    Ну вот и обещанный выпуск, включающий все статьи, посвящённые работе с Word из Delphi.

    «Delphi 4: Автоматизация приложений MS® Office® для эффективного анализа результатов»

  • Глава 1: Работа с MS Excel.
    • Часть 1: Создание, отображение и удаление экземпляра Excel.
    • Часть 2: Лучшее решение — шаблоны.
    • Часть 3: Создание или открытие книги.
    • Часть 4: Работа с листами и ячейками.
    • Часть 5: Передача данных разного типа.
    • Часть 6: Передача данных используя буфер обмена и DDE.
    • Часть 7: Пример обмена данными с Excel используя VCL и OLE.
  • Глава 2: Работа с MS Word.
    • Часть 1: Управление Word-ом через OLE.
    • Часть 2: Подсчет статистики обычного текста, сносок и колонтитулов в документах.
    • Часть 3: Открытие документа используя VCL.
    • Часть 4: Работа с таблицами.
    • Часть 5: Работа с текстом, рисунками и списками.
  • Глава 2. Работа с MS Word.

    Часть 1. Управление Word-ом через OLE.

    Здесь мы рассмотрим пример того, как управлять объектами Word-а (Excel — аналогично) из программ на Delphi.

    а) Для чего это нужно ?

    Задачи могут быть самые разные, в общем случае это использование возможностей Word-а в своей программе, н-р: проверка текста на орфографию; печать текста, графики; экспорт отчетов в Word или изначальное создание их там и т.д.

    б) Подготовительные работы.

    На самом деле существует несколько способов сделать это, мы рассмотрим только один (пример кроме Delphi 5, в Delphi 5 для этого есть компоненты на закладке Servers переименуете в программе типы на соответствующие компоненты, дальше так же).

    Для начала начнем новый проект File, New Application; File, Save All. Создадим отдельную папку для проекта и сохраним Unit1 как Main, а Project1 как WordWriter.

    Далее для работы с Word-ом нам потребуется библиотека типов Word-а, это делается так:

    Project, Import Type Library, Add, далее переходим в папку, где стоит Word ( у меня это — «c:\program files\microsoft office»), заходим в папку Office и выбираем файл — msword8.olb (цифра -? версии Word-а — у Вас может отличаться ) или excel8.olb (для Excel). Нажимаем Оk. Delphi создаст 2 файла — Word_tlb.pas и Office_tlb.pas, их надо включить в раздел uses модуля Main нашего проекта:

    в) Теперь займемся непосредственно программированием.

    В разделе var опишем следующие переменные:

    Далее проектируем форму:

    1. Поместим вверх нашей формы кнопку — button1 типа TButton, поменяем заголовок (св-во Caption) на ‘Старт’;

    2. Под кнопкой разместим панель — panel1 типа TPanel. Внутри панели поместим компонент — bevel1 типа TBevel, поменяем св-во Align на alClient (при этом рамка растянется на всю панель);

    3. Сверху панели (далее все компоненты будут размещаться внутри этой панели) разместим метку — label1 типа TLabel, поменяем значение св-ва Caption на ‘Передать в ячейку’;

    4. Ниже слева поместим метку — label1 типа TLabel, св-во Caption поменяем на ‘X=’;

    5. Правее метки помещаем компонент Edit1 типа TEdit, св-во Text меняем на ‘1’;

    6. По правой границе Edit1 помещаем компонент UpDown1 типа TUpDown, в списке св-ва ‘Associate’ выбираем Edit1, св-во ‘Position’ приравниваем ‘1’;

    7. Чуть отступаем вправо и повторяем шаги 4-6, заменив Edit1 на Edit2, UpDown1 на UpDown2, Label1 на Label2 соответственно;

    8. Ниже размещаем еще одну метку — label4 типа TLabel, меняем св-во ‘Caption’ на ‘Новое значение ячейки:’;

    9. Ниже размещаем компонент Edit3 типа TEdit, св-во Text меняем на ‘0’;

    10. И, наконец, в самом низу панели размещаем кнопку BitBtn1 типа TBitBtn, меняем св-во ‘Kind’ на ‘bkOk’.

    Теперь напашем обработчики — именно в них и заключается вся функциональность программы:

    1. Назначим обработчик OnClick компоненту Button1 :

    2. Зададим обработчик формы :

    3. Назначим обработчик OnClick компоненту Bitbtn1 :

    в) В общем-то, это все .

    Часть 2: Подсчет статистики обычного текста, сносок и колонтитулов в документах.

    В данном небольшом материале рассматривается вопрос подсчета статистики файлов *.doc и *.rtf. Такой вопрос у меня возник, когда пришлось сделать небольшую базу данных по учету документов, куда надо было заносить и статистику документа — число знаков, слов и т.п. Открывать каждый раз Word, считать статистику и забивать ее в форму ввода было лень, так что пришла в голову мысль это дело автоматизировать. Информации по данному вопросу найти так и не удалось, так что основным источником знаний служили заголовочный файл Word2000.pas и справка по Visual Basic for Applications. Ну и, конечно, множество разных экспериментов.

    Сразу оговорюсь, что я не профессиональный программист, так что в тонкости интерфейсов вникать не будем — сам в них не особо разбираюсь. Потому, не мудрствуя лукаво, просто поместим на форме компоненты WordApplication и WordDocument с палитры Servers. Для работы используются свойства и методы этих компонентов.

    Встроенная статистика Word подсчитывает статистику обычного текста, обычных и концевых сносок. Для подсчета статистики используется метод компонента WordDocument ComputeStatistic(). Он имеет один параметр, характеризующий, что именно считать, представляющий из себя шестнадцатеричную константу. Константы описаны в заголовочном файле Word2000.pas, он лежит обычно в /Delphi/Ocx/Servers.

    Шестнадцатеричная Символьное обозначение Смысл
    $00000000 wdStatisticWords Количество слов
    $00000001 wdStatisticLines Количество строк
    $00000002 wdStatisticPages Количество страниц
    $00000003 wdStatisticCharacters Знаки без пробелов
    $00000004 wdStatisticParagraphs Количество разделов
    $00000005 wdStatisticCharactersWithSpaces Знаки с пробелами

    Это было основное, что надо знать. Ну а теперь по порядку.

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

    Первым делом откроем документ. Предварительно надо объявить переменную FileName, она будет типа OleVariant, которой присвоим строку с именем файла.

    Обратите внимание на количество параметров-«пустышек». Их число больше того, которое обычно приводится в книжках. Ну, в моих, во всяком случае. Объясняется это тем, что «книжные» функции предназначены для MS Word 97, а такая запись для работы с Word 2000 и Word XP.

    Обычный текст.

    Объявив нужное количество переменных типа LongInt (в очень большом файле или при суммировании по нескольким документам в принципе может оказаться больше знаков, чем пределы обычного целого типа), можем уже и приступать к подсчету. Например, посчитаем число слов, знаков с пробелами и без пробелов обычного текста, а также количество страниц в документе. Результаты сохраним соответственно в «длинных» переменных WCount, SCount, CCount, и PCount.

    Открыв нужный документ в Word’е и вызвав диалог подсчета статистики, нетрудно увидеть, что значения переменных равны параметрам вордовской статистики со сброшенным флажком «Учитывать все сноски».

    Сноски.

    обычные и концевые. То есть если первые располагаются внизу данной страницы, то концевые — строго в конце документа. Кроме того, они могут отличаться и нумерацией — автоматической или заданной пользователем. Начнем с обычных сносок как с самого простого. В терминологии объектной модели Word — Footnotes. Сначала надо вычислить количество самих сносок:

    Подсчет статистики текста в сноске производится так:

    Здесь ifoot — целое число, «нумерующее» сноску. Для того, чтобы учесть сами номера сносок, сделаем так:

    Это мы посчитали для примера количество слов в сноске с номером ifoot и ее метке — при пользовательской нумерации в качестве «номера» может быть целое предложение. Далее начинаем перебирать их одну за другой. При этом следует учесть, что кроме статистики сносок необходимо получить и статистику их «номеров». То есть:

    Прибавление единицы появляется оттого, что сумма статистики сносок и номеров не совпадает с тем, что выдает встроенная статистика Word. Между номером сноски и текстом сноски Word ставит пробел, который почему-то не учитывается. Условный оператор определяет, как пронумерована данная сноска — по умолчанию или нет. В последнем случае следует проверить количество слов в обозначении сноски. Такая схема дает результат, совпадающий со показаниями встроенной статистики. Кроме того, цикл у нас идет от 1 — так начинается нумерация сносок в MS Word, да и практически всех остальных объектов тоже.

    Теперь перейдем к концевым сноскам. Теоретически все то же самое, только вместо слова «Footnotes» пишем «Endnotes». И тут наталкиваемся на сюрприз — почему-то оно считает неточно. Я в данном случае поступил так: сохраняю документ под другим именем, переконвертирую концевые сноски в обычные и далее все, как сказано выше. Сохранение документа:

    где в скобках стоят два параметра типа OleVariant — имя файла и шестнадцатеричная константа, задающая формат файла. Некоторые константы:

    Шестнадцатеричная Символьное обозначение Смысл
    $00000000 wdFormatDocument Документ Word
    $00000004 wdFormatDOSText Простой текст
    $00000006 wdFormatRTF Файл RTF

    Полный список констант формата можно найти все в том же файле Word2000.pas. И еще один интересный момент — если просто поставить в скобки обе константы, работать не будет. Следует предварительно объявить две переменных, присвоить им соответствующие значения и только потом сохранять.

    Ну, а теперь, собственно, можем вернуться к сноскам. Конвертирование концевых сносок в обычные происходит так:

    Теперь мы имеем документ, в котором содержатся только обычные сноски. С ними никаких проблем не возникает, пример, как с ними работать, см. выше. Если интересует статистика отдельно разных типов сносок, считаем предварительно статистику обычных сносок, сохраняем ее в «буферных» переменных и считаем еще раз после конвертирования. Разница даст статистику концевых сносок по отдельности. Сложив статистику сносок и простого текста, получаем статистику документа с учетом сносок так, как ее дает сам Word.

    Колонтитулы.

    Тут по традиции несколько покритикуем Microsoft. Как оказалось, Word показывает не все, что содержится в документе. Не принимаются в расчет колонтитулы. А ведь в них может содержаться изрядный кусок текста, особенно в справках, бланках и т.п. Оказывается, Word их на самом деле считает, но нам не показывает. Вот и посмотрим, как же его можно заставить это сделать.

    Колонтитулы в документе тесно связаны с несколько загадочной штукой под названием «разделы» — Sections. Каждый раздел может иметь верхние и нижние колонтитулы. Потому первым делом определяем количество абзацев.

    Здесь у нас целые переменные isectct, icofct, icohct обозначают соответственно количество разделов как таковых, количество нижних и верхних колонтитулов данного раздела. Переменная isec служит «номером» раздела, переменные icof, icoh «нумеруют» соответственно нижние и верхние колонтитулы в пределах данного раздела. Количество колонтитулов в разделе определяем так:

    Теперь уже можем «достать» текст из колонтитула:

    В данном случае мы для примера посчитали число слов, содержащихся в нижнем колонтитуле под номером icof, принадлежащем разделу под номером isec. Теперь можем написать «двойной» цикл для подсчета статистики верхних и нижних колонтитулов. Полностью это будет выглядеть так:

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

    Часто использующиеся для рисования схемок текстовые вставки с панели рисования также представляют интерес. Сам Word формально считает их «картинками», не имеющими никакой статистики — видимо, по географическому расположению в панели инструментов. В объектной модели — Shapes. Вот тут начинается самое интересное. Во-первых, все, что находится на панели рисования, является Shapes. То есть в принципе для Word’а все едино, текстовая вставка, объект WordArt или геометрическая фигура. Вместе с тем смотрится довольно нелогично, что этот самый Shape можно переконвертировать, на выбор, во Frame или InlineShape. Они уже обладают статистикой, так что, казалось бы, все в порядке. Но коварству Microsoft, кажется, вообще нет предела. Во-первых с удивлением обнаруживаем, что Shapes нумеруются индексом типа OleVariant. Что с ним дальше делать, неясно. Если просто присваивать индексу целое число, при конвертации каждого второго Shape во Frame получаем ошибку. А если обработать исключение, то будем таки иметь статистику половины вставок. Видимо, есть какие-то тонкости с четными и нечетными индексами. Во-вторых, InlineShape штука и вовсе загадочная. Никаких ошибок при конвертации не возникало, но и количество InlineShapes неизменно оказывалось нулевым. Подсчитать статистику вставок удалось только сохранив файл как RTF и расковыряв его код, но это стоит описать отдельно. Приводился же последний абзац в надежде, что кто-то с таким сталкивался и нашел способ работы с Shapes «встроенными» способами.

    Ну, вот практически и все. Суммируя все, что мы получили, имеем статистику документа даже точнее встроенной. Еще пара замечаний. Перед подсчетом Word стоит «спрятать», чтобы он не маячил на экране:

    При подсчете статистики, особенно если в документе содержится что-то кроме простого текста, считается, что в файл внесены изменения. Потому напоследок сохраняем и закрываем документ:

    Ну и, конечно, делаем серверу Word Disconnect, когда он станет нам уже не нужен.

    А теперь предупреждение тем, кто заинтересовался данным вопросом и хочет поэкспериментировать сам. Офис слишком тесно связан с Windows, потому на сбои в его работе система реагирует крайне остро. При отладке программ подсчета статистики у меня после ошибки часто появлялся «голубой экран». То же самое происходило, если после разбора RTF — файла в поисках Shapes и превращения их в обычный текст в Word загружался неправильно «собранный» файл. Так что очень рекомендуется предварительно сохранить важные данные или поставить систему понадежнее. У меня стоит WindowsXP, который к таким сбоям оказался нечуствителен. Кроме того, пока приведенное здесь не было отлажено, после ошибок частенько летел сам офис. Так что имейте под рукой дистрибутив для запуска диагностики офиса и устранения повреждений.

    Часть 3. Открытие документа используя VCL.

    Каждый, наверное, хоть раз сталкивался с необходимостью выдачи отчета. В Delphi имеются для этого специальные компоненты, но они налагают на нас достаточно строгие ограничения на форму представления данных. Одним из выходов может служить использование программы MS Word. Здесь не будем подробно обсуждать простейший вопрос, как открыть документ и добавить в него нужную строку текста, это есть практически в каждом учебнике по Delphi, приведем только самые необходимые сведения. А из литературы на эту тему особенно рекомендуется найти книжку А.Я. Архангельского «Язык SQL в Delphi 5». Но что может придать отчету такую читабельность, как представление результатов в систематизированном табличном виде? В данной статье и обсуждается вопрос программной работы с таблицами документа Word.

    Тут могут быть два пути. Первый — если мы знаем заранее структуру данных отчета, можем приготовить шаблон, куда в ячейки таблицы затем просто занесем нужные данные. И второй — создаем отчет с нуля, рисуем в документе таблицу, заполняем ее. При этом мы можем программно добавить или удалить строки и столбцы, объединить или разбить ячейки — почти все, что мы делаем в самом Word’e. Все, что понадобится — компоненты WordApplication и WordDocument с палитры Servers.

    Теперь все по порядку — открываем файл и приступаем. Предварительно объявляем переменную FileName, типа OleVariant, которой присваиваем строку с именем файла.

    Обратите внимание на количество параметров — «пустышек». Их число не совпадает с тем, что обычно приводится в книжках. Объясняется это тем, что «книжная» функция предназначена для MS Word 97, а такая запись для Word 2000 и Word XP.

    Создание нового документа выглядит проще:


    Здесь также ставим на пару «пустышек» больше — по тем же самым причинам. Кроме того, полезно будет сразу же отключить проверку орфографии, чтобы Word не тратил время понапрасну:

    По окончании работы нам надо сохранить или распечатать наш отчет:

    где переменная в скобках типа OleVariant, ей присваиваем строку с именем файла.

    Объект Range.

    В документе нас пока больше всего интересует объект Range, который нам понадобится при создании таблицы. Он представляет из себя кусок текста, который может включать в себя как весь текст документа, так и любую его часть. То есть:

    Первый наш объект включает в себя весь текст документа, у второго мы ограничили пределы 5-м и 15-м символами, третий представляет из себя весь последующий текст документа, начиная с 5-го символа. Объект имеет несколько полезных методов, например, с его помощью можем добавить текст в документ:

    Это мы вставили текст после выделенного Range. Точно также можем вставить текст и перед ним, для этого служит метод InsertBefore(). Текст, заключенный в объекте Range, можем получить так:

    Кроме того, с помощью Range можем изменить шрифт в пределах объекта. Пример:

    Если хотим отменить выделение жирным шрифтом, присваиваем 0. Аналогично можно сделать шрифт курсивом, подчеркнутым — наберите WordDocument1.Range.Font., и среда сама подскажет, какие могут быть варианты. Методы Select, Cut, Copy и Paste работают как в обычном тексте. С помощью Paste можем на место выбранного Range вставить не только строки, но и рисунок, находящийся в буфере обмена.

    Часть 4. Работа с таблицами.
    Работа со столбцами, строками и ячейками.

    Таблицы в документе Word образуют коллекцию Tables. Их количество можем узнать так:

    к отдельной таблице обращаемся по ее номеру:

    где i — целое число. В данном случае мы обращаемся к первой таблице, а вообще i может принимать значения от 1 до WordDocument1.Tables.Count. Если нам необходимо создать таблицу самим, следует поступить так:

    Эта таблица — единственное, что будет в документе, так как она заменяет собой указанный в числе параметров объект Range. В данном случае получаем таблицу на i строк и j столбцов. Если уже еcть какой-то текст, который надо сохранить, совершенно аналогичным образом можем указать пределы объекта Range:

    Переменные a и b должны быть объявлены как OleVariant.

    Ну вот, теперь у нас есть таблица. Неважно, содержалась она уже в документе или мы создали ее сами. Посмотрим, что же мы с ней можем сделать. Число столбцов и строк узнаем так:

    Здесь мы опять обратились к первой таблице, но можем работать с любой — надо только правильно указать ее номер. Теперь изменим ширину столбцов или высоту строк:

    Аналогично можем задавать размеры отдельных строк и столбцов:

    Здесь j — опять таки целое число, начинается от 1. Можем обратится к отдельной ячейке, прочитать или изменить содержащийся в ней текст:

    Здесь j и k целые переменные, изменяются от 1 до числа строк или столбцов соответственно. Присвоив данной величине строковое выражение, увидим, что оно появилось в ячейке (j,k). Несколько непривычно, но в таблицах Word на первом месте стоит именно номер строки. Можем также задать программно отступы от края ячеек, как для всей таблицы сразу, так и для отдельной ячейки:

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

    Кроме того, можем подогнать размеры ячеек по содержимому. Для этого вызываем метод AutoFit:

    Добавить строку или столбец также не представляет сложностей:

    Мы добавили строку внизу и столбец справа. Теперь вставим столбец в определенном месте таблицы:

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

    Теперь про объединение ячеек. Довольно просто:

    Мы объединили две соседние по горизонтали ячейки (j,k) и (j,k+1). При этом получается, что большая ячейка как бы имеет два «адреса». Аналогично надо действовать и при объединении по вертикали. Все точно так же, но с нумерацией ячеек после объединения двух соседних по вертикали начинается путаница и при попытке заполнить таблицу возникают ошибки.

    Теперь разобьем ячейки.

    Здесь мы разбили ячейку (j,k) на две по горизонтали. Переменные varcol и varrow типа OleVariant, это количество столбцов и строк, на которые разбивается данная ячейка. Здесь снова с нумерацией начинается чехарда, так что этот вопрос разбиения и объединения ячеек представляет скорее чисто теоретический интерес. В таких случаях лучше заранее приготовить шаблоны.

    Теперь для примера удалим из таблицы второй столбец или третью строку:

    Внешний вид таблицы.

    Простейшая таблица, конечно, смотрится не очень. Теперь посмотрим, как мы можем ее приукрасить. При желании все сделать посимпатичнее можем использовать текстуру. Выглядеть это будет так:

    Совершенно аналогично можем сделать текстуру в целом столбце или строке:

    Текстура задается шестнадцатеричной константой, список констант можно найти заголовочном файле Word2000.pas. Можно их использовать как в шестнадцатеричном, так и в символьном виде. Чтобы не загромождать материал, значения констант будут выноситься в «Приложение» в конце статьи. Сразу оговорюсь, что заливка будет черно-белая или в шкале серого. Заливку определенным цветом пока так и не удалось обнаружить. Самая первая константа означает отсутствие заливки. Ее можно использовать, чтобы отменить текстуру.

    Чтобы выделить что-нибудь важное, можем изменить шрифт текста в определенной ячейке. Для этого воспользуемся свойствами объекта Selection:

    В данном примере мы сделали цвет текста в ячейке (1,2) красным, выделили его курсивом и изменили размер на 16. Кроме того, можем сделать шрифт подчеркнутым, перечеркнутым и т.п.

    Еще один способ изменить внешний вид таблицы — использовать стилевые шаблоны Word’a. У таблицы имеется метод AutoFormat, который меняет внешний вид таблицы в соответствии с некими предопределенными стилями. В заголовочном файле он описан следующим образом:

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

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

    И еще об одном способе создания таблиц.

    Людям, интересующимся работой с MS Word, возможно, тоже попадались в интернете компоненты, превращающие в таблицу соответствующим образом отформатированный текст. Вот мы как раз и разберемся, как же они устроены. Здесь нам опять надо вспомнить про объект Range, а именно про имеющийся у него метод ConvertToTable. В заголовочном файле это выглядит так:

    Здесь опять видим все те же константы применения стиля, что и в автоформате. Только в отличие от него тут они ошибок не вызывают. Правда, есть у меня жуткое подозрение, что они все равно не работают и можем со спокойной совестью поставить вместо них «пустышки» — всех, кроме опять-таки, первых двух параметров «применения изменений». Теперь по порядку. Первый параметр у нас задает символ, которым будут отделяться ячейки одной строки нашей будущей таблицы, второй — число строк таблицы, третий — число столбцов, затем идет ширина столбцов. Следующая группа параметров задает стиль таблицы и особенности его применения, необходимые значения констант есть в таблице «Приложения». Последние три параметра задают подгонку размера ячеек по содержимому, но на самом деле не работают. Так что ставим вместо них EmptyParam. И, наконец, практический пример. Предположим, мы открыли новый документ и занесли в него нужный текст:

    Такую операцию повторим трижды, и у нас будет заготовка для таблицы на 4 столбца и 3 строки. Будущие столбцы отделяются символами табуляции, а строки — переходами на новую строку. Теперь выделяем объект Range — в данном случае это весь текст документа, и превращаем его в таблицу:

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

    Проделав все это, обнаруживаем, что наш текст превратился в таблицу. Все это несколько напоминает создание таблиц в HTML.

    Список некоторых констант.

    Смотрите файл Word2000.pas

    Описание Символьное обозначение Шестнадцатеричное
    Текстуры
    Некоторые константы текстур — откройте Word2000.pas в «блокноте», введите в диалог поиска «texture», и получите полный список.
    wdTextureNone $00000000
    wdTexture2Pt5Percent $00000019
    wdTexture7Pt5Percent $0000004B
    wdTexture35Percent $0000015E
    wdTexture62Pt5Percent $00000271
    wdTextureSolid $000003E8
    wdTextureDarkHorizontal $FFFFFFFF
    wdTextureCross $FFFFFFF5
    Формат таблицы
    Константы формата таблицы. Необходимы при использовании автоформата и преобразовании текста в таблицу.
    wdTableFormatNone $00000000
    wdTableFormatSimple1 $00000001
    wdTableFormatSimple3 $00000003
    wdTableFormatClassic1 $00000004
    wdTableFormatClassic3 $00000006
    wdTableFormatColorful1 $00000008
    wdTableFormatColumns1 $0000000B
    wdTableFormatGrid1 $00000010
    wdTableFormatGrid3 $00000012
    wdTableFormatList1 $00000018
    wdTableFormat3DEffects1 $00000020
    wdTableFormat3DEffects2 $00000021
    wdTableFormat3DEffects3 $00000022
    wdTableFormatContemporary $00000023
    wdTableFormatElegant $00000024
    wdTableFormatProfessional $00000025
    wdTableFormatSubtle1 $00000026
    wdTableFormatWeb3 $0000002A
    Стили таблицы
    Константы «применения изменений» стиля таблицы. В идеале предполагается, что можно задавать отдельно, изменять ли стиль границ, текста, цвета и т.д. В автоформате работают, мягко выражаясь, невразумительно, все время возникают какие-то непонятные ошибки.
    wdTableFormatApplyBorders $00000001
    wdTableFormatApplyShading $00000002
    wdTableFormatApplyFont $00000004
    wdTableFormatApplyColor $00000008
    wdTableFormatApplyAutoFit $00000010
    wdTableFormatApplyHeadingRows $00000020
    wdTableFormatApplyLastRow $00000040
    wdTableFormatApplyFirstColumn $00000080
    wdTableFormatApplyLastColumn $00000100
    Разделители
    Константы разделителей для конвертации текста в таблицу.
    wdSeparateByParagraphs $00000000
    wdSeparateByTabs $00000001
    wdSeparateByCommas $00000002
    wdSeparateByDefaultListSeparator $00000003
    Часть 5. Работа с текстом, рисунками и списками.
    Текст.

    Сначала о самом простом — добавлении в документ Word нужной строки текста. Поместим на форму компоненты WordDocument, WordApplication и WordParagraphFormat с палитры Servers. Нас интересуют в первую очередь свойство Range компонента WordDocument и свойство Selection компонента WordApplication. Классики утверждают, что они являются ссылкой на объекты Range и Selection. Range представляет из себя, проще говоря, кусок текста, это может быть как весь текст документа, так и любая его часть. Его пределы задаются двумя (или меньше) параметрами типа OleVariant. Например:

    Первый наш объект включает в себя весь текст документа, у второго мы ограничили пределы 5-м и 15-м символами, третий представляет из себя весь последующий текст документа, начиная с 5-го символа. Объект имеет несколько полезных методов, например, с его помощью можем добавить текст в документ:

    Это мы вставили текст после выделенного Range. Точно также можем вставить текст и перед ним, для этого служит метод InsertBefore(). Текст, заключенный в объекте Range, можем получить так:

    Кроме того, с помощью Range можем изменить шрифт в пределах объекта. Пример:

    Если хотим отменить выделение жирным шрифтом, присваиваем 0. Аналогично можно сделать шрифт курсивом, подчеркнутым — наберите WordDocument1.Range.Font., и среда сама подскажет, какие могут быть варианты. Методы Select, Cut, Copy и Paste работают как в обычном тексте. С помощью Paste можем на место выбранного Range вставить не только строки, но и рисунок, находящийся в буфере обмена.

    С помощью Range можем найти в документе нужную строку. Пусть в тексте содержится слово «picture». Например, нам на его место надо будет вставить рисунок.

    Такая процедура находит и выделяет нужный кусок текста.

    Теперь про Selection, представляющий из себя выделенный фрагмент документа. Если выделения нет, это текущая позиция курсора в документе. С его помощью можем вставить что-либо на место выделенного фрагмента, сделать выравнивание, изменить шрифт. Он также имеет методы InsertAfter() и InsertBefore():

    Форматирование выделенного текста происходит аналогично Range, например:

    Для выравнивания проще воспользоваться компонентом WordParagraphFormat. Сначала только нужно «подключить» его к выделенному фрагменту текста:

    Значения его свойства Alignment может принимать значения wdAlignParagraphCenter, wdAlignParagraphLeft, wdAlignParagraphRight, смысл которых очевиден. Имеются и методы Cut, Copy и Paste, которые в пояснениях вряд ли нуждаются:

    Убираем выделение с помощью метода Collapse. При этом необходимо указать, в какую сторону сместится курсор, будет ли он до ранее выделенного фрагмента или после:

    При этом выделение пропадет, а курсор займет позицию перед фрагментом текста. Если присвоить переменной значение wdCollapseEnd, то курсор переместится назад. Можно просто поставить в скобках «пустышку»:

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

    Рисунки.

    Логично было бы предположить, что рисунки документа будут представлять из себя коллекцию, аналогичную таблицам, и мы, обратившись к конкретной картинке, сможем менять ее свойства — обтекание, размер и т.д. Однако ничего подобного в WordDocument не обнаруживается. Потому возможности управления встраиваемыми в документ изображениями сильно ограничены.

    Простейший метод вставить в документ рисунок — по упомянутым причинам он же и единственный — скопировать его в Word из буфера обмена. Предположим, рисунок у нас находится в компоненте DBImage. Сначала нужно загнать его в буфер обмена:

    Теперь для его вставки следует воспользоваться методом Paste объектов Range или Selection: WordApplication1.Selection.Paste или WordDocument1.Range(a,b).Paste. Оставить для рисунка достаточное количество пустых строк и попасть в нужное место — это уже наша забота. Если он попадет посреди текста, вид будет довольно противный — при такой вставке обтекание текстом рисунка происходит как-то странно. Можно приготовить для отчета шаблон, где заменяем рисунком какое-либо ключевое слово. О том, как найти в документе нужный текст, см. выше.

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

    «Рамки» образуют коллекцию Frames, нумеруются целым индексом, пробегающим значения от 1 до WordDocument1.Frames.Count. Добавим в документ рамку, изменим ее размер и вставим рисунок:

    Здесь для простоты предполагается, что размер DBImage равен размеру самой картинки, а также что до этого рамок у нас в документе не было. Обратить внимание следует на несколько моментов. Размер рамки надо задавать до того, как копировать в нее рисунок. Иначе она будет иметь размер по умолчанию, под который замасштабируется и наша картинка. При попытке изменить размер рамки задним числом размер картинки уже не изменится. Кроме того, параметр Range при добавлении рамки часто никакой роли не играет. Рамка изначально все равно появится в левом верхнем углу документа, а указанный кусок текста при этом не пострадает. Но это только в том случае, если он не выделен. Если в документе есть выделение, рамка появится вместо выделенного фрагмента. Таким образом можем ее вставить в нужное место взамен какого-то ключевого слова.

    При желании можем ее подвигать в документе и «вручную». Для этого служат свойства горизонтального и вертикального позиционирования, которые задают ее отступ от левого верхнего «угла» документа:

    Отступ между краями рамки и текстом задается следующим образом:

    А теперь о масштабировании. Для этого достаточно длину и ширину рамки умножить на одно и то же число. Например:

    При этом наша картинка в полтора раза пропорционально растянется. Точно также можно и уменьшить, но делить, как и множить, следует на одно число. Растягивать длину и ширину по-разному у меня лично не получалось. Задавать размер опять-таки надо еще до вставки рисунка. Ну и, наконец, удаление рамки:

    Списки.

    Списки в документе образуют коллекцию Lists, к отдельному списку обращаемся WordDocument1.Lists.Item(i), где i целое число от 1 до WordDocument1.Lists.Count . на этом все. Нет методов, позволяющих не то что создать новый список, а даже добавить пункт к уже существующему. Ничего страшного, настоящие герои всегда идут в обход:)) Сейчас мы все же проделаем и то, и другое. Все что нам понадобится — свойство Range отдельного списка, то есть его текст без разделения на пункты, а также возможность его выделить:

    Для этого в любом случае потребуется заготовка. Неважно, вставлена она в общий шаблонный документ или хранится в отдельном файле. Заготовку делаем так: выбираем в меню Формат/Список, и сохраняем, если это отдельный шаблон списка. У нас появляется пустой список без текста с одним маркером. Далее вспоминаем, как мы делали списки вручную — писали текст, нажимали «Enter», появлялся новый элемент списка. Теперь то же самое, только программно. Предположим, у нас уже открыт документ с заготовкой, и мы хотим внести в список пункты «Item 1» и «Item 2»:

    То есть мы вставляем в документ текст первого пункта списка, он попадает на свое место. Потом посылаем в Word символ перехода строки, он честно переходит и тем самым сам создает нам второй пункт списка, куда и вставляем нужную строку. Ну и так далее, нужное количество раз. Последние две строки нужны, если список заготовлен в отдельном файле — после их выполнения список оказывается в буфере обмена. Здесь выгода в том, что можем иметь заготовки списков разных стилей и по ходу дела выбирать, какой список создать. Затем открываем документ, где должен быть список, выделяем с помощью Range нужный кусок, копируем из буфера обмена через WordDocument1.Range(a,b).Paste. Чтобы не испортить файл с заготовкой, можем сразу после открытия пересохранить его под другим именем, а можем просто выйти из него без сохранения изменений:

    Константа сохранения изменений может принимать значения

    Шестнадцатеричная Символьное обозначение
    $FFFFFFFF wdSaveChanges
    $00000000 wdDoNotSaveChanges
    $FFFFFFFE wdPromptToSaveChanges

    Первое значение сохраняет изменения, второе дает возможность выйти без сохранения изменений. Последняя константа вызывает при выходе стандартный диалог сохранения изменений. Можем сделать и несколько по-другому. Хотя мы не можем создать новый элемент списка, но текст в уже существующем изменить можно:

    Так что можно с помощью переходов строки создать нужное количество элементов, а затем их заполнить:

    Это было в предположении, что у нас один элемент списка в заготовке уже есть. Ну вот, в общем-то, и все про текст, списки и картинки.

    На этом наш цикл статей на тему «Delphi 4: Автоматизация приложений MS® Office® для эффективного анализа результатов» окончен. Надеемся они кому-нибудь принесут пользу.

    OLE-объект и проблема с его редактированием

    Здравствтвуйте, уважаемые коллеги!
    Собственно проблема такая! Вставляю ОLE-объект (документ WORD) в файл! Всё как обычно спрашивает высоту и прочее! После вставки объекта редактирование документа становится невозможно, а именно его растяжение и его перенос!
    Видимо что-то стоит стоит в настройках! Ну никак не могу побороть эту проблему!
    Если кто-то сталкивался с подобным подскажите как быть!

    Читал ранние темы подобной проблемы не нашёл!

    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL
    27.03.2009, 17:29 #1