Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Отчет в Word


Автор: Dobromen 12.6.2016, 14:23
Программа работает. Запускает документ, но в него вносится всего одна строка "Отчет" , а затем выдает ошибку "Вызов отклонен" при нажатии на кнопку Break выделяет строку либо wdRng.Font.Name := 'Times New Roman'; либо wdRng.Font.Bold := True; то есть формирование отчета заканчивается либо на выводе слова "Отчет" без учета формата шрифта. либо с учетом формата шрифта, но в любом случае без учета регистра букв.
Почему происходит сбой?
Ко всему сказанному выше добавлю: во время написания кода редактор кода по идее должен выводить подсказки.. т. е. например когда пишешь edit1 и ставишь точку появляется раскрывающийся список где можно выбрать сответствующий компонент для edit, например text
НО когда ввожу wdDoc и ставлю точку в раскрывающемя списке нет таких компонентов как Font, content и прочее. Почему так? Может нужна какая то дополнительная библиотека???

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DB, ADODB, DBGrids, DBTables;

type
  TForm1 = class(TForm)
    Button1: TButton;
    SaveDialog1: TSaveDialog;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    TADOQuery1: TADOQuery;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  ComObj;

procedure TForm1.Button1Click(Sender: TObject);
const
  wdAlignParagraphCenter = 1;
  wdAlignParagraphLeft = 0;
  wdAlignParagraphRight = 2;

  wdLineStyleSingle = 1;
var
  wdApp, wdDoc, wdRng, wdTable : Variant;
  i, j, Res : Integer;
  D : TDateTime;
  Bm : TBookMark;
  Sd : TSaveDialog;
begin
  //{
  Sd := SaveDialog1; //SaveDialog1 уже должен быть на форме.
  //Если начальная папка диалога не задана, то в качестве начальной берём ту папку,
  //в которой расположен исполняемый файл нашей программы.
  if Sd.InitialDir = '' then Sd.InitialDir := ExtractFilePath( ParamStr(0) );
  //Запуск диалога сохранения файла.
  if not Sd.Execute then Exit;
  //Если файл с заданным именем существует, то запускаем диалог с пользователем.
  if FileExists(Sd.FileName) then begin
    Res := MessageBox(0, 'Файл с заданным именем уже существует. Перезаписать?'
      ,'Внимание!', MB_YESNO + MB_ICONQUESTION + MB_APPLMODAL);
    if Res <> IDYES then Exit;
  end;
  
  //Попытка запустить MS Word.
  try
    wdApp := CreateOleObject('Word.Application');
  except
    MessageBox(0, 'Не удалось запустить MS Word. Действие отменено.'
      ,'Внимание!', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
 
  //Делаем видимым окно MS Word. На постоянной основе или на время отладки.
  wdApp.Visible := True;
  //Создаём новый документ.
  wdDoc := wdApp.Documents.Add;
  //На случай, если очень много данных и wdApp.Visible := True - тогда
  //для ускорения работы отключаем перерисовку окна MS Word.
  wdApp.ScreenUpdating := False;
  try
    wdRng := wdDoc.Content; //Диапазон, охватывающий всё содержимое документа.

    //Параграф 1. Заголовок отчёта.

    //Заголовок отчёта и перевод строки.
    wdRng.InsertAfter('Отчёт'#13#10);
    //Выравнивание по центру.
    wdRng.ParagraphFormat.Alignment := wdAlignParagraphCenter;
    //Параметры шрифта.
    wdRng.Font.Name := 'Times New Roman';
    wdRng.Font.Bold := True;
    wdRng.Font.Size := '14';

    //Параграф 2. Общие сведения.

    //Формируем диапазон нового параграфа непосредственно за текущим диапазоном.
    wdRng.Start := wdRng.End;
    wdRng.InsertAfter(#13#10);
    D := Now;
    wdRng.InsertAfter('Дата: ' + FormatDateTime('dd.mm.yyyy', D) + #13#10);
    wdRng.InsertAfter('Время: ' + FormatDateTime('hh:nn:ss:zzz', D) + #13#10);
    //Сброс параметров параграфа.
    wdRng.ParagraphFormat.Reset;
    //Выравнивание по левому краю.
    wdRng.ParagraphFormat.Alignment := wdAlignParagraphLeft;
    //Отступ слева на 2 сантиметра. Размер отступа задаётся в типографских
    //единицах - в пунктах. 1 пункт = 0.035 сантиметра.
    //При записи в поле LeftIndent, отступ отсчитывается от левого поля на странице.
    //wdRng.ParagraphFormat.LeftIndent := 2 / 0.035;
    //Параметры шрифта.
    wdRng.Font.Reset; //Сброс параметров шрифта.
    wdRng.Font.Size := 12;
    wdRng.Font.Bold := True;

    //Параграф 3. Заголовок таблицы.

    wdRng.Start := wdRng.End;
    wdRng.InsertAfter(#13#10);
    wdRng.InsertAfter('Таблица 1. Размер и население стран.'#13#10);
    wdRng.ParagraphFormat.Reset;
    wdRng.Font.Reset;
    wdRng.Font.Size := 12;
    wdRng.Font.Bold := False;

    //Параграф 4. Таблица.

    if not TADOQuery1.Active then TADOQuery1.Open;

    wdRng.Start := wdRng.End;
    //Добавляем таблицу MS Word. Пока создаём таблицу с двумя строками.
    wdTable := wdDoc.Tables.Add(wdRng.Characters.Last, 2, TADOQuery1.Fields.Count);
    //Параметры линий таблицы.
    wdTable.Borders.InsideLineStyle := wdLineStyleSingle;
    wdTable.Borders.OutsideLineStyle := wdLineStyleSingle;
    //Сброс параметров параграфа.
    wdRng.ParagraphFormat.Reset;
    //Выравнивание всей таблицы - по левому краю.
    wdRng.ParagraphFormat.Alignment := wdAlignParagraphLeft;
    //Оформление шапки.
    wdRng := wdTable.Rows.Item(1).Range; //Диапазон первой строки.
    wdRng.ParagraphFormat.Alignment := wdAlignParagraphCenter;
    wdRng.Font.Size := 10;
    wdRng.Font.Bold := True;
    //Оформление первой строки данных - это вторая строка в таблице.
    //При добавлении следующих строк, их оформление будет копироваться с этой строки.
    wdRng := wdTable.Rows.Item(2).Range; //Диапазон второй строки.
    wdRng.ParagraphFormat.Alignment := wdAlignParagraphLeft;
    wdRng.Font.Size := 10;
    wdRng.Font.Bold := False;

    //Записываем шапку таблицы.
    for i := 0 to TADOQuery1.Fields.Count - 1 do
      wdTable.Cell(1, i + 1).Range.Text := TADOQuery1.Fields[i].DisplayName;
    //Записываем данные таблицы.
    TADOQuery1.DisableControls;
    Bm := TADOQuery1.GetBookMark;
    TADOQuery1.First;
    i := 1; //Текущая строка в таблице MS Word.
    while not TADOQuery1.Eof do begin
      Inc(i);
      //Если требуется, добавляем новую строку в конец таблицы.
      if i > 2 then wdTable.Rows.Add;
      //Записываем данные в строку таблицы MS Word.
      for j := 0 to TADOQuery1.Fields.Count - 1 do
        wdTable.Cell(i, j + 1).Range.Text := TADOQuery1.Fields[j].AsString;
      TADOQuery1.Next;
    end;
    TADOQuery1.GotoBookMark(Bm);
    TADOQuery1.EnableControls;

  finally
    //Включение перерисовки окна MS Word. В случае, если wdApp.Visible := True.
    wdApp.ScreenUpdating := True;
  end;

  wdApp.DisplayAlerts := False; //Отключаем режим показа предупреждений.
  try
    wdDoc.SaveAs(FileName:=Sd.FileName); //Запись документа в файл.
  finally
    wdApp.DisplayAlerts := True; //Включаем режим показа предупреждений.
  end;
 
  //Закрываем документ.
  //wdDoc.Close;
  //Закрываем MS Word.
  //wdApp.Quit;
end;

end.

Автор: Poseidon 13.6.2016, 17:55
Dobromen, попробуй работать с Word не напрямую через OLE, а с помощью http://forum.vingrad.ru/forum/topic-84634/0.html

Автор: Regulum 7.8.2016, 12:57
Обратите внимание на 89 строку вашего кода
Код

wdRng.Font.Size := '14';

Вы передаете строковый параметр целочисленному свойству, хотя дальше по тексту размер шрифта задаете верно  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)