Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Подскажите как правильно выводить отчет в Word


azamatufa ©   (2010-07-13 08:47:00) 

Есть шаблон в котором есть куски текста ключевые (#familia$ #otchestvo$)

Делаю так:
W := CreateOleObject('Word.Application');
W.Documents.Open('rep_blank.rtf');
.....ищу ключевые тексты, заменяю их данными....
W.ActiveDocumnt.SaveAs('rep_done.rtf')
W.Quit;
W.Free;

ShellExecute(handle,'open',pchar('rep_done'),'','',1);


Открывается Отчет. Далее еще раз жму кнопку отчет. Пытается сделать SaveAs - но файл занят. Выходит окно сохранить 'rep_blank.rtf' ? (ведь юзер может нажать Да и запороть шаблон).

Поделитесь опытом, Спасибо!


azamatufa   (2010-07-13 15:31:00) [1]

Удалено модератором


ixen   (2010-07-13 15:21:00) [2]

> расскажи о преимуществах...?

тебе уже написали в 12 и 13 посту


azamatufa   (2010-07-13 15:12:00) [3]

а что дает дот?

если я скажу W.OpenFile (dot)
что будет?

расскажи о преимуществах...?


ixen   (2010-07-13 15:06:00) [4]

> спасибо! действительно можно защититься при помощи расширения
> rt!

используй dot


azamatufa   (2010-07-13 15:02:00) [5]


> ixen

спасибо за unassigned!

> Двенадцать

спасибо! действительно можно защититься при помощи расширения rt!


ixen   (2010-07-13 15:00:00) [6]

> W.Free;

его освобождают не с помощью free, а w:=unassigned;


Anatoly Podgoretsky   (2010-07-13 14:56:00) [7]

Я использую сервера с соответствующей закладки, это СОМ сервера, а не надшлепка в виде OLE


Anatoly Podgoretsky   (2010-07-13 14:55:00) [8]

Перейти на Ворд, с RTF, там ничего не надо сохранять для печати, кроме того Ворд поддерживает шаблоны *.dot как раз для того, что бы не испортить оригинал. Далее есть свойство подавления предупреждений. Кроме того очень легко запретить повторный запуск документа. Я правда с Вордом не работал, работал с Экселем, но ДОМ один и тот же.


ixen   (2010-07-13 14:49:00) [9]

> W.Documents.Open('rep_blank.rtf');

и почему у тебя шаблон в формате rtf ... есть специальный тип для шаблонов *.dot ... и этот файл пользователь не сможет пересохранить.. так как сформируется новый документ на основе dot файла..


ixen   (2010-07-13 14:44:00) [10]

> ShellExecute(handle,'open',pchar('rep_done'),'','',1);

Зачем документ открывать через ShellExecute? Не проще ли после того как он сформирован сделать:
 w.visible:=true;
 w.activate;
 w:=unassigned;


Двенадцать   (2010-07-13 13:40:00) [11]

вариант еще
'rep_blank.rtf' держать как 'rep_blank.rt'
переименовывать в temp директорию как GetGUID+'rep_blank.rtf', и с ним работать


azamatufa   (2010-07-13 13:27:00) [12]

Юрий, а как бы "все" поместить в один perort.pas
чтоб из формы Form1 лишь вызывать..?

так, процедура ThreadTerminated(Sender: TObject);  , помещенная в report.pas
ругается на не соответствие типов (method pointer vs  simple procedure..)

да, не в ник я в ООП, видимо...

подумаю сделать по-тупому:  

try
 удалить файл "готовый_отчет.doc"
 удалить файл "~готовый_отчет.doc"   (ну на всякий пожарный..)

except
 не могу удалить (файл занят) - закройте отчет...
 exit;
end;

W.CreateOle Word
W.open шаблон
W. напихать данными
w,saveAs "готовый отчет"
W.Quit;

тоже вариант...?


Юрий Зотов   (2010-07-13 10:27:00) [13]

Ну да. Идея в том, чтобы не дать юзеру второй раз нажать кнопку, пока не закроет Word.


azamatufa   (2010-07-13 10:18:00) [14]

d:\temp\Doc.doc  - это уже готовый файл?

т.е.
1. я создаю CreateOleObject(Word..)   пихаю туда данные..
2. Save AS
3. W.Close; W.Free

и потом Вашим методом создаю поток и открываю готовый файл.... так?
(при этом дизаблю кнопку)


Юрий Зотов   (2010-07-13 09:57:00) [15]

И еще маленькая поправка, тоже для надежности:
CommandLine := '"' + String(Buff) + '" "' + DocFileName + '"';
Потому что имя файла документа тоже может содержать пробелы.


Юрий Зотов   (2010-07-13 09:53:00) [16]

И, для надежности - файл шаблона сделать Read-Only.


Юрий Зотов   (2010-07-13 09:51:00) [17]

Вот так получше будет:
Win32Check(FindExecutable(DocFileName, nil, Buff) > 32);
вместо
FindExecutable(DocFileName, nil, Buff);


Юрий Зотов   (2010-07-13 09:43:00) [18]


uses
 ShellAPI;

type
 TMyThread = class(TThread)
 protected
   procedure Execute; override;
 end;

{ TMyThread }

procedure TMyThread.Execute;
const
 DocFileName = 'D:\Temp\Doc.doc';
var
 Buff: array[0..MAX_PATH] of char;
 CommandLine: string;
 SI: TStartupInfo;
 PI: TProcessInformation;
begin
 ZeroMemory(@Buff, SizeOf(Buff));
 FindExecutable(DocFileName, nil, Buff);
 CommandLine := '"' + String(Buff) + '" ' + DocFileName;
 ZeroMemory(@SI, SizeOf(SI));
 SI.cb := SizeOf(SI);
 Win32Check(CreateProcess(nil, PChar(CommandLine), nil, nil, False, 0, nil, nil, SI, PI));
 CloseHandle(PI.hThread);
 WaitForSingleObject(PI.hProcess, INFINITE);
 CloseHandle(PI.hProcess)
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
 Button1.Enabled := False;
 with TMyThread.Create(True) do
 begin
   FreeOnTerminate := True;
   OnTerminate := ThreadTerminated;
   Resume
 end
end;

procedure TForm1.ThreadTerminated(Sender: TObject);
begin
 Button1.Enabled := True
end;


azamatufa   (2010-07-13 09:12:00) [19]

Я еще хотел донести мысль, что все что создавалось при помощи Create - должно иметь в конце Free (я про W).

Йо...... Юрий, а чууточку подробнее, а?
Благодарю!


Юрий Зотов   (2010-07-13 08:58:00) [20]

1. Создать второй поток, прописав ему FreeOnTerminate = True.
2. Вместо ShellExecute использовать CreateProcess, вставив этот вызов в метод Execute второго потока.
3. Там же, сразу после после CreateProcess сначала вызвать WaitForSingleObject, а потом 2 раза CloseHandle.
4. В обработчике нажатия на кнопку "Отчет" задизаблить ее.
5. В обработчике OnTerminate второго потока раздизаблить кнопку.


Наверх

Титульная страница Поиск, карта сайта Написать письмо