mo_logoВ одной из статей, посвященных работе с Excel в Delphi читатель с ником Kanti задал весьма не тривиальную задачку — как добраться до диаграммы Excel, внедренной в документ Word и работать с ней. За что Kanti большое человеческое спасибо — приятно, когда читатели интересуются жизнью блога и предлагают новые темы и идеи.
На первый взгляд задача довольно не простая. Однако решение для неё есть. Я пошел немного дальше в решении проблемы и сегодня расскажу вам:

  • как работать с объектом Excel, внедренном в документ Word
  • как работать с документом Word, внедренным в Excel.

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

1. Азы работы с MS Word в Delphi

Запуск MS Word в принципе ни чем не отличается от запуска MS Excel за одним небольшим исключением — меняется параметр функции CreateOLEObject:

MyWord:=CreateOleObject('Word.Application');

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

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

MyExcel:=GetActiveOleObject('Word.Application')

MyExcel:=GetActiveOleObject('Word.Application')

Соответственно, чтобы не гадать запущена или не запущена та или иная программа пакета MS Office достаточно воспользоваться связкой двух функций:

try MyWord:=GetActiveOleObject('WordApplication'); except MyWord:=CreateOleObject('Word.Application'); end;

try MyWord:=GetActiveOleObject('WordApplication'); except MyWord:=CreateOleObject('Word.Application'); end;

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

MyWord.Documents.Open('myword.doc');

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

2. Как работать с объектом Excel, внедренном в документ Word

Каждый документ Word имеет коллекцию Shapes, которая позволяет добавлять в документ объекты, созданные и отображаемые с помощью программ-серверов OLE (OLE-серверов). OLE-объекты в документах Word могут отображаться также, как они отображаются в приложениях, предназначенных для их создания и редактирования. Все наверно пользовались редактором формул Math Type? Вот вам простой OLE-сервер. Добавляете OLE-объект формулы  в документ — открывается окно Math Type где вы вводите то, что хотите увидеть и потом формула отображается в документе Word.

Другое дело, когда Вы пробуете вставить в документ Word, например файл mp3. В этом случае объект будет отображен в документе в виде ярлыка, но, тем не менее будет внесен в коллекцию Shapes и до него можно будет добраться из Delphi.

insert_objectТеперь попробуем посмотреть как выглядит добавление OLE-объектов. В простейшем случае Вы открываете Word, создаете документ и выбираете «Правка — Вставить — Объект» и перед Вами открывается окно с перечнем всех OLE-объектов, которые Вы можете использовать в документе. Выбираете объект, вставляете в документ — работаете. Обратите внимание на рисунок — в окне на рисунке как раз отображены всевозможные объекты нашего с Вами исследования.

Для того, чтобы вставить OLE-объект в документ Word из Delphi необходимо воспользоваться методом AddOleObject коллекции Shapes, который имеет следующий вид:

Shapes.AddOleObject(ClassType, FileName, LinkToFile, DisplayAsIcon, IconFileName, IconIndex, IconLabel, Range)

ClassType — имя, используемое для включения указанного объекта OLE. Например, чтобы вставить в документ Word диаграмму Excel следует использовать

ClassType:='Excel.Chart'

ClassType:='Excel.Chart'

для добавления листа Excel, соответственно:

ClassType:='Excel.Sheet'

ClassType:='Excel.Sheet'

и так далее. В принципе ничего сложного нет — вставить можно, что угодно, хоть exe-файл :)

FileName — имя файла, из которого должен быть создан объект. Если этот аргумент опущен, то используется текущая папка. Вы должны указать либо ClassType либо  FileName, но никак не одновременно оба параметра.

LinkToFileTrue для того, чтобы связать OLE-объект с файлом, из которого он был создан. False, чтобы сделать объект OLE-объект независимым от копии файла, т.е. включить объект в документ Word. Если Вы определили значение для ClassType, аргумент LinkToFile должны быть ложными. Значение по умолчанию False.

DisplayAsIconTrue для отображения объекта OLE в виде значка. Значение по умолчанию False.

IconFileName — Файл, который содержит значок для отображения объекта OLE.

IconIndex -индекс иконки отображения из IconFileName. Значение по умолчанию — ноль.

IconLabel — подпись к иконке объекта.

Range — диапазон,  где объект OLE будет размещен в тексте. Объект OLE заменяет выбранный диапазон. Если этот аргумент опущен, объект вставляется автоматически (в текущую позицию курсора в документе).

Давайте теперь продемонстрируем использование этого метода на практике и, заодно, приготовим плацдарм для дальнейшей работы. Рассмотрим как можно вставить чистый лист Excel в документ Word. Причем вставим лист в нужные нам координаты и зададим ему (листу) длину и ширину:

var MyWord: OLEVariant; begin MyWord:=CreateOleObject('Word.Application'); MyWord.Visible:=true; MyWord.Documents.Open(doc); MyWord.ActiveDocument.Shapes.AddOLEObject(ClassType:='Excel.Sheet',Left:=10, Top:=10, Width:=400, Height:=300); end;

var MyWord: OLEVariant; begin MyWord:=CreateOleObject('Word.Application'); MyWord.Visible:=true; MyWord.Documents.Open(doc); MyWord.ActiveDocument.Shapes.AddOLEObject(ClassType:='Excel.Sheet',Left:=10, Top:=10, Width:=400, Height:=300); end;

Как видите, вместо того, чтобы указать объект Range мы просто расписали его параметры Left, Top, Width и Height. После выполнения этих операций в документе doc аккурат в верху страницы вставиться лист Excel.

Теперь, когда лист вставлен, можно приступать к дальнейшему изучению «глубин» OLE-серверов Microsoft.

Создадим новую переменную, в которой будем хранить ссылку на OLE-объект.

MyOLE: OLEVariant;

MyOLE: OLEVariant;

и сразу получим ссылку на наш лист Excel в Word’е:

MyOLE:=MyWord.ActiveDocument.Shapes.Item(1);

Так будет проще разбираться и избавит нас от лишней писанины.

Представим себе, что мы ничего абсолютно не знаем про то, что лежит в MyOLE. Знаем только то, что это элемент из коллекции Shapes и все. Как определить, что мы получили ссылку именно на объект Excel, а не на автофигуру или, ещё хуже, не на файл mp3?

Для того, чтобы получить всю необходимую информацию об OLE-объекте достаточно обратиться к объекту MS Word под названием OLEFormat.

OLEFormat имеет следующие свойства:

Свойство Описание Application Возвращает имя приложения к которому относится объект. В нашем случае вернет «Microsoft Word» ClassType Возвращает или устанавливает тип класса для указанного объекта OLE, фотографии или поля. Creator Возвращает 32-битное целое число, которое указывает на приложение в котором был создан объект. DisplayAsIcon True, если указанный объект отображается в виде значка. Свойство для чтения/записи IconIndex Возвращает или устанавливает индекс иконки, используемой если DisplayAsIcon True. IconLabel Возвращает или устанавливает подпись к иконке OLE-объекта. IconName Возвращает или устанавливает файл программы, в которой хранится икона для объекта OLE. IconPath Возвращает путь к файлу, в котором хранится иконка для объекта OLE Label Возвращает строку, которая используется, чтобы определить часть исходного файла для связывания объектов Object Возвращает объект, который представляет собой объект верхнего уровня интерфейса указанного объекта OLE Parent Возвращает объект, который представляет собой родительский объект указанного объекта OLEFormat ProgID Возвращает программный идентификатор (ProgID) для указанного объекта OLE.

Теперь, используя эти свойства, попробуем получить всю необходимую нам информацию об OLE-объекте.

Вызовем последовательно свойства ClassType и ProgID:

ShowMessage(MyOle.OLEFormat.ClassType); ShowMessage(MyOle.OLEFormat.ProgID);

В моем случае, результатом выполнения операций были две одинаковых строки «Excel.Sheet.12» Так как у меня установлен Office 2007 то версия 12, что и отразилось в сообщениях. У Вас это могут быть 10, 11 или как у меня 12 версии. С помощью номера версии можно будет определять — возможно ли в принципе изменять такие объекты на машине пользователя или нет.

Идем дальше. Итак, мы определили, что объект представляет собой лист Excel. Как получить доступ к Excel? И причем сделать это так, чтобы можно было наш OLE-объект изменить?

Обратимся к свойству Object. Согласно описанию, свойство должно вернуть нам ссылку на объект верхнего уровня. Следовательно, применительно к нашей ситуации — это будет ссылка на объект Excel. Чтобы убедиться в сказанном, сделаем так:

ShowMessage(MyOle.OLEFormat.Object.Application.Name);

то есть получим имя приложения в котором был создан объект. В результате получим сообщение в виде строки «Microsoft Excel«.

Ну, а теперь развязка вопроса — используя ссылку на Excel попробуем написать что-нибудь на листе, например, избитую фразу «Hello World!»:

MyOle.OLEFormat.Object.Application.ActiveSheet.Range['A1'].Value:='Hello World!';

Можете проверить — в ячейку А1 запишется строка. Здесь следует обратить внимание на то, что при записи в Excel мы не использовали свойства ActiveWorkBook, которое обычно предшествует свойству ActiveSheet. Все дело в том, что среди объектов OLE Office нет такого OLE-объекта — вставляется только лист либо диаграмма. По сути диаграмма — это два листа Sheet где на одном находится сам график, а на втором — данные к нему.

Вот таким простым и достаточно понятным способом можно добавлять, изменять и удалять OLE-объекты. Кстати, на досуге можете потренироваться вставлять, активировать, редактировать оле-объект сразу несколько различных OLE-объектов — принцип работы тот же. Получаете Object и используете его функции.

3. Как работать с документом Word, внедренным в Excel.

Надо сказать, что разработчики в Microsoft весьма неплохо потрудились, чтобы запутать бедных разработчиков :).  В начале все просто — как в Word. Есть Shapes у которого в свою очередь есть метод AddOLEObject, с практически теме же параметрами.

Далее, по логике вещей, у Shapes должно быть свойство-объект OLEFormat. Проверяем — действительно есть, но…свойства другие, точнее одно из свойств другое, а большинства вообще нет. Но, мы люди не гордые — будем управляться с тем, что есть:

Свойство Описание Application При использовании без классификатора объектов, это свойство возвращает объект приложения, представляющий приложение Microsoft Excel.
При использовании с объектом Qualifier, это свойство возвращает объект приложения, которое использовалось для создания объекта Object Возвращает OLE Automation объект ассоциированный с OLE объектом Parent Возвращает объект, который представляет собой родительский объект указанного объекта OLEFormat progID Возвращает программный идентификатор (ProgID) для указанного объекта OLE.

Как видите свойств не много. Главное, что осталось свойство Object — вот его мы и попробуем использовать в своих корыстных целях.

За что следует, наверное, сказать спасибо разработчикам Excel, так это за то, что они предусмотрели сразу объект OLEObjects предоставляющий нам в распоряжение все OLE-объекты листа. Используя этот объект мы минуем использование Shapes. Например так:

MyExcel.ActiveWorkBook.ActiveWorkSheet.OLEObjects.Count

Мы получаем число OLE-объектов документа.

MyExcel.ActiveWorkBook.ActiveWorkSheet.OLEObjects(1)

соответственно даст доступ к первому из OLE-объектов документа, а уж с ним-то нам и предстоит работать. Итак, рассмотрим следующую задачку: необходимо вставить в документ Excel пустой документ Word и написать в нем любую строку.

Чтобы не повторяться в применениях метода — вставим в Excel уже готовый документ Word из файла:

... MyExcel.ActiveWorkBook.ActiveSheet.OLEObjects.Add(FileName:=doc, Left:=10, Top:=10, Width:=300, Height:=300); MyOLE:=MyExcel.ActiveWorkBook.ActiveSheet.OLEObjects.item(1); MyOLE.Activate; ShowMessage(MyOle.ProgID); //убедимся, что объект относится к Word ShowMessage(MyOle.Object.Application.Name); //запросим имя приложения MyOle.Object.Application.ActiveDocument.Range.InsertAfter('Привет');....

...MyExcel.ActiveWorkBook.ActiveSheet.OLEObjects.Add(FileName:=doc, Left:=10, Top:=10, Width:=300, Height:=300); MyOLE:=MyExcel.ActiveWorkBook.ActiveSheet.OLEObjects.item(1); MyOLE.Activate; ShowMessage(MyOle.ProgID); //убедимся, что объект относится к Word ShowMessage(MyOle.Object.Application.Name); //запросим имя приложения MyOle.Object.Application.ActiveDocument.Range.InsertAfter('Привет');....

Обратите внимание, в данном случае мы использовали для работы с OLE-объектом не Shapes, а OLEObjects. Попробуйте воспроизвести те же самые действия как в случае работы с Excel из Word, т.е. воспользоваться свойством Object у объекта ObjectFormat. Думаю Вы будите «приятно» удивлены, т.к. в результате запроса имени приложения Вам вернется не Word как ожидалось, а Excel — следовательно работать с OLE-объектом становится невозможно.

Также следует отметить, что прежде, чем приступать к редактированию OLE-объекта, следует его предварительно активировать.

Вот так можно работать с Excel из Word и с Word из Excel и при этом не выходить из Delphi :). Ну, а для чего это использовать — решать Вам. Я только показал Вам возможности работы в Delphi с программами Word и Excel.

Предыдущая статья на тему работы с Excel в Delphi — «Excel в Delphi. Работа с объектом Range (диапазон)«

Следующая статья на тему работы с Excel в Delphi — «Создаем свои контролы на ленте Microsoft Office.«

Читайте также:


Источник: http://www.webdelphi.ru/2009/09/polnaya-avtomatizaciya-redaktiruem-obekty-excel-soderzhashhiesya-v-dokumentax-word-i-naoborot/


Рекомендуем посмотреть ещё:


Закрыть ... [X]

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


Как сделать оле-объект Полная автоматизация. Редактируем объекты Excel, содержащиеся
Как сделать оле-объект AutoCAD. Как вставить растровое изображение. - Форумы oektant. org
Как сделать оле-объект Как добавить фото "через OLE"? - MS Access - Киберфорум
Как сделать оле-объект Вставка объекта в электронной таблице Excel - Excel
Как сделать оле-объект Вставка объектов в поле с типом данных OLE
Как сделать оле-объект Форумы Как повернуть OLE -объект
Как сделать оле-объект Специальная вставка в AutoCAD
Как сделать оле-объект How to: Add OLE Objects to Applications