Заметки · 24.11.2023

А и Б сидели на трубе

Как-то довелось мне писать программку, которая брала данные из нескольких TEdit и впихивала их в документ формата docx с помощью обращения к тому самому Word.Application (API, все дела). Дело было уже сравнительно давно и я уже успел забыть, что вообще работал над такой софтиной. А её исходники случайно раскопал на одном из своих бэкапов.

Логика программы была такой — заполнялись поля, нажималась кнопка, из ресурсов программы разворачивался эталонный документ, в нём выполнялась замена маркерных слов на введённые данные и документ перемещался в обозначенную пользователем папку.

Особым сокровищем я счёл весь процесс замены маркерного слова surname на условную фамилию Иванов.

Итак, прежде всего нужно подключить в блоке uses два модуля — Variants и ComObj.

uses ..., Variants, ComObj, ...;

Функция WriteToWord:

function WriteToWord(pathtofile,find,replace,savefile:string):boolean;
var
   word: variant;
   decode_pathtofile: string;
   decode_find: string;
   decode_replace: string;
   decode_savefile: string;
begin
  decode_pathtofile:=UTF8Decode(pathtofile);
  decode_find:=UTF8Decode(find);
  decode_replace:=UTF8Decode(replace);
  decode_savefile:=UTF8Decode(savefile);
  try
    word:=CreateOleObject('Word.Application');
    word.Documents.Open(WideString(decode_pathtofile));
    word.Selection.find.execute(findtext:=decode_find, replacewith:=decode_replace);
    word.selection.start:=0;
    word.ActiveDocument.SaveAs(decode_savefile);
    word.ActiveDocument.Close(False);
    word.Quit;
    result:=true;
  except
    result:=false;
    word.Quit;
  end;
end;

Параметры функции:

  • pathtofile — указывается путь к файлу-шаблону;
  • find — слово, которое необходимо найти;
  • replace — слово, которым нужно заменить слово find;
  • savefile — путь для сохранения файла.

Если в savefile указан тот же путь, что и в pathtofile, изменения будут внесены и сохранены в файл-шаблон.

Разумеется, функция была написана для замены одного конкретного слова в одном конкретном документе. Никаких циклов внутри функции, как видите, нет. Для работы WriteToWord не важны регистр или форматирование, она подхватит тот регистр и то форматирование, в которых создано маркерное слово.

И вот еще что, в случаях, когда вы хотите обратиться к документу, который лежит в той же папке, что и приложение — воспользуйтесь этой конструкцией:

ExtractFilePath(Application.ExeName) + '\имя_файла.docx'