Как вывести в word delphi

1 / 1 / 0

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

Сообщений: 53

1

Вывод в Ворд

14.03.2011, 14:05. Показов 13627. Ответов 13


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

У меня вопрос. Подскажите, у меня программа на Delphi 7 там у меня ведутся разные расчеты подсчеты и у меня результат выводит в лейбл и в едит не важно а мне надо сделать что бы сохраняло и выводило в Word. что надо сделать для этого подскажите полз!))

Добавлено через 1 час 10 минут
вот я создал ворд:

WordDoc := CreateOleObject(‘Word.Application’);

WordDoc.Visible := true;

WordDoc.Documents.Add;

а как туда теперь результат отправить хотя бы из Label ??



0



Programming

Эксперт

94731 / 64177 / 26122

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

Сообщений: 116,782

14.03.2011, 14:05

Ответы с готовыми решениями:

Вывод в Ворд
У меня вопрос. Как сделать так чтобы данные из Edit выводились в Word файл в определённые места?

Вывод текста из Дельфи в Ворд
Доброго времени суток!

Делаю программу и мне надо сделать пару отчётов с выводом данных в word….

Вывод в Ворд содержимого формы
Подскажите. Накидал несколько Edit, Stringrid, Panel на форму. Теперь и нужно вывести в ворд для…

Вывод таблицы в ворд
Здравствуйте. Есть таблица, которая генерируется пхп-скриптом и заполняется данными из mysql. Нужно…

13

maxo

хацкер

172 / 157 / 34

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

Сообщений: 425

14.03.2011, 15:05

2

Создаешь в документе закладку например MOVE, дальше:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
uses comobj;
....
 
procedure TForm1.Button1Click(Sender: TObject);
var
WordApp, doc:Variant;
begin
try
WordApp:= CreateOleObject('Word.Application');
doc:=WordApp.documents.Open('c:123.doc');
WordApp.ActiveDocument.SaveAs('c:123.doc');
Wordapp.Visible:=true;
[COLOR="Red"]WordApp.Selection.Goto(-1, unAssigned, unAssigned,'MOVE');
WordApp.Selection.TypeText(Label1.Caption);[/COLOR]
 except
 
end;
 
end;

Конечно лучше сохранять его под другим именем, если документ будет как шаблон



2



Mawrat

13094 / 5875 / 1706

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

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

14.03.2011, 15:18

3

Ещё пример. На форму надо положить TButton, TMemo и TOpenDialog. В коде можно задействовать не открытие готового документа, а создание нового — эти строки закоментованы.

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
uses
  ComObj;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  wdApp, wdDocs, wdDoc : Variant;
  S : String;
  Od : TOpenDialog;
begin
  Od := OpenDialog1;
 
  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;
 
  try
    //Делаем видимым окно MS Word.
    wdApp.Visible := True;
    //Ссылка на коллекцию документов.
    wdDocs := wdApp.Documents;
    //Попытка открыть выбранный файл.
    wdDoc := wdDocs.Open(FileName:=Od.FileName);
    //Создание нового документа. Если параметр Template:='...' не задан,
    //то новый документ создаётся по шаблону Normal.Dot.
    //wdDoc := wdDocs.Add;
    //Добавляем пустую строку в конец документа.
    wdDoc.Range.InsertAfter(#10);
    //Добавляем текст в конец документа.
    S := Memo1.Text;
    wdDoc.Range.InsertAfter(S);
    //Сохранение документа.
    //wdDoc.Save;
    //Закрываем MS Word.
    //wdApp.Quit;
  finally
    wdApp := Unassigned;
    wdDocs := Unassigned;
    wdDoc := Unassigned;
  end;
end;



1



dimon!

1 / 1 / 0

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

Сообщений: 53

14.03.2011, 16:01

 [ТС]

4

Цитата
Сообщение от maxo
Посмотреть сообщение

Создаешь в документе закладку например MOVE, дальше:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
uses comobj;
....
 
procedure TForm1.Button1Click(Sender: TObject);
var
WordApp, doc:Variant;
begin
try
WordApp:= CreateOleObject('Word.Application');
doc:=WordApp.documents.Open('c:123.doc');
WordApp.ActiveDocument.SaveAs('c:123.doc');
Wordapp.Visible:=true;
[COLOR="Red"]WordApp.Selection.Goto(-1, unAssigned, unAssigned,'MOVE');
WordApp.Selection.TypeText(Label1.Caption);[/COLOR]
 except
 
end;
 
end;

Конечно лучше сохранять его под другим именем, если документ будет как шаблон

спс) а вот если Excel то также будет? я вот переделал и ошибка

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
procedure TForm1.Button3Click(Sender: TObject);
var
ExcelApp, doc:Variant;
begin
try
 
ExcelApp:= CreateOleObject('Excel.Application');
doc:=ExcelApp.documents.Open('C:222.xlsx');
ExcelApp.ActiveDocument.SaveAs('C:222.xlsx');
ExcelApp.Visible:=true;
//WordApp.Selection.Goto(-1, unAssigned, unAssigned,'MOVE');
ExcelApp.Selection.TypeText(Label1.Caption);
ExcelApp.Selection.TypeText(Label2.Caption);
 except
 
 
  end;
  end



0



dimon!

1 / 1 / 0

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

Сообщений: 53

14.03.2011, 18:16

 [ТС]

6

Цитата
Сообщение от Mawrat
Посмотреть сообщение

Нет, в Excel другая объектная структура. Вот пример, как читать данные с листа Excel. В контексте этого кода, запись выглядела бы так:

Delphi
1
ExSheet.Cells[Row, Col].Value := 'Текст, который запишется в ячейку с координатами (Row, Col)';

Вот ещё пример — здесь и чтение и запись данных на листе Excel.

спс крнечно но у меня в другом проблема, наверное)))
я делаю прогу для расчета смет там идут разные подсчеты за ремонт и тд и мне нужно результат вывести в ексель или в ворд но лучше бы в ексель)) А я тока могу по простому в лейбалы ответы позагонять и все ))))
если что я могу вам скинуть прогу которую делаю может вы там разберетесь) заранее благодарен )



0



Mawrat

13094 / 5875 / 1706

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

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

14.03.2011, 21:08

7

dimon!, здесь, на самом деле, всё проще. Сначала прямо в Excel вручную создай таблицу — такую какую ты хочешь, чтобы формировала программа. А потом пишешь код, который должен построить нечто подобное.
В общем, вот шаблон:

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
var
  exApp, exBook, exSheet : Variant;
  Row, Col : Integer;
begin
  try
    //Попытка запустить и подключиться к Excel.
    exApp := CreateOleObject('Excel.Application');
  except
    MessageDlg(
      'Не удалось подключиться к Excel. Действие отменено.'
      ,mtError, [mbOK], 0
    );
    Exit;
  end;
  end;
 
  exApp.Visible := True;
  //Создаём рабочую книгу.
  exBook := exApp.Workbooks.Add;
  //Подключаемся к первому листу раб. книги.
  exSheet := exBook.Worksheets[1];
 
  //Для ускорения вывода данных в Excel, можно отключать обновление окна Excel.
  //Это полезно выполнять в случае, когда на лист передаётся много данных -
  //например, таблица из нескольких тысяч строк.
  //exApp.ScreenUpdating := False;
  
  //Создаём шапку таблицы.
  Row := 2;
  exSheet.Cells[Row, 2].Value := 'Таблица 1. Смета.';
  Inc(Row);
  exSheet.Cells[Row, 2].Value := 'Наименование';
  exSheet.Cells[Row, 3].Value := 'Стоимость единицы';
  exSheet.Cells[Row, 4].Value := 'Количество';
  exSheet.Cells[Row, 5].Value := 'Сумма';
  
  //Набор данных.
  
  //Первая строка.
  Inc(Row);
  exSheet.Cells[Row, 2].Value := 'Диагностика';
  exSheet.Cells[Row, 3].Value := '10';
  exSheet.Cells[Row, 4].Value := '3';
  //Вставляем формулу: <Стоимость единицы> * <Количество>. 
  exSheet.Cells[Row, 5].FormulaR1C1 := '=C[-2] * C[-1]';
  
  //Вторая строка.
  Inc(Row);
  exSheet.Cells[Row, 2].Value := 'Ремонт';
  exSheet.Cells[Row, 3].Value := '200';
  exSheet.Cells[Row, 4].Value := '2';
  //Вставляем формулу: <Стоимость единицы> * <Количество>. 
  exSheet.Cells[Row, 5].FormulaR1C1 := '=C[-2] * C[-1]';
  
  //Третья строка.
  //...
  //И т. д.
 
  //Выравниваем ширину столбцов таблицы по ширине содержащихся в них данных.
  for Col := 1 to 5 do begin
    exSheet.Columns[Col].AutoFit;
  end;
 
  //Включаем режим обновления окна Excel.
  //exApp.ScreenUpdating := True;
 
  //Отключаемся от объектов OLE-автоматизации.
  //В этом примере это делать не обязательно, т. к. соответствующие
  //переменные являются локальными и связанные с ними объекты будут
  //освобождены автоматически при выходе из процедуры.
  //Но если переменные являются глобальными и нам они в дальнейшем
  //не понадобятся, то следует их освободить.
  //Код обнуления, в случае глобальных переменных, следует добавить,
  //например, в обработчик события OnDestroy формы. Или в раздел
  //finalization модуля.
  //Если объекты OLE-автоматизации не освободить, то процесс Excel и связанные
  //объекты Excel так и останутся в памяти.
  exSheet := UnAssigned;
  exBook := UnAssigned;
  exApp := UnAssigned;
end;



1



dimon!

1 / 1 / 0

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

Сообщений: 53

14.03.2011, 21:13

 [ТС]

8

Цитата
Сообщение от Mawrat
Посмотреть сообщение

dimon!, здесь, на самом деле, всё проще. Сначала прямо в Excel вручную создай таблицу — такую какую ты хочешь, чтобы формировала программа. А потом пишешь код, который должен построить нечто подобное.
В общем, вот шаблон:

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
66
67
68
69
70
71
72
73
74
var
  exApp, exBook, exSheet : Variant;
  Arr : array of array of Integer;
  i, j, Row, Col : Integer;
begin
  try
    //Попытка подключиться к уже запущенному экземпляру Excel.
    exApp := GetActiveOleObject('Excel.Application');
  except
    try
      //Попытка запустить и подключиться к Excel.
      exApp := CreateOleObject('Excel.Application');
    except
      MessageDlg(
        'Не удалось подключиться к Excel. Действие отменено.'
        ,mtError, [mbOK], 0
      );
      Exit;
    end;
  end;
 
  SetLength(Arr, M, N);
  Randomize;
  for i := 0 to M - 1 do
  for j := 0 to N - 1 do begin
    Arr[i, j] := Random(10); //0..9.
  end;
 
  exApp.Visible := True;
  //Создаём рабочую книгу.
  exBook := exApp.Workbooks.Add;
  //Подключаемся к первому листу раб. книги.
  exSheet := exBook.Worksheets[1];
 
  //Для ускорения вывода данных в Excel, можно отключать обновление окна Excel.
  //Это полезно выполнять в случае, когда на лист передаётся много данных -
  //например, таблица из нескольких тысяч строк.
  //exApp.ScreenUpdating := False;
 
  exSheet.Cells[2, 2].Value := 'Таблица, переданная из внешней программы.';
  Row := 3;
  Col := 3;
  for j := 0 to N - 1 do begin
    exSheet.Cells[Row, Col + j].Value := 'Колонка №' + IntToStr(j + 1);
  end;
  Inc(Row);
  for i := 0 to M - 1 do
  for j := 0 to N - 1 do begin
    exSheet.Cells[Row + i, Col + j].Value := Arr[i, j];
  end;
 
  //Выравниваем ширину столбцов таблицы по ширине содержащихся в них данных.
  for j := 0 to N - 1 do begin
    exSheet.Columns[Col + j].AutoFit;
  end;
 
  //Включаем режим обновления окна Excel.
  //exApp.ScreenUpdating := True;
 
  //Отключаемся от объектов OLE-автоматизации.
  //В этом примере это делать не обязательно, т. к. соответствующие
  //переменные являются локальными и связанные с ними объекты будут
  //освобождены автоматически при выходе из процедуры.
  //Но если переменные являются глобальными и нам они в дальнейшем
  //не понадобятся, то следует их освободить.
  //Код обнуления, в случае глобальных переменных, следует добавить,
  //например, в обработчик события OnDestroy формы. Или в раздел
  //finalization модуля.
  //Если объекты OLE-автоматизации не освободить, то процесс Excel и связанные
  //объекты Excel так и останутся в памяти.
  exSheet := UnAssigned;
  exBook := UnAssigned;
  exApp := UnAssigned;
end;

спасибо тока что-то я не понимаю не могли бы вы скинуть готовое в zip



0



Mawrat

13094 / 5875 / 1706

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

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

14.03.2011, 21:23

9

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

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
uses
  ComObj;
 
procedure TForm1.Button1Click(Sender: TObject);
const
  M = 7;
  N = 10;
var
  exApp, exBook, exSheet : Variant;
  Arr : array of array of Integer;
  i, j, Row, Col : Integer;
begin
  try
    //Попытка подключиться к уже запущенному экземпляру Excel.
    exApp := GetActiveOleObject('Excel.Application');
  except
    try
      //Попытка запустить и подключиться к Excel.
      exApp := CreateOleObject('Excel.Application');
    except
      MessageDlg(
        'Не удалось подключиться к Excel. Действие отменено.'
        ,mtError, [mbOK], 0
      );
      Exit;
    end;
  end;
 
  SetLength(Arr, M, N);
  Randomize;
  for i := 0 to M - 1 do
  for j := 0 to N - 1 do begin
    Arr[i, j] := Random(10); //0..9.
  end;
 
  exApp.Visible := True;
  //Создаём рабочую книгу.
  exBook := exApp.Workbooks.Add;
  //Подключаемся к первому листу раб. книги.
  exSheet := exBook.Worksheets[1];
 
  //Для ускорения вывода данных в Excel, можно отключать обновление окна Excel.
  //Это полезно выполнять в случае, когда на лист передаётся много данных -
  //например, таблица из нескольких тысяч строк.
  //exApp.ScreenUpdating := False;
 
  exSheet.Cells[2, 2].Value := 'Таблица, переданная из внешней программы.';
  Row := 3;
  Col := 3;
  for j := 0 to N - 1 do begin
    exSheet.Cells[Row, Col + j].Value := 'Колонка №' + IntToStr(j + 1);
  end;
  Inc(Row);
  for i := 0 to M - 1 do
  for j := 0 to N - 1 do begin
    exSheet.Cells[Row + i, Col + j].Value := Arr[i, j];
  end;
 
  //Выравниваем ширину столбцов таблицы по ширине содержащихся в них данных.
  for j := 0 to N - 1 do begin
    exSheet.Columns[Col + j].AutoFit;
  end;
 
  //Включаем режим обновления окна Excel.
  //exApp.ScreenUpdating := True;
 
  //Отключаемся от объектов OLE-автоматизации.
  //В этом примере это делать не обязательно, т. к. соответствующие
  //переменные являются локальными и связанные с ними объекты будут
  //освобождены автоматически при выходе из процедуры.
  //Но если переменные являются глобальными и нам они в дальнейшем
  //не понадобятся, то следует их освободить.
  //Код обнуления, в случае глобальных переменных, следует добавить,
  //например, в обработчик события OnDestroy формы. Или в раздел
  //finalization модуля.
  //Если объекты OLE-автоматизации не освободить, то процесс Excel и связанные
  //объекты Excel так и останутся в памяти.
  exSheet := UnAssigned;
  exBook := UnAssigned;
  exApp := UnAssigned;
end;

Вложения

Тип файла: rar SendArrToExcel.rar (175.6 Кб, 78 просмотров)



1



dimon!

1 / 1 / 0

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

Сообщений: 53

14.03.2011, 21:27

 [ТС]

10

Цитата
Сообщение от Mawrat
Посмотреть сообщение

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

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
uses
  ComObj;
 
procedure TForm1.Button1Click(Sender: TObject);
const
  M = 7;
  N = 10;
var
  exApp, exBook, exSheet : Variant;
  Arr : array of array of Integer;
  i, j, Row, Col : Integer;
begin
  try
    //Попытка подключиться к уже запущенному экземпляру Excel.
    exApp := GetActiveOleObject('Excel.Application');
  except
    try
      //Попытка запустить и подключиться к Excel.
      exApp := CreateOleObject('Excel.Application');
    except
      MessageDlg(
        'Не удалось подключиться к Excel. Действие отменено.'
        ,mtError, [mbOK], 0
      );
      Exit;
    end;
  end;
 
  SetLength(Arr, M, N);
  Randomize;
  for i := 0 to M - 1 do
  for j := 0 to N - 1 do begin
    Arr[i, j] := Random(10); //0..9.
  end;
 
  exApp.Visible := True;
  //Создаём рабочую книгу.
  exBook := exApp.Workbooks.Add;
  //Подключаемся к первому листу раб. книги.
  exSheet := exBook.Worksheets[1];
 
  //Для ускорения вывода данных в Excel, можно отключать обновление окна Excel.
  //Это полезно выполнять в случае, когда на лист передаётся много данных -
  //например, таблица из нескольких тысяч строк.
  //exApp.ScreenUpdating := False;
 
  exSheet.Cells[2, 2].Value := 'Таблица, переданная из внешней программы.';
  Row := 3;
  Col := 3;
  for j := 0 to N - 1 do begin
    exSheet.Cells[Row, Col + j].Value := 'Колонка №' + IntToStr(j + 1);
  end;
  Inc(Row);
  for i := 0 to M - 1 do
  for j := 0 to N - 1 do begin
    exSheet.Cells[Row + i, Col + j].Value := Arr[i, j];
  end;
 
  //Выравниваем ширину столбцов таблицы по ширине содержащихся в них данных.
  for j := 0 to N - 1 do begin
    exSheet.Columns[Col + j].AutoFit;
  end;
 
  //Включаем режим обновления окна Excel.
  //exApp.ScreenUpdating := True;
 
  //Отключаемся от объектов OLE-автоматизации.
  //В этом примере это делать не обязательно, т. к. соответствующие
  //переменные являются локальными и связанные с ними объекты будут
  //освобождены автоматически при выходе из процедуры.
  //Но если переменные являются глобальными и нам они в дальнейшем
  //не понадобятся, то следует их освободить.
  //Код обнуления, в случае глобальных переменных, следует добавить,
  //например, в обработчик события OnDestroy формы. Или в раздел
  //finalization модуля.
  //Если объекты OLE-автоматизации не освободить, то процесс Excel и связанные
  //объекты Excel так и останутся в памяти.
  exSheet := UnAssigned;
  exBook := UnAssigned;
  exApp := UnAssigned;
end;

ясно) а вот откуда берутся эти числа?? у меня в программе ведется счет как мне свой счет в эти калонки занести?



0



Mawrat

13094 / 5875 / 1706

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

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

14.03.2011, 21:34

11

Это зависит от того, в каком виде программа формирует выходные данные.
Т. е., надо ответить вот на эти вопросы:
1. Могут ли быть представлены выходные данные (те которые надо распечатать на листе Excel) в виде таблицы?
2. Какое количество строк в такой таблице? — Это количество неизменно или может быть разным?

Если в программе вывод идёт в Label, то при работе с Excel вместо:

Delphi
1
Label1.Caption := 'Какой-то текст.';

будет:

Delphi
1
exSheet.Cells[Row, Col].Value := 'Какой-то текст.';

Здесь Row — номер строки на листе Excel, Col — номер столбца. Нумерация идёт от единицы.



1



dimon!

1 / 1 / 0

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

Сообщений: 53

16.03.2011, 22:59

 [ТС]

12

Цитата
Сообщение от Mawrat
Посмотреть сообщение

Это зависит от того, в каком виде программа формирует выходные данные.
Т. е., надо ответить вот на эти вопросы:
1. Могут ли быть представлены выходные данные (те которые надо распечатать на листе Excel) в виде таблицы?
2. Какое количество строк в такой таблице? — Это количество неизменно или может быть разным?

Если в программе вывод идёт в Label, то при работе с Excel вместо:

Delphi
1
Label1.Caption := 'Какой-то текст.';

будет:

Delphi
1
exSheet.Cells[Row, Col].Value := 'Какой-то текст.';

Здесь Row — номер строки на листе Excel, Col — номер столбца. Нумерация идёт от единицы.

Ох спасибо большое! выручил так выручил)



0



dimon!

1 / 1 / 0

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

Сообщений: 53

23.05.2011, 22:54

 [ТС]

13

Цитата
Сообщение от Mawrat
Посмотреть сообщение

Это зависит от того, в каком виде программа формирует выходные данные.
Т. е., надо ответить вот на эти вопросы:
1. Могут ли быть представлены выходные данные (те которые надо распечатать на листе Excel) в виде таблицы?
2. Какое количество строк в такой таблице? — Это количество неизменно или может быть разным?

Если в программе вывод идёт в Label, то при работе с Excel вместо:

Delphi
1
Label1.Caption := 'Какой-то текст.';

будет:

Delphi
1
exSheet.Cells[Row, Col].Value := 'Какой-то текст.';

Здесь Row — номер строки на листе Excel, Col — номер столбца. Нумерация идёт от единицы.

Здравствуйте! вы мне помогали с Екселем, а можно ли задавать ширину столбцов? Если да то как?



0



Mawrat

13094 / 5875 / 1706

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

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

24.05.2011, 20:29

14

Цитата
Сообщение от dimon!
Посмотреть сообщение

а можно ли задавать ширину столбцов? Если да то как?

В контексте выше приведённого кода, ширина столбцов и высота строк, выраженная в «пунктах». 1 пункт — это примерно 7 — 8 пикселов при установленном масштабе в Windows в 96 пикселов на 1 дюйм.

Delphi
1
2
3
4
5
6
7
8
  //Устанавливаем ширину столбца, в котором расположена ячейка
  //с координатами [Row, Col], равной 100 пунктов.
  exSheet.Cells[Row, Col].ColumnWidth = 100;
  //Установка ширины для всех столбцов, входящих в диапазон exRng, равной 50 пунктов.
  exRng.ColumnWidth = 50;
  
  //Установка высоты для всех строк, входящих в диапазон exRng, равной 20 пунктов.
  exRng.RowHeight = 20;



0



уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Сегодня, в последний рабочий день недели, практически весь день провозился над передачей данных из Delphi в Word. Так как подозрение есть, что работа продолжится то решил кое-какие моменты по работе с Microsoft Word в Delphi запечатлеть и у себя в блоге. Написать такую мини-шпаргалку (тем более, что по Excel уже кое что есть).

Для начала, немного общих моментов по работе с MS Office в Delphi. И первое, что мы сделаем — это создадим объект Word.Application. Создается этот объект абсолютно также, как и объект Excel.Application:

uses ComObj;
var Word: variant;
[...]
procedure CreateWord(const Visible: boolean);
begin
  Word:=CreateOleObject('Word.Application');
  Word.Visible:=Visible;
end;

Всё достаточно просто. Далее мы можем работать с объектом следующим образом:

  1. Создавать документ Word с нуля
  2. Открыть уже существующий документ и изменить в нем текст для получения необходимой формы документа.

Рассмотрим оба варианта, т.к. оба они имеют как свои плюсы, так и недостатки.

Чтобы создать новый документ необходимо выполнить метод Add у коллекции Documents, т.е.:

[...]
Word.Documents.Add
[...]

и после этой операции уже начинать работать с документам обращаясь к нему по индексу или имени в коллекции. Также, можно создать новый документ по шаблону (*.dot). Для этого необходимо выполнить тот же метод Add, но с одним входным параметром — путем к файлу-шаблону:

[...]
Word.Documents.Add(TamplatePath:string);
[...]

Чтобы получить список всех открытых в данный момент документов Word можно воспользоваться следующим листингом:

[...]
var List: TStringList;
    i: integer;
begin
  List:=TStringList.Create;
  for i:=1 to Word.Documents.Count do
    List.Add(Word.Documents.Item(i).Name);
end;
[...]

Обратите внимание, что нумерация начинается с 1, а не с нуля. Чтобы активировать любой документ из коллекции для работы, необходимо выполнить метод Activate:

Word.Documents.Item(index).Activate

где index — номер документа в коллекции.

Теперь можно приступать к записи и чтению документа. Для работы с текстов в документе Word, как и в Excel для работы с ячейками таблицы, определен объект Range. Именно методы этого объекта и дают нам возможность работы с текстом. Для начала рассмотрим работу двух основных методов: InsertBefore и InsertAfter.

Как следует из название — первый метод вставляет текст в начало содержимого Range, а второй — в конец. При этом сам объект Range может содержать как весть документ (Document) так и какую-либо его часть. Например, в следующем листинге я вставлю строку в начало документа и затем методом InsertAfter буду добавлять несколько строк текста в конец документа:

[...]
Word.ActiveDocument.Range.InsertBefore('Hello World');
Word.ActiveDocument.Range.InsertAfter('текст после Hello World');
Word.ActiveDocument.Range.InsertAfter('окончание строки в документа');
[...]

При выполнении этих трех операции Range содержал весь документ.

Если работать со всем документом неудобно, а необходимо, например выделить фрагмент с 50 по 100 символ и работать с ним, то можно воспользоваться функцией Range, которая вернет нам необходимый объект Range:

var MyRange: variant;
begin
  MyRange:=WordActiveDocument.Range(50,100);
  MyRange.InsertBefore('Привет');//всё, что было после 50-го символа сдвинулось вправо
end;

Это что касается записи текста. Решение обратной задачи — чтения текста из документа ещё проще. Достаточно воспользоваться свойством Text у объекта Range:

[...]
ShowMessage(Word.ActiveDocument.Range.Text) //весь текст в документе
[...]

Также для чтения документа можно воспользоваться коллекцией документа Words (слова). За слово принимается непрерывный набор символов — цифр и букв, который оканчивается пробелом.

Перечисляются слова документа точно также как и при работе с коллекцией документов, т.е. первое слово имеет индекс 1 последнее — Word.Count.

[...]
  ShowMessage(Word.ActiveDocument.Words.Item(Word.ActiveDocument.Words.Count).Text)
[...]

В данном случае я вывел на экран последнее слово в документе.

Очевидно, что приведенный выше способ работы с документам хорош в случае, когда требуется создать относительно простой документ Word и не требуется лишний раз рассчитывать фрагменты текста, правильно вставлять таблицы и т.д. Если же необходимо работать с документами, которые имеют сложное содержание, например текст в перемежку с рисунками, таблицами, а сам текст выводится различными шрифтами, то, на мой взгляд наиболее удобно использовать второй способ работы с Word в Delphi — просто заменить текст в уже заранее заготовленном документа.

2. Работа с документами Word в Delphi. Открытие готового документа и замена текста.

Чтобы открыть заранее заготовленный документ Word в Delphi достаточно воспользоваться методом Open у коллекции Documents, например так:

var FilePath: string;
[...]
  Word.Documents.Open(FilePath)
[...]

Метод Open можно вызывать с несколькими аргументами:

  • FileName: string — путь и имя файла;
  • ConfirmConversions: boolean — False — не открывать диалоговое окно «Преобразование файла» при открытии файла, формат которого не соответствует формату Word (doc или docx)
  • ReadOnly:boolean — True — открыть документ в режиме «Только для чтения»
  • AddToRecentFiles: boolean — True, чтобы добавить документ в список недавно открытых документов.
  • PasswordDocument: string — пароль для открытия документа
  • PasswordTemplate: string — пароль для открытия шаблона
  • Revert : boolean — True, чтобы вернуться к сохраненному документу, если этот документ открывается повторно.
  • WritePasswordDocument: string — пароль для сохранения измененного документа в файле
  • WritePasswordTemplate:string — пароль для сохранения изменений в шаблоне
  • Format:integer — формат открываемого документа.

Обязательным параметром метода Open является только FileName, остальные — могут отсутствовать. Если же Вам необходимо воспользоваться несколькими параметрами, то их необходимо явно указывать при вызове метода, например:

[...]
  Word.Documents.Open(FileName:=FilePath, ReadOnly:=true)
[...]

В этом случае документ открывается в режиме «Только для чтения». При таком способе вызова (с явным указанием аргументов) положение аргументов может быть произвольным.

Что касается последнего аргумента — Format, то он может принимать  целочисленные значения (применительно к версиям Microsoft Word 2007 и выше) от 0 до 13. При этом, для того, чтобы открыть «родные» вордовские документы (doc) достаточно использовать значения 0 или 6.

Теперь, когда документ открыт его необходимо преобразовать. Обычно я делаю следующим образом: в тех местах документа, в которые необходимо вставить текст я расставляю либо закладки, либо простые строки текста, например, обрамленные символом $ или #. И затем просто выполняю поиск и замену подстрок следующим образом:

function FindAndReplace(const FindText,ReplaceText:string):boolean;
  const wdReplaceAll = 2;
begin
  Word.Selection.Find.MatchSoundsLike := False;
  Word.Selection.Find.MatchAllWordForms := False;
  Word.Selection.Find.MatchWholeWord := False;
  Word.Selection.Find.Format := False;
  Word.Selection.Find.Forward := True;
  Word.Selection.Find.ClearFormatting;
  Word.Selection.Find.Text:=FindText;
  Word.Selection.Find.Replacement.Text:=ReplaceText;
  FindAndReplace:=Word.Selection.Find.Execute(Replace:=wdReplaceAll);
end;

Приведенная выше функция позволяет провести поиск и замену текстового фрагмента во всём документе. Для того, чтобы ограничить возможности пользователя при работе с шаблоном документа я обычно ставлю на необработанный файл пароль, а после обработки — пароль снимаю и сохраняю документ с другим названием в необходимую директорию.

Вот, наверное, самые-самые простые методы работы с Word в Delphi. Кстати, пишу пост и, думаю, что у кого-то из читателей может возникнуть вопрос: причём тут Delphi в Internet и Word в Delphi? :) Честно говоря, приведенный выше фрагменты кода можно использовать для нужд в Internet с натяжкой, например, при автосоставлении небольших отчётов по чему-либо. А вообще, в недалеком будущем, есть в планах поразбираться с Тезаурусом Word и попробовать составить небольшой синонимайзер для собственных нужд — он-то и пригодится нам в Internet :)

3.1
8
голоса

Рейтинг статьи

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

  
К статье прилагаются исходный
код примера и база данных. Выполнены в
Delphi 7 и Access 2003 соответственно.
 


Экспорт из БД в Word

 
   Статья написана на основе собственного опыта, и опыта других людей, полученного при общении в конференциях. И надеюсь, кому-нибудь хоть сколько поможет.
   В статье приведены примеры работы с:
   — таблицами;

  
— закладками;

   — колонтитулами;

   — надписями;

   — шрифтами;

   — курсором.

 
   Не буду углубляться в особенности позднего и раннего связывания, т.к. информации на эту тему уже достаточно.
   Итак, стоит задача экспортировать некую таблицу в Word. Даже не так, стоит задача сформировать сложный документ с колонтитулами таблицами заголовками и т.д., и т.п.
   Есть два замечательных способа добывать информацию об интерфейсе Word:
   — для того чтобы узнать, как что-то сделать из Delphi в Word-e надо в Word-е зайти в меню Сервис/Макрос/Начать запись… Потом сделать в Word-e то, что надо сделать из Delphi и закончить запись макроса. И наконец Сервис/Макрос/Макросы… выбираем записанный… Изменить и смотрим, как он устроен. После этого
перевод синтаксиса VBA в синтаксис Delphi
осуществляется просто и непринужденно;
  — еще одним хорошим инструментом получения знаний являются компоненты типа TWordApplication. Кидаем его на форму, в любом операторе набираем WordApplication1., нажимаем
«Сtrl + Пробел» и внимательно читаем. Смысл доступных функций и свойств обычно понятен интуитивно.
   Есть, еще один, как мне сказали, наиболее логичный способ – справка VBA, но что-то не довелось мне ею пользоваться…
   Теперь немного теории, добытой этими путями…


  

W1: TWordApplication;
Vr: OleVariant;


   У Wod есть коллекция документов:
  

Vr := номер нужного документа;
//так можно обратиться к нужному документу
w1.Documents.Item(vr);


   У всякой коллекции есть свойство count – количество таким образом
w1.Documents.count – количество документов.
   Использование переменной типа olevariant (в данном случае vr) иногда требуется, иногда нет.
   У документа есть свои коллекции:

  
   1. буквы (characters):

// так можно получить доступ
// к коллекции букв активного документа
w1.ActiveDocument.Characters


   Теперь можно получить доступ к:
 

w1.ActiveDocument.Characters.Items(vr) // конкретной букве
w1.ActiveDocument.Characters.Count // количеству букв


   2. таблицы:

 

W1.activedocument.tables


   А вот так:
 

W1.ActiveDocument.Tables.Item(
  W1.ActiveDocument.Tables.Count).Columns.Item(2).Select;


   можно выбрать вторую колонку последней таблицы.

   3. абзацы:


  

w1.ActiveDocument.Paragraphs


   4. фигуры:

  

W1.ActiveDocument.Shapes


   Ну и т.д….
   Еще есть полезные объекты selection – выбранная область и range – диапазон, а так-же функция select – выбрать. Выбрать можно таблицу, колонку (опять же W1.ActiveDocument.Tables.Item(W1.ActiveDocument.Tables.Count).Columns.Item(2).Select), букву, диапазон, абзац и т.д

   Кстати, очень часто приходится работать с объектом range. Так, например, чтобы вытащить текст из документа, можно написать:

st:=w1.ActiveDocument.Range(1,5).Text;
// Это будет текст с 1-го по 5-й символ
st:=W1.ActiveDocument.Paragraphs.Item(1).Range.Text;
// это будет текст первого абзаца текущего документа


   Теперь перейдем к конкретной реализации.
  
Пусть у нас есть база “Телефонный справочник”, в которой есть следующие таблицы справочники:
  

Flat(IdFlat,NameFlat)
Korp(IdKorp,NameKorp)
Ul(IdUl,NameUl)


   и дочерняя таблица Main (Id,Tel,Name,IdUl,House,IdKorp,IdFlat).

   Почему структура именно такая – не важно… это – просто пример.
Конкретная задача – экспортировать жильцов улиц Ахметова и Летчиков.
  
Причем выходной документ должен иметь титульную страницу, на которой пишется некий текст, со второй страницы идет верхний колонтитул, где тоже пишется некий текст. Далее существует два пути, как это реализовать.

   1. Без использования шаблона.
   Создается новый документ, где создаются колонтитулы надписи и т.д.
  
Этот путь использовать не стоит т.к. на разных компьютерах могут изначально стоять разные настройки страницы, шрифтов, абзацев и красиво сформированный документ у Вас на компьютере может ужасно выглядеть на другом. Можно, конечно, программно выставлять все необходимые настройки, но, во-первых, всего не учтешь, во-вторых это – большие тормоза и много кода.
   2. С использованием шаблона.
   Суть состоит в том, что заранее создается вордовский документ, который используется как шаблон. В нашем случае в шаблон в нужном месте в центре первой страницы ставим объект типа надпись, в котом выставляем нужный нам шрифт и выравнивание. Также делаем разрыв раздела. На второй странице в верхний колонтитул тоже вставляем объект надпись. В него мы будем вставлять название документа. Далее делаем макрос, в котором повторяем действия, которые нам нужно сделать из
Делфи:
   — в объект надпись на первой странице внести текст;
   — перейти в конец документа;
   — перейти в верхний колонтитул;
   — в объект надпись в колонтитуле внести текст;
   — вернуться на вторую страницу.

   Получаем следующий макрос:


 

Sub Макрос1()
'
' Макрос1 Макрос
' Макрос записан 08.11.2004 YurikGL
'
 ActiveDocument.Shapes("Text Box 8").Select
 Selection.TypeText Text:="текст на титульной"
 Selection.EndKey Unit:=wdStory
 If ActiveWindow.View.SplitSpecial <> wdPaneNone
   Then ActiveWindow.Panes(2).Close
 End If
 If ActiveWindow.ActivePane.View.Type = wdNormalView
                                                Or ActiveWindow.
   ActivePane.View.Type = wdOutlineView Then
   ActiveWindow.ActivePane.View.Type = wdPrintView
 End If
 ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
 Selection.HeaderFooter.Shapes("Text Box 5").Select
 Selection.TypeText Text:="Текст в колонтитуле"
 ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub


   Если преобразовать в код делфи, то получим:
 

//выбираем первую надпись
vr:='Text Box 8';
w1.ActiveDocument.Shapes.Item(vr).Select(EmptyParam);
//пишем туда текст
w1.Selection.TypeText('текст на титульной');
//переходим в конец документа
vr:=wdStory;
w1.Selection.EndKey(vr,EmptyParam);
{Всякие if-ы нам не нужны}
//переходим в верхний колонтитул
w1.ActiveWindow.ActivePane.View.SeekView:=wdSeekCurrentPageHeader;
vr:='Text Box 5';
w1.Selection.HeaderFooter.Shapes.Item(vr).Select(EmptyParam);
w1.Selection.TypeText('текст в колонтитуле');
w1.ActiveWindow.ActivePane.View.SeekView:=wdSeekMainDocument;


   Итак, мы сформировали титульную страницу и колонтитул…

   Кстати, кроме объектов “Надпись” можно еще эффективно использовать закладки. Чтобы узнать, как с ними работать, достаточно записать соответствующий макрос, а например, выбрать текст между первой и второй закладками можно так:
 

vr1,vr2,vr3,vr4:OleVariant;
vr1:=1;
vr2:=2;
vr3:=W1.ActiveDocument.Bookmarks.Item(vr1).End_;
vr4:=W1.ActiveDocument.Bookmarks.Item(vr2).End_;
W1.ActiveDocument.Range(vr3,vr4).Select;


   Кстати, если кто-нибудь найдет красивое решение без использования переменных OleVariant – отпишите мне на мыло.

   Вывести данные из базы в документ можно либо используя слияние, либо построчно. Для слияния код выглядит примерно так:
 

var
  vr1,vr2,vr3,vr4,vr5,vr6: OleVariant;
begin
 vr1:=0;
 vr2:=false;
 vr3:='Provider=Microsoft.Jet.OLEDB.4.0;Password="""";
  User ID=Admin;
  Data Source=C:DatawareDeplhi7Для статьиdb1.mdb;
  Mode=Read;Extended Properties="""";
  Jet OLEDB:System database="""";
  Jet OLEDB:Database Password="""";Jet OLEDB:Engine Type=5;';
 vr4:='SELECT Телефон, Корпус FROM QMain ORDER BY ФИО';
 vr5:=GetCurrentDir+'db1.mdb';
 
 vr6:=-1;
 winit;
 try
  w1.Connect;
  w1.Documents.Add(EmptyParam,EmptyParam,EmptyParam,EmptyParam);
  w1.Visible:=true;
  w1.Selection.Range.InsertDatabase(vr1,vr1,vr2,
         vr3,vr4,EmptyParam,EmptyParam,EmptyParam,
                EmptyParam,EmptyParam,vr5,EmptyParam,
                                  EmptyParam,EmptyParam);
 except
  w1.Disconnect;
end;


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

   Для построчного вывода я пользовался созданной мною процедурой TableExport(DataSet:TDataSet; Title, FlagText:string), которая приведена в примере. В нее передаются датасет, заголовок таблицы и текстовый параметр FlagText. Если он равен ‘’ то экспортируется вся таблица. В противном случае, экспортируются лишь те записи, у которых значение последнего поля равно FlagText. Это сделано для того, чтобы получив выборку, которая долго вычислялась, можно было ее разнести по нескольким таблицам в отчете.
  
Заголовок, ширина столбца и отображать или не отображать поле задаются следующими параметрами поля:
 

// заголовок
ADODataSet1.fields[1].DisplayLabel:='ФИО';
// ширина столбца
ADODataSet1.fields[1].tag:=round(w1.CentimetersToPoints(10));
// отображать поле
ADODataSet1.fields[1].Visible:=true;


   Кстати, в приведенном примере, данные сначала выбрасываются в Word, а потом одной командой преобразуются в таблицу.
   Теперь еще некоторые полезные возможности:
 

// проведение границы с левой стороны выбранной области
// Используется при формировании таблиц.
// Изменяя параметры, можно создавать произвольные таблицы
w1.Selection.Cells.Borders.Item(wdBorderLeft).
                                    LineStyle:=wdLineStyleSingle;
//изменение параметров шрифта
W1.Selection.Font.Size:=15;
//изменение параметров шрифта
W1.Selection.Font.bold:=1;
// получить номер последнего символа выбранной
// области
I:= W1.Selection.End;


   Если Вы работаете через OleContainer, то нелишними будут команды типа:
  

OleContainer1.OleObject.CommandBars.Item[
                                       'Standard'].Visible:=false;
OleContainer1.OleObject.CommandBars.Item[
                                     'Formatting'].Visible:=false;
OleContainer1.OleObject.CommandBars.Item[
                                        'Drawing'].Visible:=false;


   которые убирают соответствующие менюшки, которые обычно разлетаются по всей форме.
  
Если работать через CreateOleObject, то чтобы получить значение констант VisualBasic, которые Дельфи вообще говоря не понимает, надо внутри макроса написать MsgBox(нужная_константа). Тогда он покажет ее численное значение, их-то в Дельфи и использовать.
   Теперь привожу код всей программы:
  

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes,
  Graphics, Controls, Forms, Dialogs, StdCtrls,
  DB, ADODB, OleServer, Word2000;
 
type
  TForm1 = class(TForm)
    ADOConnection1: TADOConnection;
    ADODataSet1: TADODataSet;
    Button1: TButton;
    W1: TWordApplication;
 
    // Здесь удалено несколько строчек
 
    StatusLabel: TLabel;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure TableExport(DataSet:TDataSet;
                     Title, FlagText: string);
    Procedure TableLineSet;
    procedure WInit;
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses ComObj;
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
  vr: olevariant;
begin
  try
    statusLabel.Caption:='Формирую отчет ждите';
    winit;
    w1.Connect;
    //w1.Visible:=true;
    vr:=GetCurrentDir+'Shablon.doc';
    W1.Documents.Open(vr,EmptyParam,EmptyParam,
       EmptyParam,EmptyParam,EmptyParam,
         EmptyParam,EmptyParam,EmptyParam,
             EmptyParam,EmptyParam,EmptyParam);
    //выбираем первую надпись
    vr:='Text Box 8';
    w1.ActiveDocument.Shapes.Item(vr).Select(EmptyParam);
    //пишем туда текст
    w1.Selection.TypeText('текст на титульной');
    //переходим в конец документа
    vr:=wdStory;
    w1.Selection.EndKey(vr,EmptyParam);
    {Всякие if-ы нам не нужны}
    //переходим в верхний колонтитул
    w1.ActiveWindow.ActivePane.View.SeekView:=
                                      wdSeekCurrentPageHeader;
    vr:='Text Box 5';
    w1.Selection.HeaderFooter.Shapes.Item(vr).Select(EmptyParam);
    w1.Selection.TypeText('текст в колонтитуле');
    w1.ActiveWindow.ActivePane.View.SeekView:=wdSeekMainDocument;
    ADODataSet1.Close;
    ADODataSet1.CommandText:=
                        'SELECT [Main].[Tel], '+
                        '[Main].[name], '+
                        '[Main].[House], '+
                        '[Korp].[NameKorp], '+
                        '[Flat].[NameFlat], '+
                        '[Ul].[NameUl] '+
    ' FROM Main, Ul, Korp, Flat '+
    ' WHERE ([Main].[IdUl]=[Ul].[IdUl])
       And ([Main].[IdKorp]=[Korp].[IdKorp])
        And ([Main].[IdFlat]=[Flat].[IdFlat]) ';
    ADODataSet1.Open;
    // несколько строчек убрано
    // настраиваем параметры экспорта
    // заголовок
    ADODataSet1.fields[0].DisplayLabel:='Телефон';
    //ширина столбца
    ADODataSet1.fields[0].tag:=round(w1.CentimetersToPoints(2));
    //отображать поле
    ADODataSet1.fields[0].Visible:=true;
    //заголовок
    ADODataSet1.fields[1].DisplayLabel:='ФИО';
    //ширина столбца
    ADODataSet1.fields[1].tag:=round(w1.CentimetersToPoints(10));
    ADODataSet1.fields[1].Visible:=true;
    ADODataSet1.fields[2].DisplayLabel:='Дом';
    //ширина столбца
    ADODataSet1.fields[2].tag:=round(w1.CentimetersToPoints(1.5));
    ADODataSet1.fields[2].Visible:=true;
    ADODataSet1.fields[3].DisplayLabel:='Корпус';
    //ширина столбца
    ADODataSet1.fields[3].tag:=round(w1.CentimetersToPoints(1.5));
    ADODataSet1.fields[3].Visible:=true;
    ADODataSet1.fields[4].DisplayLabel:='Квартира';
    //ширина столбца
    ADODataSet1.fields[4].tag:=ound(w1.CentimetersToPoints(1.5));
    //отображать поле
    ADODataSet1.fields[4].Visible:=true;
    //не отображать поле
    ADODataSet1.fields[5].Visible:=false;
    //вызываем процедуру экспорта
    TableExport(ADODataSet1,'Живущие на улице
                                        Ахметова','АХМЕТОВА');
    TableExport(ADODataSet1,'Живущие на улице
                                        Летчиков','ЛЕТЧИКОВ');
    //отображем Word. Это можно было сделать и
    // вначале, но тогда вывод данных был бы
    // значительно медленнее
    w1.Visible:=true;
    w1.Disconnect;
    statusLabel.Caption:='';
  except
   on e:exception do begin
     w1.Visible:=true;
     statusLabel.Caption:='Отчет был сформирован неверно';
     w1.Disconnect;
     raise Exception.Create('Ошибка формирования
                                          отчета.'+#13+e.Message);
    end;
   end;
end;
 
procedure TForm1.TableExport(DataSet:TDataSet;
                                       Title, FlagText: string);
var
 i,ColCount, // количество колонок в таблице
 TableBeg, // Номер символа в начале таблицы
 TableBeg2: integer; // Номер символа в начале данных таблицы
 vr1,vr2:OleVariant;
 f:boolean;
 st:string;
 
Function ConvertString(S: string): string;
{это, казалось бы глупая функция, делает очень
важное дело.
При формировании таблицы в качестве разделителя по
умолчанию
используется "-", который может встречаться в
экспортируемых
записях. В этом случае в таблицу преобразуется
абсолютно
неверно. Чтобы избежать этого, мы меняем обычный 
"-" на символ
с кодом #173, который отображается точно так-же}
Begin
  Result := StringReplace(S, '-', #173,[]);
End;

Begin
{Процедура экспортирует лишь те записи датасета,
 у которых
значение последнего поля совпадает с FlagText
Если FlagText='' то экспортируются все записи.
Это связано с тем, что зачастую нужно разнести
в разные таблицы записи, полученные в результате
долго выполняемого запроса}
 
  Application.ProcessMessages;
  vr1:=wdStory;
  //переходим в конец документа
  w1.Selection.EndKey(vr1,EmptyParam); 
  //вставляем заголовок таблицы
  W1.ActiveDocument.Range(EmptyParam,EmptyParam).
                                            InsertAfter(Title);
  // далее идут настройки, что-бы заголовок не
  // отрывался от основной таблицы и все красиво выглядело
  W1.ActiveDocument.Paragraphs.Item(w1.
              ActiveDocument.Paragraphs.Count).Range.Select;
  W1.Selection.ParagraphFormat.KeepWithNext:=-1;
  W1.Selection.ParagraphFormat.SpaceAfter:=14;
  W1.Selection.Font.Size:=15;   //применяем шрифт
  W1.Selection.Font.bold:=1;
  //добавляем строчку
  //выбираем ее
  W1.ActiveDocument.Paragraphs.Add(EmptyParam);
  W1.ActiveDocument.Paragraphs.Item(w1.
              ActiveDocument.Paragraphs.Count).Range.Select;
  W1.Selection.ParagraphFormat.SpaceAfter:=0;
  vr1:=wdStory;
  //переходим в конец документа
  w1.Selection.EndKey(vr1,EmptyParam);
  // запоминаем положение курсора. Это - начало
  // будущей таблицы.
  // потом выберем весь оставшийся текст, чтобы
  // преобразовать его в таблицу
  // В ворде есть такая фунция "Преобразовать в
  // таблицу" ею и воспользуемся
  TableBeg:=W1.Selection.End_;
  DataSet.First;
  //вставляем заголовки для всех видимых полей
  for i:=0 to DataSet.FieldCount-1 do
   if DataSet.Fields[i].Visible then
    W1.ActiveDocument.Range(EmptyParam,EmptyParam).
     InsertAfter(convertstring(DataSet.Fields[i].
                                             DisplayLabel)+#9);
  Application.ProcessMessages;
  w1.Selection.EndKey(vr1,EmptyParam);
  //убираем последний символ табуляции
  {Вообще символ табуляции используется в качестве
  разделителя для столбцов таблиццы}
  w1.Selection.TypeBackspace;
  //применяем шрифт
  W1.ActiveDocument.Paragraphs.Item(w1.
    ActiveDocument.Paragraphs.Count).Range.Select;
  W1.Selection.Font.Size:=14;
  W1.Selection.Font.Italic:=1;
  W1.Selection.Font.bold:=0;
 
  //добавляем строчку
  W1.ActiveDocument.Paragraphs.Add(EmptyParam);
  // флаг для определения, были ли в таблице вообще
  // записи
  // для экспорта
  f:=true;
  // в эту строчку будем экспортировать текст
  // таблицы
  st:='';
  TableBeg2:=W1.Selection.End_; //начало данных в таблице
 
 if dataset.RecordCount>0 then begin
  Repeat
    Application.ProcessMessages;
    if (dataset.fields[DataSet.Fields.Count-1].
              AsString=FlagText) or (FlagText='')
      then begin
        // через табуляцию выводим все видимые поля
        for i:=0 to DataSet.FieldCount-1 do
         if DataSet.Fields[i].Visible
         then st:=st+DataSet.Fields[i].AsString+#9;
        // убираем последний символ табуляции
        SetLength(st,length(st)-1); 
        st:=st+#13;   // перенос строки
        f:=false;
           end;
    dataset.Next;
  until dataset.Eof;
  //уходим в конец текста
  w1.Selection.EndKey(vr1,EmptyParam);
  //вставляем данные таблицы
  W1.Selection.InsertAfter(convertstring(st));
  vr1:=TableBeg2;        //начало данных таблицы
  vr2:=W1.Selection.End_;  //конец таблицы
  W1.ActiveDocument.Range(vr1,vr2).Select;
  W1.Selection.Font.Size:=12;
  W1.Selection.Font.bold:=0;
  W1.Selection.Font.Italic:=0;
  end;
  //в том случае, если не экспортировалось ни одной
  // записи формируем пустую строчку
  if f then begin
    for i:=0 to DataSet.FieldCount-1 do
      if DataSet.Fields[i].Visible then
        W1.ActiveDocument.Range(EmptyParam,
             EmptyParam).InsertAfter(' '+#9);
    w1.Selection.EndKey(vr1,EmptyParam);
    w1.Selection.TypeBackspace;
            end;
   Application.ProcessMessages;
   vr1:=TableBeg; //начало будущей таблицы
   vr2:=W1.Selection.End_; //конец будущей таблицы
   //выбираем этот диапазон
   W1.ActiveDocument.Range(vr1,vr2).Select;
   //и преобразуем его в таблицу
   W1.Selection.ConvertToTable(EmptyParam,
      EmptyParam,
      EmptyParam,EmptyParam,EmptyParam,EmptyParam,
      EmptyParam,EmptyParam,EmptyParam,EmptyParam,
      EmptyParam,EmptyParam,EmptyParam,EmptyParam,
      EmptyParam,EmptyParam);
   colcount:=1;
   //выставляем ширины колонок
    for i:=0 to DataSet.FieldCount-1 do
      if DataSet.Fields[i].Visible then begin
        W1.ActiveDocument.Tables.Item(W1.
                          ActiveDocument.Tables.
          Count).Columns.Item(colcount).Width:=
                            DataSet.Fields[i].Tag;
        inc(colcount);
        Application.ProcessMessages;
     end;
 
  TableLineSet;
  // эта процедура прорисовывает нужные
  // границы таблицы
  W1.ActiveDocument.Paragraphs.Add(EmptyParam);
  W1.ActiveDocument.Paragraphs.Item(w1.
   ActiveDocument.Paragraphs.Count-1).Range.Select;
  W1.Selection.ParagraphFormat.KeepWithNext:=0;
End;
 
// эта процедура прорисовывает нужные границы таблицы
Procedure TForm1.TableLineSet; 
Begin
  w1.Selection.Cells.Borders.Item(wdBorderLeft).
   LineStyle:=wdLineStyleSingle;
  w1.Selection.Cells.Borders.Item(wdBorderRight).
   LineStyle:=wdLineStyleSingle;
  w1.Selection.Cells.Borders.Item
 (wdBorderHorizontal).LineStyle:=wdLineStyleSingle;
  w1.Selection.Cells.Borders.Item(wdBorderTop).
   LineStyle:=wdLineStyleSingle;
  w1.Selection.Cells.Borders.Item(wdBorderBottom).
   LineStyle:=wdLineStyleSingle;
  w1.Selection.Cells.Borders.Item
   (wdBorderVertical).LineStyle:=wdLineStyleSingle;
End;
 
procedure TForm1.WInit;
Begin
 // для избежания глюков полезно убивать
 // используемые компоненты
 // и потом их создавать заново...
 W1.free;
 W1:=TWordApplication.Create(Form1);
 //Чтобы всегда новое приложение запускалось
 w1.connectkind:=ckNewInstance;
End;
 
procedure TForm1.Button2Click(Sender: TObject);
var
  vr1,vr2,vr3,vr4,vr5:OleVariant;
begin
  vr1:=0;
  vr2:=false;
  vr3:='Provider=Microsoft.Jet.OLEDB.4.0;
   Password="""";
   User ID=Admin;Data
   Source=C:DatawareDeplhi7Для статьиdb1.mdb;
   Mode=Read;Extended Properties="""";
   Jet OLEDB:System database="""";
   Jet OLEDB:Database Password="""";
   Jet OLEDB:Engine Type=5;';
  vr4:='SELECT Телефон, Корпус FROM QMain ORDER BY ФИО';
  vr5:=GetCurrentDir+'db1.mdb';
  winit;
  try
    w1.Connect;
    w1.Documents.Add(EmptyParam,EmptyParam,
                        EmptyParam,EmptyParam);
    w1.Visible:=true;
    w1.Selection.Range.InsertDatabase(vr1,vr1,vr2,
       vr3,vr4,EmptyParam,EmptyParam,EmptyParam,
          EmptyParam,EmptyParam,vr5,EmptyParam,
                           EmptyParam,EmptyParam);
  except
    w1.Disconnect;
  end;
end;
 
end.


   Если кто-то увидит в данной статье свои приемы, которые я здесь описал, пожалуйста, не обижайтесь :).
 

Дата: 12.01.2006,
Автор:
Глущенко
Юрий, aka YurikGL.

Понравилась статья? Поделить с друзьями:
  • Как вывести в excel с фильтра список
  • Как вывести в excel регрессионную статистику
  • Как вывести в excel картинки
  • Как вывести в excel для графика функцию
  • Как вывести в excel данные с сайта