Январь/Февраль 2004


Советы, рекомендации, опыт


Полтавский П. В.
peter63@interfintrade.ru
разработчик ПО
Компания: GCProjects
(www.cgprojects.ru)

Применение OLE Automation в Oracle Forms 6i для генерации отчетов в формате MS Word.

  1. Постановка задачи.

    Одной из проблем, возникающих при формировании пользовательской отчетности, является получение результирующего отчета в формате, удобном для последующей обработки сотрудниками бизнес-подразделений. Стандартные средства разработки отчетов (Oraclr Reports, Crystal Reports и другие) имеют возможности генерации отчетов в формате приложений MS Office (Ms Word, MS Excel), но их внешний вид зачастую не удовлетворяет предъявляемым требованиям. Oracler Forms 6i включает инструментальное средство (встроенный пакет OLE2), позволяющее реализовать практически любой отчет непосредственно в формате документов MS Word, MS Excel и любого другого приложения, поддерживающего технологию OLE. В данной статье рассматриваются некоторые возможности использования пакета OLE2 для формирования отчетов MS Word.

  2. Технология разработки.

Процесс создания отчета можно разбить на следующие этапы:

  • создание файла-шаблона документа MS Word. Этот файл представляет внешний вид конкретного документа отчета (например, договора на брокерское обслуживание). Содержит фрагменты текста (далее по тексту поля замены), предназначенные для заполнения данными из БД.
  • создание PL/SQL процедуры, которая обеспечивает генерацию результирующего отчета (как правило, эта процедура базируется на прикладной .PLL библиотеке, реализующей вызовы процедур и функций пакета OLE2)
  1. Структура файла-шаблона.
    Рассмотрим правила формирования шаблона на примере следующего фрагмента:

    --
    --

    ДОГОВОР
    купли-продажи ценных бумаг №

    г. Москва “ 12 ” июля 2003 г.
    ООО “Рога и копыта”, именуемое в дальнейшем “Продавец”, в лице Генерального директора #FIO#., действующего на основании Устава, с одной стороны,


    --
    --

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

     

  2. Процедура формирования отчета.

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

    PROCEDURE Gen_Word_Doc (…) IS
    …
    v_is_visible      VARCHAR2(5);
    v_app_ptr         OLE2.obj_type;
    v_doc_ptr         OLE2.obj_type;
    v_is_release_obj  BOOLEAN;
    
    --
    v_open_tpl_doc   VARCHAR2(300);
    v_new_doc   VARCHAR2(300);
    …
    BEGIN
    
     
     
    -- Открываем MS Word в режиме, когда просмотр окна приложения недоступен 
    -- (обеспечивается фактическим параметром ‘FALSE’ ).  
    -- Переменная v_app_ptr содержит указатель на объект открытого приложения.
    
    STD_SYSTOR_OLE_Supp.New_App_Word ('FALSE',                         
    
                          v_app_ptr,                         
                          FALSE);
    

    -- Открываем шаблон договора (см. п. 3). Переменная v_open_tpl_doc содержит полный путь к файлу шаблона -- (например, C:\My_Template\agr_tpl.doc), v_doc_ptr содержит указатель на открытый документ MS Word, в -- который скопировано содержимое шаблона.

    STD_SYSTOR_OLE_Supp.Open_Word_Doc (v_open_tpl_doc,                        
                          v_app_ptr,
                          v_doc_ptr,
                          FALSE);                                                 
    

    -- Сохраняем шаблон как другой документ в каталоге отчетов. Переменная v_new_doc содержит полный путь -- к сохраняемому файлу (например, C:\My_Reports\my_rep.doc), v_doc_ptr содержит указатель на открытый -- и сохраненный документ.

    STD_SYSTOR_OLE_Supp.Save_Word_Doc (v_new_doc,                         
    v_app_ptr,   
    
    v_doc_ptr,                       
    'SAVEAS',                                         
    FALSE);
    

    -- Производим контекстную замену реквизитов в сохраненном документе. Значение фактического параметра --‘#FIO#' служит для поиска поля замены #FIO# (см. п. 3) в теле шаблона договора. Если поле замены найдено, -- то оно замещается значением фактического параметра ‘Иванов Иван Иванович’.

    STD_SYSTOR_OLE_Supp.Replace_By_Pattern (v_app_ptr,                         
                          '#FIO#',
                          ‘Иванов Иван Иванович’,  
    -- вместо этого обычно передается информация из БД 
                          FALSE);           
    
    -- Сохраняем сделанные изменения в открытом документе, v_doc_ptr содержит указатель на открытый -- и сохраненный документ.
    STD_SYSTOR_OLE_Supp.Save_Word_Doc 
                  (v_new_doc,                         
    
                   v_app_ptr,   
                   v_doc_ptr,                       
                   'SAVE',                                         
                   FALSE);
           
    -- Закрываем созданный документ. 
    STD_SYSTOR_OLE_Supp.Close_Word_Doc(v_doc_ptr);
    
    -- Закрываем экземпляр приложения MS Word
    STD_SYSTOR_OLE_Supp.Exit_App_Word(v_app_ptr);
    
    END Gen_Word_Doc;
    

    По завершении выполнения данной процедуры фрагмент сформированного документа Word будет следующим: --
    --

    ДОГОВОР
    купли-продажи ценных бумаг №

    г. Москва “ 12 ” июля 2003 г.

    ООО “Рога и копыта”, именуемое в дальнейшем “Продавец”, в лице Генерального директора Иванов Иван Иванович, действующего на основании Устава, с одной стороны,

    --
    --
    
  3. PLL библиотека.

    Рассмотрим набор процедур и функций пакета STD_SYSTOR_OLE_Supp (содержится в библиотеке STD_SYSTOR_OLE.pll), которые непосредственно реализуют обращения к пакету OLE2 (Oracle Forms 6i).

    --
    -- Процедура создает новое приложение MS Word
    
    --
    PROCEDURE New_App_Word ( p_is_visible     IN varchar2,                         
                          p_app_ptr        IN OUT ole2.obj_type,                         
                          p_is_release_obj IN boolean
                           )
    IS
     v_app           ole2.obj_type;  
    begin 
     
     v_app:=OLE2.Create_Obj('Word.Application');      
     OLE2.Set_Property(v_app,'Visible', p_is_visible);
     
     if (p_is_release_obj) then    
        OLE2.Release_Obj(v_app);
     end if;	
     
     p_app_ptr:=v_app; 
    end;	
    
    --
    -- Процедура создает новый пустой документ MS Word и возвращает указатель на него
    --
    PROCEDURE New_Word_Doc ( p_app_ptr        IN ole2.obj_type,
                          p_doc_ptr        IN OUT ole2.obj_type,
                          p_is_release_obj IN boolean                                          
                           )
    IS 
     v_doc      ole2.obj_type; 
    begin
     
     v_doc:=OLE2.Get_Obj_Property(p_app_ptr,'Documents'); 
     OLE2.Invoke(v_doc, 'Add');   
     
     if p_is_release_obj then
        OLE2.Release_Obj(v_doc);
        OLE2.Release_Obj(p_app_ptr);
     end if;	
     -- 
    
     p_doc_ptr:=v_doc; 
    end;	
    --
    -- Процедура открывает документ MS Word и возвращает указатель на него
    --
    PROCEDURE Open_Word_Doc (p_doc_file       IN     varchar2,                        
                          p_app_ptr        IN     ole2.obj_type,
                          p_doc_ptr        IN OUT ole2.obj_type,
                          p_is_release_obj IN boolean                                                        
                             )
    IS
     v_app      ole2.obj_type;
     v_doc      ole2.obj_type; 
     v_arglist  OLE2.List_Type;
    begin
     
     v_arglist := OLE2.Create_Arglist;
     OLE2.Add_Arg(v_arglist, p_doc_file); 
     
     v_doc:=OLE2.Get_Obj_Property(p_app_ptr,'Documents');
    
     OLE2.Invoke(v_doc, 'Open', v_arglist);   
     OLE2.DESTROY_ARGLIST(v_argList);
      
     if p_is_release_obj then
        OLE2.Release_Obj(v_doc);
        OLE2.Release_Obj(p_app_ptr);
     end if;	
     --
     p_doc_ptr:=v_doc;     	
    end;	
    --
    -- Процедура сохраняет активный документ MS Word в файл с указанным именем 
    -- и возвращает указатель на него
    --
    PROCEDURE Save_Word_Doc (p_doc_file       IN     varchar2 default NULL,                         
                          p_app_ptr        IN     ole2.obj_type,   
                          p_doc_ptr        IN OUT ole2.obj_type,                       
                          p_save_method    IN varchar2, -- Save/SaveAs                                         
                          p_is_release_obj IN boolean
                             )
    IS
    
     v_arglist   OLE2.List_Type;
     v_saved_doc OLE2.obj_type;
    begin
     
     v_saved_doc:=OLE2.Get_Obj_Property(p_app_ptr,'ActiveDocument');
     
     if (upper(p_save_method) = 'SAVEAS') then 
         v_arglist := OLE2.Create_Arglist;
         OLE2.Add_Arg(v_arglist, p_doc_file);       
         OLE2.Invoke(v_saved_doc, 'SaveAs', v_arglist); 
         OLE2.DESTROY_ARGLIST(v_argList); 
     elsif (upper(p_save_method) = 'SAVE') then    
         OLE2.Invoke(v_saved_doc, 'Save');   
     end if;	  
     
     if (p_is_release_obj) then
        OLE2.Release_Obj(v_saved_doc);
        OLE2.Release_Obj(p_app_ptr);
     end if;	
     -- 
     p_doc_ptr:=v_saved_doc;	
    end;	
    
    --
    -- Процедура выполняет контекстную замену по образцу в документе MS Word
    -- 
    PROCEDURE Replace_By_Pattern (p_app_ptr        IN OUT ole2.obj_type,                         
                          p_find_str       IN varchar2,
                          p_repl_str       IN varchar2, 
                          p_is_release_obj IN boolean                    
                                 )
    IS 
     v_exec             OLE2.obj_type;
     v_arglist           ole2.list_type; 
     --
     C_WD_FIND_CONTINUE  CONSTANT INTEGER:=1; -- непрерывный поиск
     C_WD_REPLACE_ALL    CONSTANT INTEGER:=2; -- замена всех вхождений
    begin  
     v_arglist := OLE2.Create_Arglist; 
     --
     OLE2.Add_Arg(v_argList, p_find_str); 
     OLE2.Add_Arg(v_argList, TRUE);  
     OLE2.Add_Arg(v_argList, TRUE);  
     OLE2.Add_Arg(v_argList, FALSE);  
     OLE2.Add_Arg(v_argList, FALSE);  
     OLE2.Add_Arg(v_argList, FALSE);  
    
     OLE2.Add_Arg(v_argList, TRUE);  
     OLE2.Add_Arg(v_argList, C_WD_FIND_CONTINUE);  
     OLE2.Add_Arg(v_argList, FALSE);  
     OLE2.Add_Arg(v_argList, p_repl_str); 
     OLE2.Add_Arg(v_argList, C_WD_REPLACE_ALL);
     --
     
    v_exec:= OLE2.Get_Obj_Property(OLE2.Get_Obj_Property
        (OLE2.Get_Obj_Property(p_app_ptr,'ActiveDocument'),'Content'),'Find');
    
    OLE2.Invoke(v_exec, 'Execute', v_argList);
     --
     OLE2.DESTROY_ARGLIST(v_argList);
       
     if (p_is_release_obj) then    
        OLE2.Release_Obj(p_app_ptr);
     end if;	
    
    end;
    --
    -- Процедура закрывает документ MS Word
    --
    PROCEDURE Close_Word_Doc (p_doc_ptr     IN ole2.obj_type                                            
                             )
    
    IS 
    begin 
     OLE2.Invoke(p_doc_ptr, 'Close'); 
     OLE2.Release_Obj(p_doc_ptr); 
    end;	
    --
    -- Процедура закрывает MS Word и возвращает указатель на него
    --
    PROCEDURE Exit_App_Word (p_app_ptr IN ole2.obj_type                         
                            )
    IS 
    begin  
     OLE2.Invoke(p_app_ptr, 'Quit'); 
     OLE2.Release_Obj(p_app_ptr); 
    end;	
    
  4. Выводы.

    Использование технологии, описанной в данной статъе, позволяет:

    • интегрировать сформированные отчеты с популярными офисными приложениями (MS Word)
    • использовать мощные средства программирования, предоставляемые OLE-сервером приложений
E-mail this page