← →
Scorpio ©
(2005-12-19 14:47)
[0]
Добрый день мастера.
Подскажите как мне закрыть документ на програмном уровне, чтобы мне не вываливалась просьба о сохранении.
WordApplication1.Documents.Add(EmptyParam,EmptyParam);
WordApplication1.Selection.InsertAfter(" "+#13);
WordApplication1.Selection.InsertAfter(" "+#13);
WordApplication1.PrintOut;
// WordApplication1.DisplayAlerts := 1;
WordApplication1.Quit;
Пробовал с DisplayAlerts
поиграться, но так ничего и не получилось, все равно вываливается просьба сохранить документ.
← →
LORAN
(2005-12-19 15:22)
[1]
>>WordApplication1.DisplayAlerts := 1;
С какого перепоя
WordApplication1.DisplayAlerts := FALSE;
← →
Slym ©
(2005-12-19 15:27)
[2]
WordApp.Quit(false);
← →
Scorpio ©
(2005-12-20 09:35)
[3]
WordApplication1.DisplayAlerts := FALSE;
Он мне кидает ошибку:
[Error] Unit2.pas(64): Incompatible types: «TOleEnum» and «Boolean»
А что за переменная
WordApp.Quit(false);
Что ей присваивается ???
← →
Dmitrij_K
(2005-12-20 11:18)
[4]
Совсем не понимаю почему у меня работает такая неделфовая конструкция
doc.Close(SaveChanges:=False);
← →
scorpio ©
(2005-12-20 11:57)
[5]
Если работать с такой конструкцией:
var
w : variant;
w := createoleobject("word.basic");
w.filenew;
...
w.docclose(2);
Так она работает, но здесь проблема, я никак не могу найти как мне прыгать по строчкам, чтобы я мог поместить строку в нужное мне место по X*Y, и со своим шрифтом.
← →
umbra ©
(2005-12-20 12:08)
[6]
2 Scorpio © (20.12.05 09:35) [3]
в ворде DisplayAlerts не булевская переменная, а энумератор. может иметь одно из значений wdAlertsNone, wdAlertsMessageBox, wdAlertsAll.
Справка по Word VBA рулит!
← →
k2 ©
(2005-12-20 12:11)
[7]
если документ сохранять не нужно:ActiveDocument.Saved := false;
Доступ к приложению Word осуществляется, как правило, посредством основных двух объектов, Word.Application и Word.Document. Они же обеспечивают доступ и к другим объектам Word (текст, таблицы, кнопки, меню и т.д.). Наиболее легкий метод работы с COM-сервером Word базируется на использовании переменных типа Variant.
Давайте на примере рассмотрим создание документа Word помощью Delphi.
Для начала создадим новый проект (File | New | VCL Foms Application-Delphi) и поместим на него 4 кнопки (TButton). Поменяем заголовки (свойство Caption) этих кнопок на: «Создать документ Word», «Открыть документ Word», «Сохранить документ Word», «Закрыть документ Word». Как понятно из названий, мы будем открывать, создавать, сохранять и закрывать документ Word при нажатии на эти кнопки.
Чтобы начать работать с Word необходимо в модуле формы указать ссылку на использование библиотеки ComObj, поэтому в разделе uses мы дописываем ComObj. Также нам необходимо объявить переменную типа Variant. Давайте создадим обработчик события OnClick для кнопки «Создать документ Word» и напишем код:
Код
procedure TForm1.Button1Click(Sender: TObject);
begin
w:=CreateOleObject(‘Word.Application’);
end;
Если сейчас запустить нашу программу и нажать на кнопку «Создать документ Word», то приложение Word будет запущено, но его окно не будет отображено на экране монитора. В память компьютера будет загружен объект Application, который обеспечивает доступ ко всем внутренним объектам, коллекциям и свойствам. Сейчас нас интересует свойство Visible этого объекта. Если значение этого свойства установить в True, то окно приложения Word станет видимым. Поэтому давайте допишем еще одну строчку в наш код:
Код
procedure TForm1.Button1Click(Sender: TObject);
begin
w:=CreateOleObject(‘Word.Application’);// запуск приложения Word
w.Visible:=true; // делаем Word видимым
end;
Вот теперь если запустить программу и нажать на кнопку «Создать документ Word», то наше приложение Word станет видимым и отобразится на экране монитора.
Для того чтобы создать новый документ, необходимо использовать метод Add, коллекции Documents. Поэтому если мы хотим создать новый документ Word с помощью Delphi, необходимо написать:
Код
procedure TForm1.Button1Click(Sender: TObject);
begin
w:=CreateOleObject(‘Word.Application’);// запуск приложения Word
w.Documents.Add; // создание нового документа
w.Visible:=true; // делаем Word видимым
end;
В этом коде, после выполнения метода Add, будет создан новый документ, который отобразится в окне приложения Word. Обратите внимание, что видимым наш документ (w.Visible:=true) я делаю в самую последнюю очередь. При формировании отчетов, рекомендуется так делать. Это сокращает время создания отчетов и повышает производительность работы приложений.
С созданием документа Word в Delphi разобрались. Теперь перейдем к открытию документа Word. Для этого создаем обработчик события OnClick для кнопки «Открыть документ Word» и напишем следующее:
Код
procedure TForm1.Button2Click(Sender: TObject);
begin
w:=CreateOleObject(‘Word.Application’);// запуск приложения Word
w.Documents.Open(ExtractFilePath(paramstr(0))+’/Delphi and MS Word.doc’); //открываем документ Word находящийся в папке с программой
w.Visible:=true; // делаем Word видимым
end;
Синтаксис метода Open глядит следующим образом:
Код
Documents.Open(FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format)
Давайте рассмотрим аргументы метода 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, остальные параметры могут отсутствовать, как отсутствуют в вышеприведенном примере кода. Но если вдруг нам понадобится воспользоваться некоторыми из этих параметров, то их необходимо явно указать при вызове метода. Например, если мы решим открыть файл в режиме «Только для чтения», то код будет выглядеть следующим образом:
Код
procedure TForm1.Button2Click(Sender: TObject);
begin
w:=CreateOleObject(‘Word.Application’);// запуск приложения Word
w.Documents.Open(ExtractFilePath(paramstr(0))+’/DelphiSchool.doc’, ReadOnly:=true); // открываем документ Word находящийся в папке с программой в режиме «Только для чтения»
w.Visible:=true; // делаем Word видимым
end;
С открытием документа Word тоже разобрались. Переходим к сохранению документа. Для кнопки «Сохранить документ Word» создаем обработчик события OnClick и пишем:
Код
procedure TForm1.Button3Click(Sender: TObject);
begin
w:=CreateOleObject(‘Word.Application’);// запуск приложения Word
//открываем документ Word находящийся в папке с программой в режиме «Только для чтения»
w.Documents.Open(ExtractFilePath(paramstr(0))+’/DelphiSchool.doc’, ReadOnly:=true);
// сохраняем документ в папку с программой под именем DelphiSchool Copy.doc
w.ActiveDocument.SaveAs(ExtractFileDir(paramstr(0))+’/DelphiSchool Copy.doc’);
w.Visible:=true; // делаем Word видимым
end;
Аргументы метода SaveAs, их типы и функциональное назначение представлены ниже:
FileName: String — Путь и имя файла
FileFormat — Число Формат файла
LockComments: Boolean — True — не сохранять комментарии
Password: String — Пароль, который будет использоваться при открытии документа
AddToRecentFiles: Boolean — True — добавить имя файла в список меню File
WritePassword: String — Пароль, который будет использоваться для сохранения документа
ReadOnlyRecommended: Boolean — True — в последующем документ можно открыть «только для чтения»
EmbedTrueTypeFonts: Boolean — True — при сохранении перевести шрифты документа в TrueType
SaveNativePictureFormat: Boolean — Используется для импорта графики из форматов, не поддерживаемых Windows. True — импортировать только графику, поддерживаемую Windows
SaveFormsData: Boolean — True — сохранить форму документа без текста
SaveAsAOCELetter: Boolean — Используется в версиях Word для компьютеров Apple Macintosh
При вызове метода SaveAs, как и при Open, можно задавать как один, так и несколько аргументов. Но, как правило, достаточно только первого аргумента (путь и имя файла).
Ну и последнее что мы рассмотрим – это закрытие документа. Закрыть документы можно с помощью метода Close коллекции Documents. Создадим обработчик события OnClick для кнопки «Закрыть документ Word» и напишем код:
Код
procedure TForm1.Button4Click(Sender: TObject);
begin
w.ActiveDocument.Close(True); // сохраняем и закрываем Word
end;
После того как документ закрыт, можно закрывать и приложение Word:
Код
procedure TForm1.Button4Click(Sender: TObject);
begin
w.ActiveDocument.Close(True); // сохраняем и закрываем Word
w.Quit;
end;
К уроку (статье) Основы работы с MS Word. Создание, открытие, сохранение и закрытие документа Word с помощью Delphi прилагается исходник, посмотрев который, вы можете ознакомиться с полным исходным кодом программы и посмотреть как работает созданная программа. Исходный код сопровождается комментариями, благодаря чему вы сможете легко в нем разобраться. Но я настоятельно рекомендую делать все самостоятельно. Так вы лучше и быстрее усвоите то, о чем говорилось в этом уроке
Для того чтобы получить возможность скачать исходник Delphi к этому уроку, необходимо посетить сайт рекламодателя. После этого, появится ссылка на исходник Delphi к уроку Основы работы с MS Word. Создание, открытие, сохранение и закрытие документа Word с помощью Delphi
Нажмите на эту ссылку Ссылка
procedure TForm1.Button1Click(Sender: TObject); var Word: variant; begin try Word := CreateOleObject(‘Word.Application’); except ShowMessage(‘Не могу запустить Microsoft Word’); end; Word.Visible := True; end; |
Как создать новый документ Word в Delphi:
//Создание нового документа: Word.Documents.Add; |
Как открыть существующий документ Word в Delphi:
//Открытие существующего документа: Word.Documents.Open(‘c:test.doc’); |
Как добавить текст в документ Word в Delphi:
//Добавление текста в документ: Word.Selection.TypeText(Text:=‘Новый текст’); |
Как добавить абзац Word в Delphi:
//Добавление абзаца: Word.Selection.TypeParagraph; |
Как закрыть документ Word в Delphi:
//Закрытие документа Word.Quit; |
6.9K
04 апреля 2006 года
Britney
69 / / 20.03.2006
Теперь у меня появился другой вопрос. Прога у меня занимается тем, что создает отчеты. Для этого она находит в вордовском шаблоне метку(например NAME) и на ее место вставляет что-нить из полей формы (например, Петров Казимир Эдмундович). Специально для этого у меня написаны примитивные процедурки, типа такой:
procedure TForm1.N3Click(Sender: TObject); //ПРИКАЗ НА ОТЧИСЛЕНИЕ
var len,a,b:OleVariant;
i:integer;
FileName:OleVariant;
begin
Stop;
FiLeName:=ShablonName+’приказ на отчисление.doc’;
for i:=1 to 2 do
WordApplication1.Documents.Open(FileName,
EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam,EmptyParam,
EmptyParam,EmptyParam);
WordDocument1.ConnectKind:=ckAttachToInterface;
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
len:=Length(WordDocument1.Range.Text); //DATE
for i:=1 to len-4 do
begin
a:=i;
b:=i+4;
if WordDocument1.Range(a,b).Text=’DATE’ then
begin
WordDocument1.Range(a,b).InsertAfter(MaskEdit1.Text);
WordDocument1.Range(a,b).Cut;
break;
end;
end;
len:=Length(WordDocument1.Range.Text); //NAME
for i:=1 to len-4 do
begin
a:=i;
b:=i+4;
if WordDocument1.Range(a,b).Text=’NAME’ then
begin
WordDocument1.Range(a,b).InsertAfter(Edit7.Text+’ ‘+Edit8.Text+’ ‘+Edit9.Text);
WordDocument1.Range(a,b).Cut;
break;
end;
end;
len:=Length(WordDocument1.Range.Text); //SPEC
for i:=1 to len-4 do
begin
a:=i;
b:=i+4;
if WordDocument1.Range(a,b).Text=’SPEC’ then
begin
WordDocument1.Range(a,b).InsertAfter(Edit12.Text);
WordDocument1.Range(a,b).Cut;
break;
end;
end;
len:=Length(WordDocument1.Range.Text); //GROUP
for i:=1 to len-5 do
begin
a:=i;
b:=i+5;
if WordDocument1.Range(a,b).Text=’GROUP’ then
begin
WordDocument1.Range(a,b).InsertAfter(Edit11.Text);
WordDocument1.Range(a,b).Cut;
break;
end;
end;
len:=Length(WordDocument1.Range.Text); //DAT2
for i:=1 to len-4 do
begin
a:=i;
b:=i+4;
if WordDocument1.Range(a,b).Text=’DAT2′ then
begin
WordDocument1.Range(a,b).InsertAfter(MaskEdit2.Text);
WordDocument1.Range(a,b).Cut;
break;
end;
end;
len:=Length(WordDocument1.Range.Text); //DECAN
for i:=1 to len-5 do
begin
a:=i;
b:=i+5;
if WordDocument1.Range(a,b).Text=’DECAN’ then
begin
WordDocument1.Range(a,b).InsertAfter(Edit1.Text+’ ‘+Edit2.Text+’ ‘+Edit3.Text);
WordDocument1.Range(a,b).Cut;
break;
end;
end;
if (Image1.Picture.Height>0) and (CheckBox1.Checked) then
begin
Clipboard.Assign(Image1.Picture); //@}
len:=Length(WordDocument1.Range.Text);
for i:=1 to len-1 do
begin
a:=i;
b:=i+1;
if WordDocument1.Range(a,b).Text=’@’ then
begin
WordDocument1.Range(a,b).paste;
break;
end;
end;
end;
WordDocument1.Disconnect;
WordApplication1.Disconnect;
Play;
end;
Все бы хорошо, но процесс замены меток на данные из формы занимает от 2 до 5 секунд, независимо от мощности компа!Я прекрасно понимаю, что поиском меток можно заниматься и в фоновом режиме, а не при нажатии кнопок, но это все неважно! Меня интерисует почему все так долго происходит. Дело в Office или в используемых мною операциях, например:
WordDocument1.Range(a,b).Text=’@’;
WordDocument1.Range(a,b).paste;
make a unit UEventsSink
unit UEventsSink;
interface
uses
ActiveX, windows, ComObj, SysUtils;
type
IApplicationEvents = interface(IDispatch)
['{000209F7-0000-0000-C000-000000000046}']
procedure Quit; safecall;
end;
TApplicationEventsQuitEvent = procedure (Sender : TObject) of object;
TEventSink = class(TObject, IUnknown, IDispatch)
private
FCookie : integer;
FSinkIID : TGUID;
FQuit : TApplicationEventsQuitEvent;
// IUnknown methods
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
// IDispatch methods
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flag: Word;
var Params; VarResult, ExceptInfo, ArgErr: Pointer): HResult; stdcall;
protected
FCP : IConnectionPoint;
FSource : IUnknown;
procedure DoQuit; stdcall;
public
constructor Create;
procedure Connect (pSource : IUnknown);
procedure Disconnect;
property Quit : TApplicationEventsQuitEvent read FQuit write FQuit;
end;
implementation
function TEventSink.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result:= S_OK
else if IsEqualIID(IID, FSinkIID) then
Result:= QueryInterface(IDispatch, Obj)
else
Result:= E_NOINTERFACE;
end;
// GetTypeInfoCount
//
function TEventSink.GetTypeInfoCount(out Count: Integer): HResult;
begin
Result := E_NOTIMPL;
Count := 0;
end;
// GetTypeInfo
//
function TEventSink.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;
begin
Result := E_NOTIMPL;
pointer (TypeInfo) := NIL;
end;
// GetIDsOfNames
//
function TEventSink.GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
begin
Result := E_NOTIMPL;
end;
function TEventSink.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flag: Word; var Params; VarResult, ExceptInfo, ArgErr: Pointer): HResult;
begin
Result:= DISP_E_MEMBERNOTFOUND;
case DispID of
2: begin
DoQuit;
Result:= S_OK;
end;
end
end;
// DoQuit
//
procedure TEventSink.DoQuit;
begin
if not Assigned (Quit) then Exit;
Quit (Self);
end;
// Create
//
constructor TEventSink.Create;
begin
FSinkIID := IApplicationEvents;
end;
// Connect
//
procedure TEventSink.Connect (pSource : IUnknown);
var
pcpc : IConnectionPointContainer;
begin
Assert (pSource <> NIL);
Disconnect;
try
OleCheck (pSource.QueryInterface (IConnectionPointContainer, pcpc));
OleCheck (pcpc.FindConnectionPoint (FSinkIID, FCP));
OleCheck (FCP.Advise (Self, FCookie));
FSource := pSource;
except
raise Exception.Create (Format ('Unable to connect %s.'#13'%s',
['Word', Exception (ExceptObject).Message]
));
end;
end;
// Disconnect
//
procedure TEventSink.Disconnect;
begin
if (FSource = NIL) then Exit;
try
OleCheck (FCP.Unadvise(FCookie));
FCP := NIL;
FSource := NIL;
except
pointer (FCP) := NIL;
pointer (FSource) := NIL;
end;
end;
// _AddRef
//
function TEventSink._AddRef: Integer;
begin
Result := 2;
end;
// _Release
//
function TEventSink._Release: Integer;
begin
Result := 1;
end;
end.
in main program add an object eventSink and a method for your Exit function, connect the object EventSink to the ole variant of the Word application and register the function for exit
unit Unit1;
interface
uses
Windows, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
ExtCtrls, ComObj, Variants, UEventsSink;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure ApplicationEventsQuit(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FEventSink : TEventSink;
FWordApp : OleVariant;
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
FEventSink := TEventSink.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FEventSink.Disconnect;
FEventSink.Free;
end;
procedure TForm1.ApplicationEventsQuit(Sender: TObject);
begin
FEventSink.Disconnect;
Memo1.Lines.Add ('Application.Quit');
FWordApp := unassigned;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
try
// instantiate Word
FWordApp := CreateOleObject('Word.Application.14');
// connect Application events
FEventSink.Connect(FWordApp);
FEventSink.Quit := ApplicationEventsQuit;
// show Word
FWordApp.Visible := TRUE;
except
ShowMessage ('Unable to establish connection with Word !');
FWordApp := unassigned;
end;
end;
end.
|
|
|
Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как «свернуть» программу в трей.
3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
… (продолжение следует) …
Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка — 60 дней. Последующие попытки бан.
Мат в разделе — бан на три месяца…
Корректное закрытие документа Word
, каким образом ?
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Работаю с документом Word через созданную форму. При нажатии кнопки — создаётся новый документ, в него вносятся данные и т.п. Если я этот документ закрываю, а потом еще раз нажимаю кнопку, то новый документ не генерится, а я получю «Сервер RPC не доступен». Видимо как-то нужно корректно программно завершать работу с созданным документом, но как ? новый документ я создаю как if(StrToInt(Copy(WordApplication1.Version,0,Pos(‘.’,WordApplication1.Version)-1))) |
Rouse_ |
|
Moderator Рейтинг (т): 320 |
Ты покажи как ты его закрываешь… |
s-mike |
|
M Используем тег [code] для добавления текста программы в пост! Устное предупреждение! Читаем правила! |
Sergeant /// |
|
да какбы просто прописываю вот … что-то еще надо ?
Form1.WordApplication1.Disconnect; |
Jureth |
|
Чему у WordApplication1 равны св-ва AutoQuit и ConnectKind? |
Bas |
|
Цитата Sergeant /// @ 28.02.05, 19:36 да какбы просто прописываю вот … что-то еще надо ? Закрыть сам документ. |
Sergeant /// |
|
Autoquit = true, a ConnectionKing = ckNewInstance. Какбы ошибка выскакивает еще если создание документа было прервано по какой-либо причини, да и вообще сама по себе +( |
Rouse_ |
|
Moderator Рейтинг (т): 320 |
Давай ка оформляй код в теги и ложи его сюда… а то по обрывочным фразам ничего не понять |
Sergeant /// |
|
а всё — проблема решена. ПРосто вот этот
Form1.WordApplication1.Disconnect; прописываю в самом конце функции создающий документ. Соответствтенно если при выполнении функции происходила ошибка, то приложение останавливалось и от сервера по ходу не отсоединялось. Ну и при попытке создать новый чего-то там не работало. Просто теперь в начале функции проверяю есть ли открытые серверы, если есть — закрываю, а так стартую новый. Всем спасибо за участие +) |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0389 ] [ 16 queries used ] [ Generated: 13.04.23, 22:37 GMT ]