Шаг 111.
Автоматизация Microsoft Word. Программирование свойств MS Word. Создание и использование макроса Visual Basic средствами Delphi

    На этом шаге мы рассмотрим создание и использование макроса Visual Basic средствами Delphi.

    Как уже говорилось и было показано на многочисленных примерах, используя среду визуального программирования приложений Delphi, можно без особого труда создать и использовать любой документ приложения Word. Но есть некоторые ограничения, которые порой достаточно трудно обойти. Одним из таких ограничений является невозможность передавать из Delphi в Visual Basic значения, типы которых не поддерживаются для такого взаимодействия. Например, в документе требуется создать объект - ломаную линию. Для создания такого объекта приходится заполнять массив данных для точек изломов этой линии, затем вызывать метод, аргументом которого является этот массив. При создании контроллера автоматизации мы не можем использовать вызов из Delphi функций Visual Basic, аргументами которых являются массивы. Как быть в таком случае или в других случаях, когда ситуация кажется безвыходной? Решением может быть создание макроса средствами Delphi с использованием объектов Visual Basic и выполнение этого макроса, а затем его удаление после выполнения задачи.

    Макросы представляют собой тексты процедур или функций на языке Visual Basic, связанные с проектами. Проекты являются родительскими объектами по отношению к макросам. В свою очередь проект связан или с документом, или с шаблоном документа. Все проекты объединены в коллекцию проектов. Текст макроса хранится в программном модуле, в котором могут храниться и несколько макросов.

    Доступ к коллекции или к любому проекту коллекции обеспечивают объекты W.VBA.VBProjects и W.VBE.VBProjects.Item(i:integer), где i - индекс элемента коллекции. Имя элемента коллекции связано с именем шаблона или документа, обычно для шаблона Normal индекс равен единице. Проекту, в свою очередь, принадлежит коллекция VBComponents элементов проекта - это и визуальные объекты, и тексты макросов. Метод Add коллекции VBComponents создает новый элемент. Чтобы создать стандартный модуль, содержащий тексты макросов, аргумент этого метода должен быть равен vbext_ct_StdModule. После создания модуля мы получаем доступ к текстовой части макроса и можем записать в него любые операторы, соответствующие спецификации языка Visual Basic. Рассмотрим пример процедуры.

procedure TForm1.Button2Click(Sender: TObject);
//Создание и использование макроса Visual Basic средствами Delphi
const
  vbext_ct_StdModule=1;
  msoBarFloating=4;
  msoControlButton=1;
var
  CM,CB,BTN:Variant;
  S: String;
begin
  CM:= W.VBE.VBProjects.Item(1).VBComponents.Add(vbext_ct_StdModule).CodeModule;
  S:= 'Sub Макрос1()'+Chr(10)+Chr(13)+
  'MsgBox '+Chr(34)+'Выполняется процедура нажатия кнопки'+Chr(34)+
  Chr(10)+Chr(13)+
//  'Set Document = Application.Documents.Add '+Chr(10)+Chr(13)+
  'Dim pts(1 To 7, 1 To 2) As Single '+Chr(10)+Chr(13)+
  'pts(1, 1) = 0 '+ Chr(10)+Chr(13)+
  'pts(1, 2) = 0 '+Chr(10)+Chr(13)+
  'pts(2, 1) = 72 '+Chr(10)+Chr(13)+
  'pts(2, 2) = 72 '+Chr(10)+Chr(13)+
  'pts(3, 1) = 100 '+Chr(10)+Chr(13)+
  'pts(3, 2) = 40 '+Chr(10)+Chr(13)+
  'pts(4, 1) = 20 '+Chr(10)+Chr(13)+
  'pts(4, 2) = 50 '+Chr(10)+Chr(13)+
  'pts(5, 1) = 90 '+Chr(10)+Chr(13)+
  'pts(5, 2) = 120 '+Chr(10)+Chr(13)+
  'pts(6, 1) = 60 '+Chr(10)+Chr(13)+
  'pts(6, 2) = 30 '+Chr(10)+Chr(13)+
  'pts(7, 1) = 150 '+Chr(10)+Chr(13)+
  'pts(7, 2) = 90 '+Chr(10)+Chr(13)+
  'ActiveDocument.Shapes.AddPolyline (pts) '+Chr(10)+Chr(13)+
  'End Sub';
  CM.AddFromString (S);
  S:=CM.Name;
  MessageBox(handle,PChar('Макрос "Макрос1" создан в модуле  "'+
     S+'"'), '',0);
  CB:=W.CommandBars.Add (Name:='Временная панель',
      Position:=msoBarFloating);
  CB.Enabled:=true;
  CB.Visible:=true;
  MessageBox(handle,PChar('Создана временная панель'),'',0);
  BTN:=W.CommandBars.Item['Временная панель'].Controls.Add(
    Type:=msoControlButton, ID:=1);
  BTN.Caption:='Временная кнопка';
  BTN.OnAction:=CM.Name+'.Макрос1';
  MessageBox(handle,PChar('Создана временная кнопка'),'',0);
  BTN.Execute;
  BTN.Delete;
  MessageBox(handle,PChar('Удалена временная кнопка'),'',0);
  CB.Delete;
  MessageBox(handle,PChar('Удалена временная панель'),'',0);
  W.VBE.VBProjects.Item(1).VBComponents.Remove(CM.parent);
  MessageBox(handle,PChar('Модуль "'+S+'" и "Макрос1" удалены'),'',0);
end;

    В первом операторе этой процедуры мы создаем и получаем доступ к программному модулю, в который сможем записать текст создаваемого макроса. Далее в строковую переменную записываем текст создаваемого макроса, учитывая стиль написания операторов Visual Basic. Оператор

    CM.AddFromString (S);

где S - строка, содержащая текст макроса, записывает текст макроса в модуль. Далее создаем меню и кнопку, в свойство OnAction которой записываем строку - имена модуля и макроса, разделенные точкой. Метод Execute кнопки запускает созданный макрос на выполнение. Далее удаляем кнопку, панель и компонент, содержащий программный модуль.


    Замечание. Если убрать комментарий у строки
    'Set Document = Application.Documents.Add '+Chr(10)+Chr(13)+
то построение ломаной будет происходить в новом документе.

    Если эту процедуру выполнять по шагам, то сможем наблюдать следующее. На первом этапе мы видим в окне редактора Visual Basic, как создается программный модуль и в него записывается текст макроса (рисунок 1).


Рис.1. Создан модуль и записан текст макроса

    Далее, вызывается метод Execute кнопки, с которой связан макрос, и выполняется программа на Visual Basic, записанная в программном модуле (рисунок 2).


Рис.2. Макрос запущен на выполнение

    После выполнения удаляются созданные элементы управления и программный модуль с текстом подпрограммы на Visual Basic (рисунок 3).


Рис.2. Макрос выполнен, элементы управления и программный модуль удалены

    Вот полный текст приложения.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComObj, CheckLst, Spin;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
var
  W: Variant;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
//Создание объекта Word и его визуализация
begin
  W:=CreateOleObject('Word.Application');
  W.Visible:=True;
  W.Documents.Add;   //Создание документа
end;

procedure TForm1.Button2Click(Sender: TObject);
//Создание и использование макроса Visual Basic средствами Delphi
const
  vbext_ct_StdModule=1;
  msoBarFloating=4;
  msoControlButton=1;
var
  CM,CB,BTN:Variant;
  S: String;
begin
  CM:= W.VBE.VBProjects.Item(1).VBComponents.Add(vbext_ct_StdModule).CodeModule;
  S:= 'Sub Макрос1()'+Chr(10)+Chr(13)+
  'MsgBox '+Chr(34)+'Выполняется процедура нажатия кнопки'+Chr(34)+
  Chr(10)+Chr(13)+
//  'Set Document = Application.Documents.Add '+Chr(10)+Chr(13)+
  'Dim pts(1 To 7, 1 To 2) As Single '+Chr(10)+Chr(13)+
  'pts(1, 1) = 0 '+ Chr(10)+Chr(13)+
  'pts(1, 2) = 0 '+Chr(10)+Chr(13)+
  'pts(2, 1) = 72 '+Chr(10)+Chr(13)+
  'pts(2, 2) = 72 '+Chr(10)+Chr(13)+
  'pts(3, 1) = 100 '+Chr(10)+Chr(13)+
  'pts(3, 2) = 40 '+Chr(10)+Chr(13)+
  'pts(4, 1) = 20 '+Chr(10)+Chr(13)+
  'pts(4, 2) = 50 '+Chr(10)+Chr(13)+
  'pts(5, 1) = 90 '+Chr(10)+Chr(13)+
  'pts(5, 2) = 120 '+Chr(10)+Chr(13)+
  'pts(6, 1) = 60 '+Chr(10)+Chr(13)+
  'pts(6, 2) = 30 '+Chr(10)+Chr(13)+
  'pts(7, 1) = 150 '+Chr(10)+Chr(13)+
  'pts(7, 2) = 90 '+Chr(10)+Chr(13)+
  'ActiveDocument.Shapes.AddPolyline (pts) '+Chr(10)+Chr(13)+
  'End Sub';
  CM.AddFromString (S);
  S:=CM.Name;
  MessageBox(handle,PChar('Макрос "Макрос1" создан в модуле  "'+
     S+'"'), '',0);
  CB:=W.CommandBars.Add (Name:='Временная панель',
      Position:=msoBarFloating);
  CB.Enabled:=true;
  CB.Visible:=true;
  MessageBox(handle,PChar('Создана временная панель'),'',0);
  BTN:=W.CommandBars.Item['Временная панель'].Controls.Add(
    Type:=msoControlButton, ID:=1);
  BTN.Caption:='Временная кнопка';
  BTN.OnAction:=CM.Name+'.Макрос1';
  MessageBox(handle,PChar('Создана временная кнопка'),'',0);
  BTN.Execute;
  BTN.Delete;
  MessageBox(handle,PChar('Удалена временная кнопка'),'',0);
  CB.Delete;
  MessageBox(handle,PChar('Удалена временная панель'),'',0);
  W.VBE.VBProjects.Item(1).VBComponents.Remove(CM.parent);
  MessageBox(handle,PChar('Модуль "'+S+'" и "Макрос1" удалены'),'',0);
end;

end.
Текст этого приложения можно взять здесь (7,2 Кб).

    На следующем шаге мы рассмотрим коллекцию диалогов.




Предыдущий шаг Содержание Следующий шаг