Время теряется на переключение проццесов. Чем больше таблица тем хуже.
Каждая клетка таблицы это переключение.
Сформируйте стороку данных передайте Word (один процесс) затем конвертируйте
текст в таблицу (второй процесс)
Ниже приведе текст рабочей процедуры, написанны на Delphi 6.0 для
компонентов Офиса 97. Успешно работает и с 2000
procedure Spisok_Sotrudnikov2(Name: String);
var{Объявление переменных, для передачи их в качестве формальных параметров в}{ сервер автоматизации}
Shablon,FileName,Tempo,Separator,NumColumns:OleVariant;
i,k : Integer;
MyRange : Range; {Область документа}
Tabl : Table; {Одна таблица}
Pars : Paragraphs; {Массив параграфов}
Par : Paragraph; {Один параграф}
S : Array[1..9] ofString;
Text : WideString;
Text1: String;
begin
Screen.Cursor:=crHourGlass;
{Оформление бегущей линейки}
Otchet_Spisok_Sotrudnikov.BitBtn1.Visible:=False;
Otchet_Spisok_Sotrudnikov.Gauge1.Visible:=True;
{Определяем файл шаблона документа и файл для сохранения результата}
Shablon:=ExtractFilePath(Application.EXEName)+'Spisok.Doc';
FileName:=ExtractFilePath(Application.EXEName)+'Spisok_Sotrudnikov1.DOC';
{Открываем шаблон документа}
Otchet_Spisok_Sotrudnikov.WordApplication1.Documents.Open(Shablon,EmptyParam
,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam);
{Связываем компоненту с существующим интерфейсом}
Otchet_Spisok_Sotrudnikov.WordDocument1.ConnectKind:=ckAttachToInterface;
Otchet_Spisok_Sotrudnikov.WordDocument1.ConnectTo(Otchet_Spisok_Sotrudnikov.
WordApplication1.ActiveDocument);
{Обязательно отключить проверки орфографии и граматики в Word}
Otchet_Spisok_Sotrudnikov.WordApplication1.Options.CheckSpellingAsYouType:=f
alse;
Otchet_Spisok_Sotrudnikov.WordApplication1.Options.CheckGrammarAsYouType:=fa
lse;
{Опредеоляем область документа}
MyRange:=Otchet_Spisok_Sotrudnikov.WordDocument1.Range(EmptyParam,EmptyParam
);
Tempo:=MyRange;
{Оформляем заголовок}
Pars:=Otchet_Spisok_Sotrudnikov.WordDocument1.Paragraphs;
Par:=Pars.Add(Tempo);
Par.Alignment:=wdAlignParagraphCenter; {Выравнивание параграфа}
Par.Range.Font.Bold:=1; {Шрифт жирный}
Par.Range.Font.Size:=14; {Размер шрифта}
Par.Range.Font.ColorIndex:=1; {Цвет шрифта зеленый}
Par.Range.InsertBefore(Name);
Tempo:=Par.Range.Get_End_; {Определяем конец области}
MyRange:=Otchet_Spisok_Sotrudnikov.WordDocument1.Range(Tempo);
{Формирование данных}
DataModule1.IBQuery2.Open;
DataModule1.IBQuery2.FetchAll;
i:=DataModule1.IBQuery2.RecordCount;
Otchet_Spisok_Sotrudnikov.Gauge1.MaxValue:=i;
Text:='? п/п@Фамилия, Имя, Отчество@Должность@Табельный номер@';
for k:=1 to i dobegin
Text1:='';
Text1:=Text1+IntToStr(k)+'@';
Text:=Text+Text1;
ifnot DataModule1.IBQuery2.FieldByName('FML').IsNull then
S[1]:=DataModule1.IBQuery2.FieldByName('FML').Value;
ifnot DataModule1.IBQuery2.FieldByName('IME').IsNull then
S[2]:=DataModule1.IBQuery2.FieldByName('IME').Value;
ifnot DataModule1.IBQuery2.FieldByName('OTC').IsNull then
S[3]:=DataModule1.IBQuery2.FieldByName('OTC').Value;
Text1:=S[1]+' '+S[2]+' '+S[3]+'@';
Text:=Text+Text1;
S[1]:=' ';S[2]:=' ';S[3]:=' ';S[4]:=' ';S[5]:=' ';
S[6]:=' ';S[7]:=' ';S[8]:=' ';S[9]:=' ';
ifnot DataModule1.IBQuery2.FieldByName('NPZ').IsNull then
S[1]:=DataModule1.IBQuery2.FieldByName('NPZ').Value;
ifnot DataModule1.IBQuery2.FieldByName('NSP').IsNull then
S[2]:=DataModule1.IBQuery2.FieldByName('NSP').Value;
Text1:=S[1]+' '+S[2]+'@';
Text:=Text+Text1;
S[1]:=' ';S[2]:=' ';S[3]:=' ';S[4]:=' ';S[5]:=' ';
S[6]:=' ';S[7]:=' ';S[8]:=' ';S[9]:=' ';
ifnot DataModule1.IBQuery2.FieldByName('NNN').IsNull then
S[1]:=DataModule1.IBQuery2.FieldByName('NNN').Value;
Text1:=S[1]+'@';
Text:=Text+Text1;
S[1]:=' ';S[2]:=' ';S[3]:=' ';S[4]:=' ';S[5]:=' ';
S[6]:=' ';S[7]:=' ';S[8]:=' ';S[9]:=' ';
Otchet_Spisok_Sotrudnikov.Gauge1.Progress:=k;
DataModule1.IBQuery2.Next;
end;
{Передаем строку текста в Word}
Tempo:=MyRange;
Par:=Pars.Add(Tempo);
Par.Range.InsertBefore(Text);
{Конвертируем текст в таблицу}
Separator:='@';
NumColumns:=4;
MyRange.ConvertToTable(Separator,EmptyParam,NumColumns,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam);
{Связываем переменную и таблицу, а затем меняем размер столбцов и
выравнивание}
Tabl:=Otchet_Spisok_Sotrudnikov.WordDocument1.Range.Tables.Item(1);
Tabl.Columns.Item(1).SetWidth(30,wdAdjustNone);
Tabl.Columns.Item(2).SetWidth(250,wdAdjustNone);
Tabl.Columns.Item(3).SetWidth(250,wdAdjustNone);
Tabl.Columns.Item(4).SetWidth(200,wdAdjustNone);
Tabl.Range.Paragraphs.Format.Alignment:=wdAlignParagraphCenter;
Tabl.Range.Cells.VerticalAlignment:=wdAlignParagraphCenter;
Tempo:=Par.Range.Get_End_; {Определяем конец области}
MyRange:=Otchet_Spisok_Sotrudnikov.WordDocument1.Range(Tempo);
{Сохранение документа и отображение его в OLE контейнере (предварительный
просмотр)}
Otchet_Spisok_Sotrudnikov.WordDocument1.SaveAs(FileName);
Otchet_Spisok_Sotrudnikov.WordDocument1.Close;
{Включить проверки в Word}
Otchet_Spisok_Sotrudnikov.WordApplication1.Options.CheckSpellingAsYouType:=T
rue;
Otchet_Spisok_Sotrudnikov.WordApplication1.Options.CheckGrammarAsYouType:=Tr
ue;
Screen.Cursor:=crDefault;
Otchet_Spisok_Sotrudnikov.Gauge1.Visible:=False;
Otchet_Spisok_Sotrudnikov.BitBtn1.Visible:=True;
Otchet_Spisok_Sotrudnikov.OleContainer1.CreateLinkToFile(FileName,false);
Otchet_Spisok_Sotrudnikov.OleContainer1.Refresh;
end;
Here's the translation of the provided text into Russian:
Код, предоставленный вами, - это процедура Delphi, генерирующая отчет в формате Microsoft Word. Он кажется старым кодом, написанным для Office 97 и Delphi 6.0.
Процедура Spisok_Sotrudnikov2 принимает строковый параметр Name и использует его как заголовок отчета. Процедура открывает шаблон документа Word, заполняет данные из запроса к базе данных, форматирует текст для создания таблицы и затем сохраняет отчет в виде нового документа Word.
Вот некоторые предложения по улучшению кода:
Разделение задач: Код делает слишком много вещей одновременно (открывает файл, подключается к интерфейсу, форматирует текст, сохраняет файл). Рассмотрите возможность разбить его на более маленькие процедуры, каждая из которых имеет свою ответственность.
Использование констант: Вместо использования жестких значений, таких как wdAlignParagraphCenter и 30, рассмотрите возможность определения констант для этих значений.
Обработка ошибок: Код не обрабатывает ошибки хорошо. Рассмотрите возможность добавления блоков try-catch для ловли исключений и предоставления meaningful error messages.
Организация кода: Процедура слишком длинная и имеет многие разделы, которые seem unrelated. Рассмотрите возможность организации кода в отдельные процедуры или модули, каждая из которых имеет свою цель.
Для преобразования этого кода в более современный подход я бы предложил следующее:
Используйте библиотеку,such as OLE2 or Word Automation, для взаимодействия с Microsoft Word.
Создайте отдельную процедуру для открытия и сохранения файлов.
Используйте шаблонный движок, such as FreePascal's Template Engine, для генерации текста отчета.
Рассмотрите возможность использования более современной библиотеки запросов к базе данных, such as DBX.
Вот пример того, как вы могли бы переписать этот код:
procedureGenerateReport(constName:string);begin// Откройте шаблон документа Wordvardoc:=OpenDocumentTemplate('Spisok. Doc');// Заполните данные из запроса к базе данныхvarquery:=ExecuteQuery('SELECT * FROM ...');forrowinquerydobegin// Форматируйте текст для создания таблицыdoc.Range.InsertText(row['FML']+' '+row['IME']+' '+row['OTC']);doc.Range.InsertParagraph();end;// Сохраните отчет в виде нового документа WordvarfileName:=ExtractFilePath(Application.EXEName)+'Spisok_Sotrudnikov1.DOC';doc.SaveAs(fileName);end;
Обратите внимание, что это только пример и может не работать без модификаций.
Передача данных из программы Delphi в Microsoft Word и формирование таблицы с использованием компонентов Офиса 97.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.