Главная
Новости, анонсы ...


 Опыты
Статьи, исходники
и прочее





Чернопятов Е.А. Автоматизация приложений MS Office. Часть 1.

Начало.

В этом разделе речь пойдет об автоматизации. Кто читал шаги о VBA на сайте ->Первые шаги, тот уже знает, что это такое, а кто не читал - надеюсь, поймет сейчас. Для простоты скажем так - автоматизация - это возможность управлять поведением других программ (серверов автоматизации) или их элементов из своей программы (контроллера). Например - вам хотелось бы, чтобы данные из вашей программы сами собой преобразовывались в отчет MS Word'a? Или считались в таблице Excel'я? Это реально, потому что все приложения MS Office представляют собой серверы автоматизации, и мы можем этим пользоваться.

ВАЖНОЕ ЗАМЕЧАНИЕ! Все, что рассматривается ниже, подразумевает наличие 2000 офиса. Для обладателей 97-ого будут особые пометки.

1. Подготовка.

Как всегда в ClassWizard'е подготовим проект . Запускаем VC++. Выбираем меню File и New. Далее Project и тип создаваемого приложения MFC AppWizard. В поле Project Name необходимо указать название проекта. Пусть это будет WordTest. В Step 1 выберем тип Dialog Based, в Step 2 "дополнительные параметры". Отключите About Box - он нам не нужен, также отключаем 3D Control, а это для красоты. Отключаем ActiveX Control, у нас очень простое приложение. Идем дальше. В Step 3 устанавливаем любую компоновку и нажимаем Finish. Проект готов. С помощью редактора ресурсов добавим на форму диалога кнопку. Назовем ее "Отчет", и зададим идентификатор ID_BUTTONREPORT . Все это проделывалось ранее и не должно вызывать трудностей.

240_1.gif (4855 b)

Опять-таки с помощью ClassWizard'а зададим обработчик нажатия на эту кнопку и назовем его OnButtonreport().

240_2.gif (5147 b)

После того, как мы подготовили проект, необходимо добыть у Word'a сведения о имеющихся в нашем распряжении его ресурсах (о как!). Каждое приложение МС-Офиса имеет при себе специальный файл, называемый "библиотекой типов". Именно в нем хранятся все сведения об объектах сервера автоматизации. Внутри себя приложения имеют иерархическую структуру. Самым верхним уровнем является Application (приложение), ниже которого лежат объекты и коллекции объектов. Объектами можно управлять напрямую, а из коллекции сначала нужно извлечь экземпляр, затем уже работать с ним. Но для нас все объекты и коллекции будут выглядеть просто как классы.

Для начала нам понадобятся такие объекты, как приложение и документ (Application и Document). Импортируем эти классы из библиотеки:

Вызовем ClassWizard, и нажмем кнопку AddClass.

240_3.gif (2537 b)

Как мы видим, класс можно создать заново (New...), а можно извлечь его из библиотеки типов (From type library... ). Выберите этот пункт, раскроется диалог выбора файла.

240_4.gif (4833 b)

Найдите на вашем компьютере папку "х:\Program Files\Microsoft Office\Office\" (название может отличаться, если при установке вы выбрали иной каталог) и выберите файл, который называется MSWORD9.OLB (для тех, у кого 97 офис - MSWORD8.OLB). Это и есть библиотека типов Word 'а. Перед вами откроется окошко вида:

240_5.gif (5196 b)

В нем в левом списке будут находиться все объекты Word'а. Выберите _Application, _Document и Documents, и нажмите кнопку Ok.

ClassWizard сгенерил классы по нашему запросу, и записал их в файлы, которые называются msword9.cpp и msword9.h . Файлы эти были автоматически включены в проект.

Подведем итоги: Приложения офиса представляют собой набор объектов, которыми можно управлять. Мы рассматриваем их как набор классов. Информация об объектах хранится в "библиотеке типов". С помощью ClassWizard'а на основе информации из этой библиотеки мы можем сгенерировать классы, содержащие данные и методы для работы с объектами Word'а.

2. Поехали!

Прежде чем мы поедем, хотим сказать, что в данных шагах не будет теоретического изложения СОМ и OLE. Хотя на самом деле это НЕОБХОДИМО знать, мы умышленно избегаем теории. Все наши шаги даются чисто с утилитарными целями - сделать, чтоб работало. Теорию можно изучить самостоятельно, и поверьте - это более продуктивно и интересно. Самое первое, что нужно сделать - это запусть приложение. Откуда мы знаем, что и как нам запускать? Очень просто. Сервера автоматизации заносят данные о себе и своих объектах в реестр, и к ним можно ображаться по символьным именам. Для Word'а (любого, независимо от версии) это "Word.Application". Вот так:

HKEY_CLASSES_ROOT\CLSID\{000209FF-0000-0000-C000-000000000046}\IndependentProgID = Word.Application

А если нам нужна какая-то специфичная версия - можно использовать еще одно имя "Word.Application.НомерВерсии". Вот оно:

HKEY_CLASSES_ROOT\CLSID\{000209FF-0000-0000-C000-000000000046}\ProgID = Word.Application.9. 

Но нам в реестр лезть не надо, за нас это сделает MFC .

В файл WordTest.cpp в функцию InitInstance() перед вызовом AfxEnableControlContainer(), т.е. в самом начале добавляем строки:

if(!AfxOleInit()) // Your addition starts here
{
	AfxMessageBox("Could not initialize COM dll");
	return FALSE;
}               // End of your addition

Это заставит проинициализироваться систему OLE. Если этого не сделать, то вызов CreateDispatch не сработает. В файл WordTestDlg.cpp добавим строчку:

#include "msword9.h"

а в нашу функцию OnButtonreport добавляем следующий код:

_Application app;  // app - это объект _Application, т.е. Word 9
if(!app.CreateDispatch("Word.Application")) //запустить сервер
{
	AfxMessageBox("Ошибка при старте Wordа!");
	return;
}
else
	app.SetVisible(TRUE); //и сделать его видимым

В принципе, можно компилировать и запускать.

Для работы с автоматизацией необходимо проинициализировать OLE (Object linking and embedding) функцией AfxOleInit. Это делается при инициализации нашего приложения в InitInstance. Далее, мы создаем экземпляр Word'а - app.CreateDispatch, и делаем его видимым app.SetVisible.

3. Ваши документы, пожалуйста!

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

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

Documents oDocs;
_Document oDoc;
COleVariant  covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//наша коллекция документов
oDocs = app.GetDocuments();
//добавить к ней новый документ
//Внимание! Если у вас Word 97 - то строчка будет такая:
//oDocs.Add(covOptional,covOptional);				//97
oDocs.Add(covOptional,covOptional,covOptional,covOptional);	//2000
//и получить его как экзепляр коллекции с номером 1
oDoc = oDocs.Item(COleVariant(long(1)));
//активизировать документ
oDoc.Activate();

Все общение с функциями осуществляется с помощью переменных OLE. Например, чтобы извлечь документ с номером 1, мы пишем "COleVariant(long(1))". Переменная CovOptional , созданная с такими параметрами, используется для указания необязятельных параметров при создании объекта.

Теперь добавим текст в наш документ. Для этого придется вернуться к первому пункту, и точно как в нем написано, добавить следующие классы:

Paragraphs, Paragraph, Selection

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

Paragraphs oPars;
Paragraph oPar;	
Selection oSel;
//получить выделение. Поскольку его нет, это будет позиция курсора
oSel = app.GetSelection();	
//параграфов в документе много, возникает коллекция.
//получить текущюю коллекцию
oPars = oSel.GetParagraphs();
//добавить новый параграф с установками по умолчанию
oPar = oPars.Add(covOptional);
// напечатать текст
oSel.TypeText("Мой первый текст!");

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


Следующая часть | Оглавление

Последние изменения от 09.08.2013




e-mail:  Yegor A. Blackheel

Поиск по сайту с помощью Yandex

 www.guestbook.ru - лучший сервер гостевых книг