Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.10.03;
Скачать: CL | DM;

Вниз

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

 
azamatufa ©   (2010-07-13 08:47) [0]

Есть шаблон в котором есть куски текста ключевые (#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" ? (ведь юзер может нажать Да и запороть шаблон).

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


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

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


 
azamatufa ©   (2010-07-13 09:12) [2]

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

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


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


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;


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

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


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

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


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

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


 
azamatufa ©   (2010-07-13 10:18) [7]

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

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

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


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

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


 
azamatufa ©   (2010-07-13 13:27) [9]

Юрий, а как бы "все" поместить в один 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 13:40) [10]

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


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

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

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


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

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

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


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

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


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

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


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

> W.Free;

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


 
azamatufa ©   (2010-07-13 15:02) [16]


> ixen

спасибо за unassigned!

> Двенадцать

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


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

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

используй dot


 
azamatufa ©   (2010-07-13 15:12) [18]

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

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

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


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

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

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


 
azamatufa ©   (2010-07-13 15:31) [20]

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



Страницы: 1 вся ветка

Текущий архив: 2010.10.03;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.016 c
2-1279004324
бумбум
2010-07-13 10:58
2010.10.03
Русские буквы в PDF


2-1278658000
Виталий
2010-07-09 10:46
2010.10.03
Установить группу битов числа


2-1278941491
JohnKorsh
2010-07-12 17:31
2010.10.03
Альбомная ориентация листа при печати.


15-1278188988
Юрий
2010-07-04 00:29
2010.10.03
С днем рождения ! 4 июля 2010 воскресенье


15-1278534584
Юрий
2010-07-08 00:29
2010.10.03
С днем рождения ! 8 июля 2010 четверг