Форум: "Начинающим";
Текущий архив: 2010.10.03;
Скачать: [xml.tar.bz2];
ВнизПодскажите как правильно выводить отчет в 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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.003 c