На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
  
> Работаем с Word , COM
    ExpandedWrap disabled
      Если у Вас нет на панели инструментов закладки  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));
      У меня не получается выполнить обращение к строке таблицы Word
      (RowPtr)(Table->Rows->Item(1))->Select()
      Что я делаю не так?

      С объектами CellPtr никаких проблем.
        Table->Rows->Item(1)->Select()?
        Цитата
        Dimas51, 13.07.04, 12:19
        (RowPtr*)(Table->Rows->Item(1))->Select()
          [У меня не получается выполнить обращение к строке таблицы Word
          (RowPtr)(Table->Rows->Item(1))->Select()
          Что я делаю не так?

          А как добавить строку в конец Таблицы?
          В Worde новая строка Tabом создается, а если в проге
          суешь "\t" - не хочет
          Сообщение отредактировано: Леопольд -
            Цитата
            Леопольд, 17.07.04, 05:24
            а если в проге
            суешь "\t" - не хочет

            "\n"
              Цитата

              Не забудьте добавить в #include <COMOBJ.hpp>.
              #pragma link "Word_2K_SRVR"- для 2000
              #pragma link "Word_97_SRVR"- для 97

              А для Office XP?
                Цитата Budda, 7.10.04, 13:38
                А для Office XP?

                А это без разницы, главное версия Word'а
                  А если ворд 2002? Кстати, эта штука нужна только для компиляции. Так? У клиента будет работать независимо от указанной строки. Да?
                    Цитата Budda, 7.10.04, 14:58
                    У клиента будет работать независимо от указанной строки. Да?
                    Не факт. У разных версий Word'а разная функциональность.
                      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. Это что и зачем? И ещё много разных компонент. Хотел бы доку почитать, если где-то есть. Дайте, плиз, хотя бы линк
                        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));

                        Первое сообщение читали?
                          WordDocument1->Range(EmptyPar,EmptyPar)->InsertAfter("Test");

                          [C++ Error] untMain.cpp(30): E2034 Cannot convert 'char *' to 'wchar_t *'

                          ???

                          Bas, поделись плиз, источниками инфы, или хотя бы ключевыми словами, по которым искать нужно
                            L"Test"
                              Цитата Budda, 7.10.04, 17:04
                              WordDocument1->Range(EmptyPar,EmptyPar)->InsertAfter("Test");

                              ExpandedWrap disabled
                                WordDocument1->Range(EmptyPar,EmptyPar)->InsertAfter(StringToOleStr("Test"));
                              Поищи по форуму , кажеться я laifik скидывал и ссылки и архив.
                              Но всеравно главная инфа в хелпах Word,Excel.
                                Bas, Искал, искал... кучу линков топиков на тему нашёл, а вот твоих ссылок и архива - не нашёл...

                                Сейчас у меня проблема, что при компиляции WordApplication1->Visible получаю сообщение - метод недоступен... :(

                                А в Ворде - хэлпа нет на такие штуки... ?
                                  Скорее всего требуется:
                                  WordApplication1->Visible[0]
                                    Цитата Budda, 7.10.04, 19:11
                                    WordApplication1->Visible

                                    WordApplication1->Visible=true;
                                    Да у меня было чтото похоже когда переустановил систему и установил BCB - день мучался (ведь знал что работало). Но вспомнил что Update'ы не установил. После установки все пошло как надо.
                                    Автоматизация приложений Microsoft Office в примерах
                                      Цитата
                                      Но вспомнил что Update'ы не установил. После установки все пошло как надо

                                      По тому линку, что ты привёл - нет ни одного слова об Апдэйтах или обновлениях. Где их взять?

                                      И ещё: Как можно работать с Вордом без компонент, а используя ОЛЕ технологии?

                                      Добавлено
                                      Seva, нет
                                      ExpandedWrap disabled
                                        WordApplication1->Visible[0]=true;

                                      При компиляции выдает ошибку:
                                      Цитата
                                      [C++ Error] untMain.cpp(35): E2015 Ambiguity between 'TOLEBOOL::operator bool() const' and 'TOLEBOOL::operator short() const'
                                        Цитата Budda, 8.10.04, 12:44
                                        Как можно работать с Вордом без компонент, а используя ОЛЕ технологии?
                                        Так же, как и с другими приложениями. :)
                                        ExpandedWrap disabled
                                          Variant vApp;
                                          try {
                                             vApp = Variant::GetActiveObject("Word.Application");
                                          } catch(EOleSysError &ex) {
                                             try{
                                                vApp = Variant::CreateObject("Word.Application");
                                             } catch(EOleSysError &ex) {
                                                // не удалось запустить сервер
                                             } catch(...) {
                                                // неизвестная ошибка
                                             }
                                          } catch(...) {
                                             // не удалось подключиться к серверу
                                          }
                                        А далее через OlePropertyGet, OlePropertyPut, OleFunction, OleProcedure
                                        ExpandedWrap disabled
                                          Variant vDoc = vApp.OlePropertyGet("Documents").OleFunction("Open",имя_файла);
                                        и так далее. :)

                                        Добавлено
                                        P.S. Хотя компоненты работают с соответствующим сервером тоже через OLE :)
                                        Сообщение отредактировано: trainer -
                                          Выписка
                                          ExpandedWrap disabled
                                             
                                            Аббревиатура 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 поддерживает сервер.
                                            trainer, Спасибо!


                                            Bas, Это ты к чему?
                                              Цитата Budda, 8.10.04, 16:43
                                              Bas, Это ты к чему?

                                              Для общего развития.
                                                Bas, та мне бы чего-то попрактичнее, тот код, который Тренер дал - тоже сбоит... Ну просто 3.14здец какой-то.

                                                Может чего-то где-то в настройках.... Может кинешь маленький конкретный пример? seredaom@ukrpost.net.
                                                  Цитата Budda, 8.10.04, 18:03
                                                  который Тренер дал - тоже сбоит
                                                  В чем это проявляется и покажи свой исходник.
                                                    Исходник в студию или в приват.
                                                      Цитата Budda,8.10.04, 11:44
                                                      Seva, нет
                                                      ExpandedWrap disabled
                                                        WordApplication1->Visible[0]=true;

                                                      При компиляции выдает ошибку:
                                                      Цитата
                                                      [C++ Error] untMain.cpp(35): E2015 Ambiguity between 'TOLEBOOL::operator bool() const' and 'TOLEBOOL::operator short() const'

                                                      Ну подправь соответствующим образом.
                                                      Хочет TOLEBOOL? Попробуй так:
                                                      ExpandedWrap disabled
                                                         
                                                        WordApplication1->Visible[0]=TOLEBOOL(true);
                                                        Подскажите, пожалуйста, где скачать компоненты для работы с Office 2007.
                                                          Цитата dallas0713 @
                                                          Подскажите, пожалуйста, где скачать компоненты для работы с Office 2007.

                                                          Читай эту тему с начала.
                                                            Люди, подскажите пожалуйста, почему происходит следующее: при запуске программы в среде C++ Builder 6, она работает нормально, но когда запускаю экзешник вне среды, работает не совсем так как надо ???

                                                            Программа должна выполнять следующие действия:
                                                            1. Открыть файл *.doc, в котором есть формулы.
                                                            2. Сохранить во временный файл, но уже с расширением *.docx (Open XML Format)
                                                            3. Извлечь из временного файла формулы в виде картинок.

                                                            В среде выполняется всё норм. А "автономно" просит сохранить файл.

                                                            Вот код:
                                                            ExpandedWrap disabled
                                                              //---------------------------------------------------------------------------
                                                               
                                                              #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);
                                                               
                                                              }
                                                              //---------------------------------------------------------------------------

                                                            Заранеее благодарен ! :thanks:
                                                              При каком действии просит? Покажи скриншот диалога.
                                                                На будущее:
                                                                ExpandedWrap disabled
                                                                  void __fastcall TForm1::Button1Click(TObject *Sender) {
                                                                    if (!OpenDialog1->Execute())
                                                                      return;
                                                                    //-------------------------------------
                                                                    AnsiString fname = OpenDialog1->FileName;
                                                                    WordApplication1->Connect();
                                                                    // и всё остальное
                                                                  }
                                                                  Выяснил почему в среде разработки было норм, а сам экзешник не пахал...
                                                                  У меня стоит на компе: Windows 7 Pro x86, MS Office 2007, BCB 6.
                                                                  И я впомнил, что Борланд, я ставил в режиме совместимости с WinXP SP3, тогда работало. Потому попробывал совместить и сам экзешник... о, чудо, заработало. Думаю на WinXP будет работать.

                                                                  Да, в коде нужно исправить WordApplication1->set_DisplayAlerts(wdAlertsNone);
                                                                  но это было не существенно.

                                                                  Изените, пожалуйста за беспокойство!!! Спасибо :thanks: !!!

                                                                  Добавлено
                                                                  Цитата #SI# @
                                                                  На будущее:
                                                                  ExpandedWrap disabled
                                                                    void __fastcall TForm1::Button1Click(TObject *Sender) {
                                                                      if (!OpenDialog1->Execute())
                                                                        return;
                                                                      //-------------------------------------
                                                                      AnsiString fname = OpenDialog1->FileName;
                                                                      WordApplication1->Connect();
                                                                      // и всё остальное
                                                                    }

                                                                  Спасибо, эту проверку завтыкал... :blush:
                                                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                  0 пользователей:


                                                                  Рейтинг@Mail.ru
                                                                  [ Script execution time: 0,0696 ]   [ 16 queries used ]   [ Generated: 25.03.25, 02:37 GMT ]