Delphi word создание таблицы

wolitar

0 / 0 / 0

Регистрация: 09.12.2011

Сообщений: 30

1

09.03.2012, 08:37. Показов 7785. Ответов 1

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Всем привет! У меня два вопроса
1) написал код:

Delphi
1
2
3
4
App := CreateOleObject('Word.Application');
  App.Documents.open('C:111.doc');
  App.ActiveDocument.Tables.Add(App.ActiveDocument.Range(0, 0), 5, 2);
  App.Visible := True;

почему-то таблица получилась бесцветная. как сделать так, чтобы были видны ячейки?
2) когда пишу код:

Delphi
1
app.Tables.Item(1).Cell(1,1).Range.Text := 'текст';

то выдаёт ошибку как по другому можно заполнить ячейку таблицы?



0



Mawrat

13094 / 5875 / 1706

Регистрация: 19.09.2009

Сообщений: 8,808

09.03.2012, 17:17

2

Пример, как открыть документ MS Word, добавить в его конце новую таблицу, разлиновать её и перенести в неё данные из таблицы типа TStringGrid на форме.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
uses
  ComObj;
 
procedure TForm1.Button1Click(Sender: TObject);
const
  wdLineStyleSingle = 1;
var
  wdApp, wdDoc, wdTable : Variant;
  Row, Col : Integer;
  Od : TOpenDialog;
  Sg : TStringGrid;
begin
  Od := OpenDialog1;
  Sg := StringGrid1;
 
  if Od.InitialDir = '' then
    Od.InitialDir := ExtractFilePath( Application.ExeName )
  ;
  if not Od.Execute then Exit;
  if not FileExists(Od.FileName) then begin
    ShowMessage(
      'Файл с именем:'#10
      + Od.FileName + #10
      + 'Не найден. Действие отменено.'
    );
    Exit;
  end;
  try
    wdApp := CreateOleObject('Word.Application');
  except
    ShowMessage('Не удалось запустить MS Word. Действие отменено.');
    Exit;
  end;
 
  //Делаем видимым окно MS Word.
  wdApp.Visible := True;
  //Попытка открыть выбранный файл.
  wdDoc := wdApp.Documents.Open(FileName:=Od.FileName);
  //Добавляем отступ в конце документа.
  wdDoc.Range.InsertAfter(#13#10);
  //Добавляем таблицу внизу документа.
  wdTable := wdDoc.Tables.Add(
    Range:=wdDoc.Range.Characters.Last
    ,NumRows:=Sg.RowCount
    ,NumColumns:=Sg.ColCount
  );
  //Параметры линий таблицы.
  wdTable.Borders.InsideLineStyle := wdLineStyleSingle;
  wdTable.Borders.OutsideLineStyle := wdLineStyleSingle;
  //Копируем данные из таблицы на форме в таблицу в документе Word.
  for Row := 0 to Sg.RowCount - 1 do
  for Col := 0 to Sg.ColCount - 1 do
    wdTable.Cell(Row + 1, Col + 1).Range.Text := Sg.Cells[Col, Row]
  ;
  //Отключение режима показа предупреждений.
  //wdApp.DisplayAlerts := False;
  //Сохрание документа.
  //wdDoc.Save;
  //Закрываем документ.
  //wdDoc.Close;
  //Включение режима показа предупреждений.
  //wdApp.DisplayAlerts := True;
  //Закрываем MS Word.
  //wdApp.Quit;
end;

Что касается чтения данных из таблицы MS Word. Надо иметь в виду, что текст, прочитанный из ячейки таблицы MS Word, в конце содержит пару управляющих символов: #13#7. Эти символы следует удалить.



3



Как создать таблицу в Word’е?
Темой этой части статьи будет создание таблиц в редакторе Word из приложений, написанных на Delphi. В прошлый раз мы рассмотрели создание простых документов, которые не содержат таблиц переменной длины, но большинство отчетов так или иначе содержит табличное представление информации. Уверен, что хоть один отчет в вашей программе содержит хоть одну таблицу. Поэтому информации двух предыдущих частей статьи было бы недостаточно для создания отчета, содержащего табличное представление информации.
Как создать таблицу в Word’е? Так же просто, как это делается в обычном объектно-ориентированном языке. В объекте Document мы имеем коллекцию Tables, с помощью методов и объектов которой можем создать таблицу и получить доступ к ее свойствам, ячейкам и тексту в ячейках. Если в нашем отчете несколько таблиц, то к любой из них мы имеем доступ с помощью коллекции Tables и индекса таблицы.
Чтобы более ясно представить процесс создания таблицы, используя объектные модели MS Office, создадим документ, аналог которого после простой доработки можно будет использовать в своих программах для вывода информации. Одним из самых распространенных отчетов, содержащих таблицу, является документ типа «Прайс-лист». Его мы и будем создавать. Попробуем создать его без шаблона, т.е. с чистого листа. Определимся, каким набором функций нужно владеть для создания этого документа. Во-первых, нам нужна будет функция создания таблицы, затем потребуется задать(изменить) размеры этой таблицы, вписать данные в ячейки, объединить ячейки. Возможно, потребуется еще несколько вспомогательных функций. Творчески используя материал статьи, вы сможете сами определить и создать для себя еще несколько функций для работы с таблицами.
Определим функцию создания таблицы CreateTable. Так как количество таблиц в документе может быть больше одной, то для идентификации каждой таблицы используем ее номер. Для создания применим метод ADD коллекции Tables. Метод ADD имеет аргументы: область, где создается таблица, количество строк и количество столбцов. Наша функция будет создавать таблицу там, где расположен курсор, и иметь еще один аргумент: числовую переменную, через которую будет возвращаться порядковое значение(индекс) таблицы в документе. Функция выглядит следующим образом:

Function CreateTable(NumRows, NumColumns:integer;
 var index:integer):boolean;
 var sel_:variant;
begin
 CreateTable:=true;
 try
 sel_:=W.selection;
 W.ActiveDocument.Tables.Add (Range:=sel_.Range,NumRows: =NumRows,
  NumColumns:=NumColumns);
 index:=W.ActiveDocument. Tables.Count;
 except
 CreateTable:=false;
 end;
End;

Первый оператор определяет область выделения или положения курсора, второй оператор создает таблицу и третий возвращает количество таблиц в документе или порядковый номер вновь созданной таблицы, который будет использоваться другими функциями для доступа к этой таблице.
Наша функция создаст таблицу произвольного размера, но для корректного представления данных необходимо задать определенные размеры строк и столбцов. Чтобы задать размер таблицы или строки(столбца), нужно получить доступ к таким свойствам таблицы, как коллекции Columns и Rows (список столбцов и строк), через которые сможем получить доступ к конкретной строке или(и) столбцу, к ячейкам и к параметрам ячейки(строки, столбца). Для этого используем объект ActiveDocument.Tables.Item(table), где table — номер таблицы в документе. Создадим функцию, которая будет задавать ширину и высоту всех ячеек таблицы.

Function SetSizeTable(Table:integer; RowsHeight,
 ColumnsWidth:real):boolean;
begin
 SetSizeTable:=true;
 try
 W.ActiveDocument.Tables.Item (Table).Columns.Width:=ColumnsWidth;
 W.ActiveDocument.Tables.Item(Table). Rows.Height:=RowsHeight;
 except
 SetSizeTable:=false;
 end;
End;

Аналогично мы можем задавать высоту любой строки или(и) ширину любого столбца на выбор. Для доступа к размерам ячейки используем также коллекции Rows, Columns объекта Table. Чтобы воспользоваться этими возможностями из нашего приложения, создадим следующие функции.

Function SetHeightRowTable(Table,Row:integer;
 RowHeight:real):boolean;
begin
 SetHeightRowTable:=true;
 try
 W.ActiveDocument.Tables.Item(Table).Rows.item(Row).Height:=RowHeight;
 except
 SetHeightRowTable:=false;
 end;
End;
Function SetWidthColumnTable(Table,Column: integer;
 ColumnWidth:real):boolean;
begin
 SetWidthColumnTable:=true;
 try
 W.ActiveDocument.Tables.Item(Table).Columns.
  Item(Column).Width:=ColumnWidth;
 except
 SetWidthColumnTable:=false;
 end;
End;

Возможно, нам придется не только задавать размеры таблицы, но и определять(считывать) размеры ячеек таблицы. Для этого используем те же коллекции, объекты и свойства таблицы, что и в функции SetSizeTable, но немного изменим внутренние операторы таким образом, что в возвращаемые переменные RowsHeight и ColumnsWidth будут записываться значения размеров строк и столбцов таблицы.

Function GetSizeTable(Table:integer;var RowsHeight,
 ColumnsWidth: real):boolean;
begin
 GetSizeTable:=true;
 try
 ColumnsWidth:=W.ActiveDocument. Tables.Item(Table).Columns.Width;
 RowsHeight:=W.ActiveDocument. Tables.Item(Table).Rows.Height;
 except
 GetSizeTable:=false;
 end;
End;

Также можно считать и размеры строки или столбца на выбор, для этого достаточно использовать коллекции Rows, Columns объекта Table (Tables.Item(Table)).
Следующим этапом формирования табличного документа определим запись текстовой информации в выбранную ячейку таблицы. Одним из способов такой записи является доступ к полю Text ячейки, но и в этом случае текст записывается не напрямую, а в объект Range ячейки таблицы. Функция SetTextToTable выполняет такую запись.

Function SetTextToTable(Table:integer;Row, Column:integer;
 text:string):boolean;
begin
 SetTextToTable:=true;
 try
 W.ActiveDocument.Tables.Item(Table).Columns.Item(Column).
  Cells.Item(Row).Range.Text:=text;
 except
 SetTextToTable:=false;
 end;
End;

И последнее действие, которое необходимо произвести над таблицей для создания простого табличного документа, это объединение ячеек. Для этого воспользуемся методом Merge объекта Cell (ячейка). Первый оператор функции объединения ячеек возвращает указатель на объект — конечную ячейку (Cel). Второй оператор объединяет начальную ячейку Row1,Column1 с конечной ячейкой, табличные координаты которой уже заданы и равны Row2,Column2.

Function SetMergeCellsTable(Table:integer;Row1,
 Column1,Row2,Column2:integer):boolean;
 var Cel:variant;
begin
 SetMergeCellsTable:=true;
 try
 Cel:=W.ActiveDocument.Tables.I tem(Table).Cell(Row2,Column2);
 W.ActiveDocument.Tables.Item(Table). Cell(Row1,Column1).Merge(Cel);
 except
 SetMergeCellsTable:=false;
 end;
End;

Переходим к заключительной стадии — созданию документа.
Для этого все определенные в этой части статьи функции объединим с ранее созданными и перенесем во вновь созданную библиотеку процедур и функций. Например, это будет файл MyWord.pas, в разделе interface которого будут описаны заголовки всех наших функций, а в разделе implementation — сами функции (в дальнейшем будем пользоваться этой библиотекой). Не забудьте после implementation вставить строки uses ComObj; var W:variant;.
Создадим новый проект, в программном модуле которого сделаем ссылку на нашу библиотеку uses MyWord;. На форме разместим кнопку и в процедуру обработки нажатия ее впишем следующий программный код.

procedure TForm1.Button1Click(Sender: TObject);
 var tablica_:integer;
begin
 if CreateWord then begin
 VisibleWord(true);
 If AddDoc then begin
// cсоздаем таблицу
  If CreateTable(5,3,tablica_) then begin
  Messagebox(0,pchar(‘Таблица создана=’+inttostr(tablica_)),»,0);
// изменяем размеры таблицы
  SetSizeTable(tablica_,25,37);
  SetWidthColumnTable(tablica_,1,300);
  SetWidthColumnTable(tablica_,2,80);
  SetWidthColumnTable(tablica_,3,80);
  Messagebox(0,‘Размер таблицы изменен’,»,0);
// записывает информацию в ячейки таблицы
  SetTextToTable(tablica_,1,1,
  ‘ПРОЦЕССОРЫ (данные от 27.05.2003) ‘);
  SetTextToTable(tablica_,2,1,‘Наименование’);
  SetTextToTable(tablica_,2,2,‘Стоимость’);
  SetTextToTable(tablica_,2,3,‘Гарантия’);
  SetTextToTable(tablica_,3,1,
  ‘ПРОЦЕССОР AMD K7- 1333 ATHLON 266MHz (Socket-A)’);
  SetTextToTable(tablica_,3,2,‘47.52 $’);
  SetTextToTable(tablica_,3,3,’12 мес.’);
  SetTextToTable(tablica_,4,1,
  ‘ПРОЦЕССОР AMD K7- 800 DURON (Socket-A)’);
  SetTextToTable(tablica_,4,2,‘23.54 $’);
  SetTextToTable(tablica_,4,3,’12 мес.’);
// объединяем необходимые ячейки таблицы
  SetMergeCellsTable(tablica_,1,1,1,3);
  end;
  SaveDocAs(‘c:Прайс лист’);
  Messagebox(0,‘Текст сохранен’,»,0);
  CloseDoc;
 end;
 Messagebox(0,‘ Текст закрыт’,»,0);
 CloseWord;
 end;
end;

В результате выполнения приведенной выше процедуры получим результат, который выглядит, как показано на рисунке.
clip0069
Полный исходный текст смотрите по адресу www.kornjakov.ru/st1_3.zip.
Мы сформировали достаточно простую таблицу, но редактор Word позволяет создавать очень сложные документы (см. как пример бланки налоговых деклараций). Практика показывает, что для таких документов лучше использовать шаблоны, которые можно заполнять информацией из программы. Причем такие шаблоны не обязательно создавать самому, они есть в любых правовых справочных системах. В следующей части статьи будет рассмотрен пример создания сложного документа, который сочетает заполнение шаблона и заполнение таблицы переменной длины, для этого понадобится ряд дополнительных функций, которыми будет дополнена наша библиотека.
По всем вопросам, касающимся материала этой статьи, вы можете обратиться к автору по адресу www.kornjakov.ru или _kvn@mail.ru.
Василий КОРНЯКОВ
Литература: Н. Елманова, С. Трепалин, А.Тенцер «Delphi 6 и технология COM» «Питер» 2002.

This adds a table after a named bookmark. You should be able to adapt it to your needs. (Your code is from decades ago, BTW — modern Delphi uses Result to indicate return values instead of FunctionName :=. Result is an automatically-created variable of the proper type for the function.) Tested using Delphi 2007, Office XP components, on Windows 7 and an Office 2007 installation.

procedure TForm1.AddTable;
const
  Line1 = 'January,February,March';
  Line2 = '31,28,31';
  Line3 = '31,59,90';
var
  R, Direction, Separator, BookmarkName, TableFormat, Cols: OleVariant;
begin
  BookMarkName := 'bmTest';
  R := WordApp.ActiveDocument.Bookmarks.Item(BookmarkName).Range;
  Direction := wdCollapseEnd;
  R.Collapse(Direction);
  R.InsertAfter(Line1);
  R.InsertParagraphAfter;
  R.InsertAfter(Line2);
  R.InsertParagraphAfter;
  R.InsertAfter(Line3);
  R.InsertParagraphAfter;
  Separator := ',';
  TableFormat := wdTableFormatGrid1;
  R.ConvertToTable(Separator);

  // Cleaner to grab a reference to the table columns, and use
  // it instead of the long reference every time.
  Cols := WordApp.ActiveDocument.Tables.Item(1).Columns;
  Cols.Item(1).SetWidth(WordApp.InchesToPoints(2.25), wdAdjustNone);
  Cols.Item(2).SetWidth(WordApp.InchesToPoints(3.5), wdAdjustNone);
  Cols.Item(3).SetWidth(WordApp.InchesToPoints(2.75), wdAdjustNone);
end;

Время теряется на переключение проццесов. Чем больше таблица тем хуже.
Каждая клетка таблицы это переключение.
Сформируйте стороку данных передайте 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] of String; 
  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 do begin 
         Text1:=''; 
         Text1:=Text1+IntToStr(k)+'@'; 
         Text:=Text+Text1; 
            if not DataModule1.IBQuery2.FieldByName('FML').IsNull then 
               S[1]:=DataModule1.IBQuery2.FieldByName('FML').Value;
            if not DataModule1.IBQuery2.FieldByName('IME').IsNull then 
               S[2]:=DataModule1.IBQuery2.FieldByName('IME').Value; 
            if not 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]:=' '; 
            if not DataModule1.IBQuery2.FieldByName('NPZ').IsNull then 
               S[1]:=DataModule1.IBQuery2.FieldByName('NPZ').Value; 
            if not 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]:=' '; 
            if not 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;


Like this post? Please share to your friends:
  • Delphi word на передний план
  • Delphi word межстрочный интервал
  • Delphi word копирование текста
  • Delphi word как найти текст
  • Delphi word как закрыть word