скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Автоматизация документов WORD



Автор: Клименко Константин

1. Для чего и для кого

В настоящий момент везде, или почти везде, для работы с текстовыми документами используется Word от Microsoft. Причем, когда читаешь в объявлениях о приеме на работу программиста в фирму не занимающейся разработкой ПО, то с уверенностью можно сказать, что необходим человек, умеющий работать с офисным пакетом (Word, Excel, Access) от вышеупомянутой фирмы. Поэтому данным материалом хотелось бы показать, как можно в некоторых случаях упростить работу с текстовым редактором Word. Для этого не обязательны знания Delphi на профессиональном уровне, достаточно уметь создавать динамически подключаемые библиотеки (DLL) и знать основы VBA для Word. К тому же макроязыки используются не только в пакете от Microsoft, слышал, что аналог VBA есть и в StarOffice.

2. Как подключить DLL в VBA

Любая программа может вызвать функцию из DLL, которая написана на Delphi, независимо от того, написана она на Си, Visual Basic или VBA. Первый вопрос, который может волновать - как это сделать в VBA для Word?
Для вызова DLL в VBA для Word существует специальная функция:
[Public | Private]Declarefunction name Lib "libname"[Alias
  "aliasname"][([arglist])][as type]
Описание функции:
Public и Private
- разрешение на использование вызываемой функции в других процедурах и модулях и использование только в данном модуле.
  • name - имя вызываемой функции.
  • libname - имя библиотеки.
Alias
псевдоним, необходим, когда используются недопустимые символы или существует переменная, название которой совпадает с названием функции
  • arglist - список передаваемых в функцию переменных
As type
тип функции
Если необходимо вызвать процедуру, то вместо Function указывается Sub, и соответственно опускается As type.
Например:
Declarefunction MyTest Lib "PrjWTest"(ByVal Ns as Byte) as string

Sub WordTest()
Dim S1, S2 as string
S1 = MyTest(1)
end Sub
Вызываем функцию MyTest из библиотеки PrjWTest.dll. Функции предаем значение переменной NS, имеющей тип Byte. Функция возвращает строку.
Желательно в VBA создать функцию для вызова DLL. В нашем примере это функция WordTest , которая вызывается MACROBUTTON-ом ({ MACROBUTTON WordTest Кликни здесь }(Вставка => Поле => Автоматизация документа)).

3. Как в Delphi создать DLL

Ответ на этот вопрос можно найти во многих справочниках и учебниках по Delphi. Я лишь приведу исходный текст библиотеки.
На форме находятся следующие компоненты: Edit1 и Button1, причем Button1.ModalResult = mrOk. Листинг библиотеки (PrjWTest.dpr):
library PrjWTest;

uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  UnitWTest in 'UnitWTest.pas' {FormWTest};

var
  //Это наша форма
  MyForm: TFormWTest;

  {*********************Test************************************}

function Test: PChar; export; stdcall;
var
  TmpStr: string;
begin
  TmpStr := '';
  //Вызываем форму
  if MyForm.ShowModal = mrOk then
  begin
    //Считываем текст с Edit
    TmpStr := MyForm.Edit1.Text;
  end;
  //Желательно указать конец строки
  TmpStr := TmpStr + #0;
  //Возвращаем текст
  Test := PChar(TmpStr);
end;

{*********************MyTest************************************
Данную функцию вызываем из Word}

function MyTest(N: Byte): PChar; export; stdcall;
begin
  //Посылаем в Edit число, полученное из Word
  MyForm.Edit1.Text := IntToStr(N);
  //Вызываем вспомогательную функцию
  MyTest := Test;
end;

{*********************MyTest************************************
Создаем форму}

procedure CreateForm; export; stdcall;
begin
  MyForm := TFormWTest.Create(Application);
end;

{*********************MyTest************************************
Освобождаем форму}

procedure FreeForm; export; stdcall;
begin
  MyForm.Free;
end;

exports
  CreateForm Index 1,
  MyTest Index 2,
  FreeForm Index 3;

//{$R *.RES}
begin
  {  Application.Initialize;
    Application.CreateForm(TFormGsk, FormGsk);
    Application.CreateForm(TDataModule2, DataModule2);
    Application.CreateForm(TFormListBoxs, FormListBoxs);
    Application.CreateForm(TFormCreateSk, FormCreateSk);
    Application.CreateForm(TFormAddKontr, FormAddKontr);
    Application.Run;}
end.
При вызове функции MyTest вызывается наша форма, в Edit помещается переданное число, функция возвращает текст из Edit. Полученную DLL желательно поместить в папку Windows.

4. Проблемы, возникающие при передаче данных.

В данной части хотелось бы обратить внимание на некоторые особенности передачи данных из Delphi в VBA.
Во-первых, если передаете текст, то тип передаваемой функции должен быть Pchar, т.к. VBA не понимает типа String.
Во-вторых, VBA все равно при выводе текста в документ выдаст ерунду. Поэтому ниже привожу листинг функции, преобразующей полученный текст в "нормальный".
//Приводим полученный текст в "нормальный" текстовый вид

function StrToStr(St as string) as string
  Dim EndStr as Long
  //Определяем количество символов до конца строки
  EndStr = InStr(1, St, Chr$(0))
  if EndStr <>
0 then
  //Вырезаем и возвращаем нужную информацию
    StrToStr = Left(St, EndStr - 1)
else
  StrToStr = ""
end if


endfunction
В-третьих, лучше создавать и освобождать формы отдельными функциями, особенно это видно при работе с базами.
//Подключаемые функции в DLL
Declare Sub CreateForm Lib "PrjWTest"()

Declarefunction MyTest Lib "PrjWTest"(ByVal Ns as Byte) as string
  Declare Sub FreeForm Lib "PrjWTest"()
5. Как вставлять текст в Word.

Это тоже можно найти в справочниках и учебниках по VBA. Но все же приведу несколько советов по этому вопросу.
Если строку необходимо вставить в определенное место в тексте, то делаем закладку: Вставка=>Закладка в меню Word. Но лучше использовать две закладки: начало текста и конец. Это может понадобиться в случае замены старого текста на новый (обновление данных). Далее листинг этих функций:
//Переходим к метке Label
Sub GotoBookMark(label as string)
Selection.goto What := wdGoToBookmark, Name := label
  with ActiveDocument.Bookmarks
    .DefaultSorting = wdSortByName
    .ShowHidden = False
end with
end Sub

//Вставляет текст NK между закладками BeginBookM и EndBookM
Sub NewTxt(BeginBookM as string, EndBookM as string, NK as string)
//Переходим к первой закладке
GotoBookMark(BeginBookM)
//Выделяем старый текст между закладками
Selection.Extend
//Переходим к второй закладке
GotoBookMark(EndBookM)
//Отступаем чтобы не захватить закладку
Selection.MoveLeft unit := wdCharacter, Count := 1
  //Заменяем старый текст на новый
  Selection.TypeText Text := NK
end Sub
И напоследок, листинг основной функции VBA - WordTest, которая вызывает DLL и вставляет текст между закладками:
Sub WordTest()
Dim S1, S2 as string
//Загружаем DLL и форму
CreateForm
//Считываем данные с Edit
S1 = MyTest(1)
S2 = S1
//Преобразуем в нормальный текст
S2 = StrToStr(S2)
//Вставляем текст между закладками
NewTxt "BeginTest", "EndTest", S2

//Удаляем формы и выгружаем DLL
FreeForm

Exit Sub
end Sub
Исходники программы и документа прилагаются — AutoWrd.zip (127 K).





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook