
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.82] |
![]() |
|
![]() |
Сообщ.
#1
,
|
|
![]() ![]() Если у Вас нет на панели инструментов закладки Servers - то можно проделать следующее : Создаем новый пакет с использованием библиотеки типов. Выберите Project | Import Type library. Из списка зарегистрированных серверов выберите библиотеку типов Word (Microsoft Word 9.0 Object Library (на моем компьютере установлен Microsoft Office 2000, поэтому в списке присутствует 9.0, для предыдущих версий Office, номера версий будут меньше)). Укажите имя закладки палитры компонентов (Pallete Page), куда будут установлены новые классы - TWordGlobal, TWordApplication, TWordDocument, TWordFont, TWordParagraphFormat, TWordLetterContent. Выберите закладку Servers. Установите флажок General Component Wraper для генерации компонентов на основе библиотеки типов и размещения ее на палитре компонент, а затем нажмите кнопку Install. Установите сервер на палитру компонент. Если закладка - Servers есть то выше перечисленные действия делать не надо. Фундаментальным объектом любого приложения является Application. Давайте получим к нему доступ . · создаем новый проект; · на главную форму выкладываем компонент WordApplication с закладки Servers; · устанавливаем свойства компонента AutoConnect и AutoQuit в True; · запускаем приложение на выполнение. Не забудьте добавить в #include <COMOBJ.hpp>. #pragma link "Word_2K_SRVR"- для 2000 #pragma link "Word_97_SRVR"- для 97 Если у вас обе строки добавлены то не избежать ошибок Ambiguity between В большинстве случаев нам надо подключиться к уже существующему интерфейсу, а не создать его заново. Также это может быть необходимо, когда контроллер должен отслеживать события, происходящие в COM сервере. Рассмотрим следующий пример: · создаем новое приложение; · помещаем на форму компоненты WordApplication и WordDocument; · устанавливаем в True свойства AutoConnect и AutoQuit компонента WordApplication; · устанавливаем в значение ckAttachToInterface свойство ConnectKind для объекта WordDocument; · для события onDokumentChange прописываем такой код: · //производим подключение к текущему документу · WordDocument1->ConnectTo( WordApplication1.ActiveDocument); · //Контроллер добавляет новую строку в текущий документ · WordDocument1->Range->InsertAfter(#13+'Переход к документу'+#13+ · WordApplication1->ActiveDocument->Get_FullName+' произведен :'+ · DateTimeToStr(Now)); для события OnFormCreate прописываем следующее: · WordApplication1->Visible=true; После запуска приложения будет автоматически загружен Microsoft Word, создайте в нем несколько новых документов и "попереключайтесь" между ними. Вы увидите, что контроллер автоматизации добавляет новые строки в текущий активный документ. Точно так же можно управлять и сервером ExcelApplication. При создании новой рабочей книги на сервере, в контроллере будет проинициализировано событие onNewWorkBook, которое можно обработать аналогично примеру с Word. Теперь рассмотрим еще один пример. Пусть существует необходимость формировать некий отчет в виде документа Microsoft Word, для чего нами используется файл-шаблон (к примеру, с именем test.doc). Поля, которые должны быть заменены, помечены символом «~» или другим сиволом который не встречается в отчете .Необходимо получить данные, а затем заменить метки реальными данными, после чего сформированный документ должен быть отправлен на печать, сохранен. В test.doc имеется шапка таблицы и нам необходимо заполнить таблицу данными из запроса (может бать любой контейнер с данными). Создадим новый проект и поместим на форму компоненты WordApplication(WApp), WordDocument(WDoc) и кнопку (TButton). В качестве обработчика события нажатия на кнопку укажем следующий код: //Следующие переменные понадобятся нам для выполнения методов сервера OleVariant FileName; OleVariant oldStr,newStr; OleVariant EmptyPar=False; OleVariant Yes=True; FileName=GetCurrentDir()+"\\test.doc"; //Открываем шаблон документа WApp->Visible=false; // что бы не моргал при заполнении данными но можно поставить в true // тогда весь процесс заполнения , замены будет на экране WApp->Caption = StringToOleStr("Отчет");//Задание заголовка для окна Word WApp->Documents->Add(FileName,EmptyParam); WDoc->ConnectTo(WApp->ActiveDocument); //Связываем компонент с существующим интерфейсом /* WDoc->ConnectTo(WordApplication1->Documents->Item(ItemIndex)); Если есть несколько открытых документов. */ //Находим в документе метки и производим их замены oldStr=AnsiString("~1"); newStr=AnsiString("Метка 1"); WDoc->Range(EmptyParam,EmptyParam)->Find->Execute(oldStr, EmptyParam,EmptyParam,EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam,EmptyParam, newStr,Yes); TablePtr MyTable=WApp->ActiveDocument->Tables->Item(1) ; // получаем указатель на нашу таблицу RangePtr MyRange =MyTable->Range ; String s; TADOQuery * QF; Создадим запрос к примеру «select * from table1» как создавать запросы и работать с ними сдесь рассматривать не будем. В принципе это могут быть и таблицы (TTable) String pole; int Current=0; //счетчик QF->First(); long j; while (!QF->Eof) { MyTable->Rows->Add(); // вставляем новую строку в таблицу int fild= QF->Fields->Count; String nPole; for (int p=1 ;p<fild-3 ;p++) // цикл по полям { MyTable->Borders->set_OutsideLineWidth(wdLineWidth300pt); MyTable->Borders->set_InsideLineStyle(wdLineStyleThinThickSmallGap); nPole=Table1->Fields->Fields[j]->AsString;//Можно делать проверку на тип и формат данных MyTable->Cell(1,p)->Range->InsertAfter(StringToOleStr(nPole)); } QF->Next(); } FileName= GetCurrentDir()+"\\newtest.doc"; Сохраняем в формате Word 6.0/95 (*.doc) OleVariant EmptyS=StringToOleStr(""); WDoc->SaveAs(FileName,(OleVariant)104,EmptyParam, EmptyS,Yes,EmptyS, EmptyParam,EmptyParam, EmptyParam,EmptyParam,EmptyParam); WDoc->Close(EmptyParam,EmptyParam,EmptyParam); WApp->Visible=1; WApp->Disconnect(); Некоторые полезные замечания : MyTable->Cell(j,1)->VerticalAlignment=wdCellAlignVerticalCenter; MyTable->Cell(j,1)->Range->Paragraphs->Alignment=wdAlignParagraphCenter; //Создание таблицы WordApplication1->Selection->Font->Bold = false; WordApplication1->ActiveDocument->Tables->Add(WordApplication1->Selection->Range , MainFrm->Query???->RecordCount + 9, 6); Этот код, он вставляет данные после таблицы // String stn = "\n"; // String koltnS; // строка для форматирования общей суммы в ??? // koltnS = koltnS.FormatFloat("0.00000", QF->?????->Value); // stn = stn + " Сумма реализации: "+ koltnS; // WDoc->Range(EmptyParam,EmptyParam)->InsertAfter(StringToOleStr(stn)); // WordFont1->ConnectTo(WordDocument1->Sentences->get_Last()->get_Font()); // WordFont1->Size = 12; // WordFont1->Bold = true; // WordFont1->Color = wdColorIndigo; // Если понадобиться код объединения ячеек WordApplication1->Selection->Tables->Item(1)->Cell(4,1)-> Merge(WordApplication1->Selection->Tables->Item(1)->Cell(4,6)); Еще вариант сохранения док-та stn = MainFrm->DBEdit5->Text; int n = stn.Length(); if (n == 1) stn = "0" + stn; stn = "?????" + stn + MainFrm->Edit1->Text + ".doc"; //Сохранение документа WordDocument1->SaveAs(&TVariant(WideString(stn)), &TVariant(wdFormatDocument)); |
Сообщ.
#2
,
|
|
|
У меня не получается выполнить обращение к строке таблицы Word
(RowPtr)(Table->Rows->Item(1))->Select() Что я делаю не так? С объектами CellPtr никаких проблем. |
![]() |
Сообщ.
#3
,
|
|
Table->Rows->Item(1)->Select()?
Цитата Dimas51, 13.07.04, 12:19 (RowPtr*)(Table->Rows->Item(1))->Select() |
Сообщ.
#4
,
|
|
|
[У меня не получается выполнить обращение к строке таблицы Word
(RowPtr)(Table->Rows->Item(1))->Select() Что я делаю не так? А как добавить строку в конец Таблицы? В Worde новая строка Tabом создается, а если в проге суешь "\t" - не хочет |
![]() |
Сообщ.
#5
,
|
|
Цитата Леопольд, 17.07.04, 05:24 а если в проге суешь "\t" - не хочет "\n" |
Сообщ.
#6
,
|
|
|
Цитата Не забудьте добавить в #include <COMOBJ.hpp>. #pragma link "Word_2K_SRVR"- для 2000 #pragma link "Word_97_SRVR"- для 97 А для Office XP? |
![]() |
Сообщ.
#7
,
|
|
Цитата Budda, 7.10.04, 13:38 А для Office XP? А это без разницы, главное версия Word'а |
Сообщ.
#8
,
|
|
|
А если ворд 2002? Кстати, эта штука нужна только для компиляции. Так? У клиента будет работать независимо от указанной строки. Да?
|
Сообщ.
#9
,
|
|
|
Цитата Budda, 7.10.04, 14:58 Не факт. У разных версий Word'а разная функциональность. У клиента будет работать независимо от указанной строки. Да? |
Сообщ.
#10
,
|
|
|
WordDocument1->ConnectTo( WordApplication1.ActiveDocument);
Наверное должно быть так: WordDocument1->ConnectTo( WordApplication1->ActiveDocument); Да? А вот тут проблемы: На строчку: WordDocument1->Range->InsertAfter Компилятор ругается: [C++ Error] untMain.cpp(26): E2288 Pointer to structure required on left side of -> or ->* Требует что-то поставить после Range. Что делать? И есть ли дока на эти компоненты? WordApplication, WordDocument? У меня в палитре есть ещё и WordGlobal. Это что и зачем? И ещё много разных компонент. Хотел бы доку почитать, если где-то есть. Дайте, плиз, хотя бы линк |
![]() |
Сообщ.
#11
,
|
|
WordDocument1 это и есть WDoc.
Цитата Bas, 14.04.04, 17:07 WDoc->ConnectTo(WApp->ActiveDocument); Цитата Bas, 14.04.04, 17:07 WDoc->Range(EmptyParam,EmptyParam)->; Цитата Bas, 14.04.04, 17:07 // WDoc->Range(EmptyParam,EmptyParam)->InsertAfter(StringToOleStr(stn)); Первое сообщение читали? |
Сообщ.
#12
,
|
|
|
WordDocument1->Range(EmptyPar,EmptyPar)->InsertAfter("Test");
[C++ Error] untMain.cpp(30): E2034 Cannot convert 'char *' to 'wchar_t *' ??? Bas, поделись плиз, источниками инфы, или хотя бы ключевыми словами, по которым искать нужно |
Сообщ.
#13
,
|
|
|
L"Test"
|
![]() |
Сообщ.
#14
,
|
|
Цитата Budda, 7.10.04, 17:04 WordDocument1->Range(EmptyPar,EmptyPar)->InsertAfter("Test"); ![]() ![]() WordDocument1->Range(EmptyPar,EmptyPar)->InsertAfter(StringToOleStr("Test")); Но всеравно главная инфа в хелпах Word,Excel. |
Сообщ.
#15
,
|
|
|
Bas, Искал, искал... кучу линков топиков на тему нашёл, а вот твоих ссылок и архива - не нашёл...
Сейчас у меня проблема, что при компиляции WordApplication1->Visible получаю сообщение - метод недоступен... ![]() А в Ворде - хэлпа нет на такие штуки... ? |
Сообщ.
#16
,
|
|
|
Скорее всего требуется:
WordApplication1->Visible[0] |
![]() |
Сообщ.
#17
,
|
|
Цитата Budda, 7.10.04, 19:11 WordApplication1->Visible WordApplication1->Visible=true; Да у меня было чтото похоже когда переустановил систему и установил BCB - день мучался (ведь знал что работало). Но вспомнил что Update'ы не установил. После установки все пошло как надо. Автоматизация приложений Microsoft Office в примерах |
Сообщ.
#18
,
|
|
|
Цитата Но вспомнил что Update'ы не установил. После установки все пошло как надо По тому линку, что ты привёл - нет ни одного слова об Апдэйтах или обновлениях. Где их взять? И ещё: Как можно работать с Вордом без компонент, а используя ОЛЕ технологии? Добавлено Seva, нет ![]() ![]() WordApplication1->Visible[0]=true; При компиляции выдает ошибку: Цитата [C++ Error] untMain.cpp(35): E2015 Ambiguity between 'TOLEBOOL::operator bool() const' and 'TOLEBOOL::operator short() const' |
Сообщ.
#19
,
|
|
|
Цитата Budda, 8.10.04, 12:44 Так же, как и с другими приложениями. Как можно работать с Вордом без компонент, а используя ОЛЕ технологии? ![]() ![]() ![]() Variant vApp; try { vApp = Variant::GetActiveObject("Word.Application"); } catch(EOleSysError &ex) { try{ vApp = Variant::CreateObject("Word.Application"); } catch(EOleSysError &ex) { // не удалось запустить сервер } catch(...) { // неизвестная ошибка } } catch(...) { // не удалось подключиться к серверу } ![]() ![]() Variant vDoc = vApp.OlePropertyGet("Documents").OleFunction("Open",имя_файла); ![]() Добавлено P.S. Хотя компоненты работают с соответствующим сервером тоже через OLE ![]() |
![]() |
Сообщ.
#20
,
|
|
Выписка
![]() ![]() Аббревиатура OLE обозначает Objects Linked and Embedded (Присоединенные И Встроенные Объекты - ПИВО ;) ). Данные, разделяемые между приложениями называются OLE объектом. Приложение, которое может содержать OLE объекты, называют OLE контейнером (OLE Container). Приложение, данные из которого можно включить в OLE контейнер в виде OLE объекта, называют OLE сервером. Например, MicroSoft Word может включать в документ графические объекты, аудио- и видеоклипы и множество других объектов (такой документ иногда называют составным документом - compound document). Как следует из названия, OLE объекты можно либо присоединить к OLE контейнеру, либо включить в него. В первом случае данные будут храниться в файле на диске, любое приложение будет иметь доступ к этим данным и сможет вносить изменения. Во втором случае данные включаются в OLE контейнер и только он сможет просматривать и модифицировать эти данные. OLE является дальнейшим развитием идеи разделяемых между приложениями данных. Если с помощью DDE можно было работать с текстом, то OLE позволяет легко встроить в приложение обработку любых типов данных. Как и в случае с DDE, для правильной работы приложения-клиента (OLE контейнера) требуется наличие приложения OLE сервера. Каждый раз, когда в программе-клиенте пользователь обращается к OLE объекту с целью просмотра или редактирования данных (обычно двойной щелчок мышкой на объекте), запускается приложение- сервер, в котором и происходит работа с данными. В природе существует несколько видов OLE, отличающихся по способу активации OLE сервера. OLE версии 1 запускает сервер в отдельном окне. OLE 2 реализует то, что называется in-place activation and editing. Развитие идеи OLE привело к появлению OLE automation - приложение-клиент может выполнить часть кода сервера. Тип OLE объекта, помещенного в программу-клиент, определяется тем, какую версию OLE поддерживает сервер. |
Сообщ.
#21
,
|
|
|
trainer, Спасибо!
Bas, Это ты к чему? |
![]() |
Сообщ.
#22
,
|
|
Цитата Budda, 8.10.04, 16:43 Bas, Это ты к чему? Для общего развития. |
Сообщ.
#23
,
|
|
|
Bas, та мне бы чего-то попрактичнее, тот код, который Тренер дал - тоже сбоит... Ну просто 3.14здец какой-то.
Может чего-то где-то в настройках.... Может кинешь маленький конкретный пример? seredaom@ukrpost.net. |
Сообщ.
#24
,
|
|
|
Цитата Budda, 8.10.04, 18:03 В чем это проявляется и покажи свой исходник. который Тренер дал - тоже сбоит |
![]() |
Сообщ.
#25
,
|
|
Исходник в студию или в приват.
|
Сообщ.
#26
,
|
|
|
Цитата Budda,8.10.04, 11:44 Seva, нет ![]() ![]() WordApplication1->Visible[0]=true; При компиляции выдает ошибку: Цитата [C++ Error] untMain.cpp(35): E2015 Ambiguity between 'TOLEBOOL::operator bool() const' and 'TOLEBOOL::operator short() const' Ну подправь соответствующим образом. Хочет TOLEBOOL? Попробуй так: ![]() ![]() WordApplication1->Visible[0]=TOLEBOOL(true); |
Сообщ.
#27
,
|
|
|
Подскажите, пожалуйста, где скачать компоненты для работы с Office 2007.
|
Сообщ.
#28
,
|
|
|
Цитата dallas0713 @ Подскажите, пожалуйста, где скачать компоненты для работы с Office 2007. Читай эту тему с начала. |
Сообщ.
#29
,
|
|
|
Люди, подскажите пожалуйста, почему происходит следующее: при запуске программы в среде C++ Builder 6, она работает нормально, но когда запускаю экзешник вне среды, работает не совсем так как надо ???
Программа должна выполнять следующие действия: 1. Открыть файл *.doc, в котором есть формулы. 2. Сохранить во временный файл, но уже с расширением *.docx (Open XML Format) 3. Извлечь из временного файла формулы в виде картинок. В среде выполняется всё норм. А "автономно" просит сохранить файл. Вот код: ![]() ![]() //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "Word_2K_SRVR" #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { AnsiString fname; OpenDialog1->Execute(); fname=OpenDialog1->FileName; if (fname!="") { WordApplication1->Connect(); WordApplication1->set_Visible(false); WordApplication1->GetDefaultInterface()->Visible = false; WordApplication1->set_DisplayAlerts(false); WordApplication1->Documents->Open(TVariant(fname)); WordApplication1->ActiveDocument->Select(); WordApplication1->Selection->Copy(); WordApplication1->Documents->Add(EmptyParam, EmptyParam); WordDocument1->ConnectTo(WordApplication1->ActiveDocument); WordDocument1->Activate(); WordApplication1->Selection->Paste(); WordDocument1->SaveAs(TVariant("c:\\~temp.docx")); WordDocument1->Close(TVariant(false)); WordApplication1->Quit(TVariant(false)); WordApplication1->Disconnect(); ZipForge1->FileName="c:\\~temp.docx"; ZipForge1->OpenArchive(fmOpenRead); ZipForge1->ExtractFiles(L"*.wmf"); ZipForge1->CloseArchive(); DeleteFileA("c:\\~temp.docx"); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { ShellExecute(NULL,"open","word\\media", NULL, NULL, SW_SHOWNORMAL); } //--------------------------------------------------------------------------- Заранеее благодарен ! ![]() |
Сообщ.
#30
,
|
|
|
При каком действии просит? Покажи скриншот диалога.
|
Сообщ.
#31
,
|
|
|
На будущее:
![]() ![]() void __fastcall TForm1::Button1Click(TObject *Sender) { if (!OpenDialog1->Execute()) return; //------------------------------------- AnsiString fname = OpenDialog1->FileName; WordApplication1->Connect(); // и всё остальное } |
Сообщ.
#32
,
|
|
|
Выяснил почему в среде разработки было норм, а сам экзешник не пахал...
У меня стоит на компе: Windows 7 Pro x86, MS Office 2007, BCB 6. И я впомнил, что Борланд, я ставил в режиме совместимости с WinXP SP3, тогда работало. Потому попробывал совместить и сам экзешник... о, чудо, заработало. Думаю на WinXP будет работать. Да, в коде нужно исправить WordApplication1->set_DisplayAlerts(wdAlertsNone); но это было не существенно. Изените, пожалуйста за беспокойство!!! Спасибо ![]() Добавлено Цитата #SI# @ На будущее: ![]() ![]() void __fastcall TForm1::Button1Click(TObject *Sender) { if (!OpenDialog1->Execute()) return; //------------------------------------- AnsiString fname = OpenDialog1->FileName; WordApplication1->Connect(); // и всё остальное } Спасибо, эту проверку завтыкал... ![]() |