C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Работа с Word через OLE  (Прочитано 15722 раз)
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« : 16 Октябрь 2009, 08:54:17 »

Следующая функция вызывает ошибку "Операция недоступна" на строке MSWord = Variant::GetActiveObject("Word.Application");
В чем дело?

Код:
TStringList* __fastcall TForm1::GetWordStatsPg (TStringList* filenames)
{
// Initialize vars
Variant MSWord  = Null;
Variant MWODocs = Null;
Variant MWODoc  = Null;
Variant DocProps = Null;
Variant Pages = Null;
//Variant Chars = Null;
UnicodeString pg = "*";
//UnicodeString ch = "*";

ShowMessage("Инициализированы переменные.");

TStringList* OutList = new TStringList;

// Start MS Word
try         {
MSWord = Variant::GetActiveObject("Word.Application");
}
catch (...) {
ShowMessage("Word не открыт.");
MSWord = Null;
}

if (MSWord.IsNull())
{
ShowMessage("Word не открыт.");
try { MSWord = Variant::CreateObject("Word.Application");    }
catch (Exception &xcp)
{
ShowMessage("Не могу запустить приложение MSWord\r\n" + xcp.Message);
MSWord = Null;
delete OutList;
return NULL;
}
catch (...)
{
MSWord = Null;
delete OutList;
return NULL;
}
}

ShowMessage("WORD STARTED!");

// Open document invisible
MWODocs = MSWord.OlePropertyGet("Documents");

// ------------ MAIN LOOP
for (int i = 0; i < filenames->Count; i++) {
// ------------
pg = "*";

try {
MWODoc = MWODocs.OleFunction("Open", filenames->Strings[i].c_str(), false, true, false);
}
catch (...) {
MSWord.OlePropertySet("Visible", true);
MWODoc = Null;
}

// If failed, try to create new Word server...
if (MWODoc.IsNull())
{
try
{      MSWord = Variant::CreateObject  ("Word.Application");
MSWord.OlePropertySet           ("Visible", false);
MWODocs = MSWord.OlePropertyGet ("Documents");
MWODoc  = MWODocs.OleFunction   ("Open", filenames->Strings[i].c_str(), false, true, false);
}
catch (Exception &xcp)
{      ShowMessage     (UnicodeString("") +
"Не могу запустить приложение MSWord.\n" +
"Если оно у Вас уже запущено закройте его и повторите попытку."
);
MSWord = Null;
delete OutList;
return NULL;
}
}

ShowMessage("DOC OPENED!");

// Still OK? Then go on, man!
DocProps = MWODoc.OlePropertyGet("BuiltinDocumentProperties");

if (DocProps.IsNull())
{
ShowMessage ("Не могу получить свойство BuiltinDocumentProperties");
delete OutList;
return NULL;
}

ShowMessage("DOC PROPS GOT!");

Pages = DocProps.OlePropertyGet("wdPropertyPages");
if (!Pages.IsNull())
pg = UnicodeString( (int)Pages );
else {
ShowMessage ("Не могу получить свойство wdPropertyPages");
delete OutList;
return NULL;
}

ShowMessage("PAGES PROPS GOT!");

/*
Chars = DocProps.OlePropertyGet("wdPropertyCharsWSpaces");
if (!Chars.IsNull())
ch = UnicodeString( (int)Chars );
else {
ShowMessage ("Не могу получить свойство wdPropertyCharsWSpaces");
delete OutList;
return NULL;
}
*/

// Still alive? Go on!
OutList->Add(pg);
//OutList->Add(ch);

Pages = Null;
//Chars = Null;
DocProps = Null;
MWODocs.OleProcedure("Close", filenames->Strings[i].c_str());

MWODoc  = Null;

ShowMessage("ALL VARS FREED!");
} // ------------ MAIN LOOP

MWODocs = Null;
MSWord.OleProcedure("Quit");
MSWord  = Null;

ShowMessage("QUIT WORD!");

return OutList;
}
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #1 : 16 Октябрь 2009, 09:04:23 »

То же самое с Excel: 

Variant App;
App = Variant::CreateObject("Excel.Application");

вызывает ошибку. А вот если Excel уже открыт, то все нормально, все остальные функции вызываются без проблем.
Записан
oxotnik
Глобальный модератор


Сказали спасибо: +100/-15
Offline

Сообщений: 2425


« Ответ #2 : 16 Октябрь 2009, 09:46:25 »

CreateOleObject не пробовал?
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #3 : 16 Октябрь 2009, 11:23:34 »

Спасибо, получилось!
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #4 : 16 Октябрь 2009, 12:06:49 »

Код
MSWord.OlePropertyGet("Documents").OleProcedure("Open", filenames->Strings[i].c_str(), false, true, false);
 

где filenames = TStringList*

>>> Access violation

Что не так?
Записан
oxotnik
Глобальный модератор


Сказали спасибо: +100/-15
Offline

Сообщений: 2425


« Ответ #5 : 16 Октябрь 2009, 12:25:04 »

попробуй
Код
WideString(filenames->Strings[i].c_str())
Записан
Tantos
А ты воспользовался поиском перед тем, как спросить?!
Давний друг


Сказали спасибо: +350/-28
Offline

Сообщений: 2181


« Ответ #6 : 16 Октябрь 2009, 14:38:15 »

точнее будет так:
Код
WideString(filenames->Strings[i])
 
Записан
S0mbre
Глобальный модератор


Сказали спасибо: +1113/-22
Offline

Сообщений: 2132

S0mbre


« Ответ #7 : 19 Октябрь 2009, 09:22:02 »

Спасибо! Но даже не в этом проблема... Уже не знаю, где копать. То приложение ( Word ) не запускается, то ошибка "несовпадение типов" (ошибка интерфейса OLE)...

Прилагаю проект. Проблемная функция - TStringList* __fastcall TForm1::GetWordStatsPg (TStringList* filenames); В GUI сначала предлагается выбрать директорию и нажать "Find files" для отображения списка файлов MS Word. Затем кнопка "Get Stats" должна вернуть свойства для каждого документа. Эта кнопка как раз запускает метод GetWordStatsPg.

Буду признателен, если кто-нибудь мог бы подсказать, где ошибка...

ПРОЕКТ
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #8 : 17 Февраль 2010, 14:07:10 »

Следующая функция вызывает ошибку "Операция недоступна" на строке MSWord = Variant::GetActiveObject("Word.Application");
В чем дело?

Код:
TStringList* __fastcall TForm1::GetWordStatsPg (TStringList* filenames)
{
// Initialize vars
Variant MSWord  = Null;
Variant MWODocs = Null;
Variant MWODoc  = Null;
Variant DocProps = Null;
Variant Pages = Null;
//Variant Chars = Null;
UnicodeString pg = "*";
//UnicodeString ch = "*";

ShowMessage("Инициализированы переменные.");

TStringList* OutList = new TStringList;

// Start MS Word
try         {
MSWord = Variant::GetActiveObject("Word.Application");
}
catch (...) {
ShowMessage("Word не открыт.");
MSWord = Null;
}

if (MSWord.IsNull())
{
ShowMessage("Word не открыт.");
try { MSWord = Variant::CreateObject("Word.Application");    }
catch (Exception &xcp)
{
ShowMessage("Не могу запустить приложение MSWord\r\n" + xcp.Message);
MSWord = Null;
delete OutList;
return NULL;
}
catch (...)
{
MSWord = Null;
delete OutList;
return NULL;
}
}

ShowMessage("WORD STARTED!");

// Open document invisible
MWODocs = MSWord.OlePropertyGet("Documents");

// ------------ MAIN LOOP
for (int i = 0; i < filenames->Count; i++) {
// ------------
pg = "*";

try {
MWODoc = MWODocs.OleFunction("Open", filenames->Strings[i].c_str(), false, true, false);
}
catch (...) {
MSWord.OlePropertySet("Visible", true);
MWODoc = Null;
}

// If failed, try to create new Word server...
if (MWODoc.IsNull())
{
try
{      MSWord = Variant::CreateObject  ("Word.Application");
MSWord.OlePropertySet           ("Visible", false);
MWODocs = MSWord.OlePropertyGet ("Documents");
MWODoc  = MWODocs.OleFunction   ("Open", filenames->Strings[i].c_str(), false, true, false);
}
catch (Exception &xcp)
{      ShowMessage     (UnicodeString("") +
"Не могу запустить приложение MSWord.\n" +
"Если оно у Вас уже запущено закройте его и повторите попытку."
);
MSWord = Null;
delete OutList;
return NULL;
}
}

ShowMessage("DOC OPENED!");

// Still OK? Then go on, man!
DocProps = MWODoc.OlePropertyGet("BuiltinDocumentProperties");

if (DocProps.IsNull())
{
ShowMessage ("Не могу получить свойство BuiltinDocumentProperties");
delete OutList;
return NULL;
}

ShowMessage("DOC PROPS GOT!");

Pages = DocProps.OlePropertyGet("wdPropertyPages");
if (!Pages.IsNull())
pg = UnicodeString( (int)Pages );
else {
ShowMessage ("Не могу получить свойство wdPropertyPages");
delete OutList;
return NULL;
}

ShowMessage("PAGES PROPS GOT!");

/*
Chars = DocProps.OlePropertyGet("wdPropertyCharsWSpaces");
if (!Chars.IsNull())
ch = UnicodeString( (int)Chars );
else {
ShowMessage ("Не могу получить свойство wdPropertyCharsWSpaces");
delete OutList;
return NULL;
}
*/

// Still alive? Go on!
OutList->Add(pg);
//OutList->Add(ch);

Pages = Null;
//Chars = Null;
DocProps = Null;
MWODocs.OleProcedure("Close", filenames->Strings[i].c_str());

MWODoc  = Null;

ShowMessage("ALL VARS FREED!");
} // ------------ MAIN LOOP

MWODocs = Null;
MSWord.OleProcedure("Quit");
MSWord  = Null;

ShowMessage("QUIT WORD!");

return OutList;
}

в месте:
Код:
DocProps = MWODoc.OlePropertyGet("BuiltinDocumentProperties");
выдает ошибку Could not convert variant of type (Boolean) into type (Dispatch)
В чем может быть проблема.
Так же не признает тип данных UnicodeString
Записан
Ex_Soft
Участник


Сказали спасибо: +12/-10
Offline

Сообщений: 74


« Ответ #9 : 17 Февраль 2010, 14:29:14 »

У меня это - работает без проблем
Записан
GIZMO
Давний друг


Сказали спасибо: +3/-1
Offline

Сообщений: 15


« Ответ #10 : 17 Февраль 2010, 22:18:35 »

Следующая функция вызывает ошибку "Операция недоступна" на строке MSWord = Variant::GetActiveObject("Word.Application");
В чем дело?
Запрашиваемого компонента нет в Running Objects Table.
Так установлен СОМ-сервер(Word).
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #11 : 18 Февраль 2010, 11:31:48 »

А можно ли закрыть документ Word без диалога сохранения ? Или же сохранить без диалога, а потом закрыть ?

Пытался так:

MWODocs.OleProcedure("SaveAs", FileName.c_str());

выдает ошибку

И так:
MWODocs.OleProcedure("Save", FileName.c_str());

тоже самое

А так же так:

MSWord.OleProcedure("Quit");

ошибка - вызов был отклонен

Может кто сможет помочь)

« Последнее редактирование: 18 Февраль 2010, 12:18:21 от 2rik » Записан
Garin
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 134


« Ответ #12 : 18 Февраль 2010, 12:11:17 »

Цитировать
А можно ли закрыть документ Word без диалога сохранения ?
Можно. Например
Код:
wVarDoc=wVarDocs.OleFunction("Item",1);
wVarDoc.OleProcedure("SaveAs",CurDir.c_str());
wVarApp.OleProcedure("Quit");
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #13 : 18 Февраль 2010, 12:26:58 »

Цитировать
А можно ли закрыть документ Word без диалога сохранения ?
Можно. Например
Код:
wVarDoc=wVarDocs.OleFunction("Item",1);
wVarDoc.OleProcedure("SaveAs",CurDir.c_str());
wVarApp.OleProcedure("Quit");

Оооо , сенк ))) Заработало )))
Я так понимаю, дело в

wVarDoc=wVarDocs.OleFunction("Item",1);

?)


Вот только в конце не хочет выполнять
wVarApp.OleProcedure("Quit");
« Последнее редактирование: 18 Февраль 2010, 12:36:19 от 2rik » Записан
Garin
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 134


« Ответ #14 : 18 Февраль 2010, 12:37:49 »

Да, правильно понимаешь...Определяешь какой документ сохранять. Смотри тут http://wladm.narod.ru/Borland/word.html всё хорошо написано
Записан
Garin
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 134


« Ответ #15 : 18 Февраль 2010, 12:43:16 »

Что значит не хочет выполнять??? Какая ошибка?
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #16 : 18 Февраль 2010, 13:08:15 »

Что значит не хочет выполнять??? Какая ошибка?

EOleSysError 'ошибка'.

Но уже все ок. Видимо, пока тестил - насоздавал серверов Word. Перезагрузил тачку - все работает.

Спасибо.
Записан
Ex_Soft
Участник


Сказали спасибо: +12/-10
Offline

Сообщений: 74


« Ответ #17 : 18 Февраль 2010, 13:44:40 »

P.S.
А можно ли закрыть документ Word без диалога сохранения ?
Код
MSWord.OlePropertySet("DisplayAlerts",0 /*wdAlertsNone */);
 
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #18 : 18 Февраль 2010, 14:18:37 »

А можно ли просто закрыть текущий документ, не закрывая самого сервера Word
Просто, мне нужно открыть массив файлов и  просчитать количество листов в каждом. Я так подозреваю, что если файлов будет 3 тысячи - то не хватит вирт. памяти.

Открываю файл, подсчитаваю, закрываю - и новый цикл.

Код:
MWODoc  = MWODocs.OleFunction   ("Open", FileName.c_str(), false, true, false);
Pages=MWODoc.OlePropertyGet("BuiltInDocumentProperties").OlePropertyGet("Item",wdPropertyPages).OlePropertyGet("Value");
wVarDoc=MWODocs.OleFunction("Item",1);
wVarDoc.OleProcedure("SaveAs",sr.Name.c_str());
wVarDoc.OleProcedure("Close", sr.Name.c_str());

и на месте wVarDoc.OleProcedure("Close", sr.Name.c_str()); слетает, говоря
EOleSysError with message 'Ошибка'

Записан
Ex_Soft
Участник


Сказали спасибо: +12/-10
Offline

Сообщений: 74


« Ответ #19 : 18 Февраль 2010, 14:41:50 »

Код:
MWODoc  = MWODocs.OleFunction   ("Open", FileName.c_str(), false, true, false);
Pages=MWODoc.OlePropertyGet("BuiltInDocumentProperties").OlePropertyGet("Item",wdPropertyPages).OlePropertyGet("Value");
wVarDoc=MWODocs.OleFunction("Item",1);
wVarDoc.OleProcedure("SaveAs",sr.Name.c_str());
wVarDoc.OleProcedure("Close", sr.Name.c_str());

1. Зачем wVarDoc? У Вас же ЭстЪ MWODoc. Работайте с ним.

2.
Код:
>>>wVarDoc.OleProcedure("SaveAs",sr.Name.c_str());<<<
Зачем? Вы что-то изменили в содержимом?

3.
Код:
wVarDoc.OleProcedure("Close", >>>sr.Name.c_str()<<<);
Цитата: C:\Program Files\Microsoft Office\Office\VBAWRD8.HLP
Close Method

Syntax 1: Closes the specified document or documents.
Syntax 2: Closes the specified window.
Syntax 3: Closes the specified pane or task.

Syntax 1
expression.Close(SaveChanges, OriginalFormat, RouteDocument)

Syntax 2
expression.Close(SaveChanges, RouteDocument)

Syntax 3
expression.Close

4. тынць
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #20 : 18 Февраль 2010, 15:29:39 »

1. Зачем wVarDoc? У Вас же ЭстЪ MWODoc. Работайте с ним.
Даже если работать с MWODoc - таже ошибка.

2.
Код:
>>>wVarDoc.OleProcedure("SaveAs",sr.Name.c_str());<<<
Зачем? Вы что-то изменили в содержимом?

Я, просто, создал еще одну переменную, идентичную MWODoc. Чтобы не путаться )
3.
Код:
wVarDoc.OleProcedure("Close", >>>sr.Name.c_str()<<<);
Цитата: C:\Program Files\Microsoft Office\Office\VBAWRD8.HLP
Close Method

Syntax 1: Closes the specified document or documents.
Syntax 2: Closes the specified window.
Syntax 3: Closes the specified pane or task.

Syntax 1
expression.Close(SaveChanges, OriginalFormat, RouteDocument)

Syntax 2
expression.Close(SaveChanges, RouteDocument)

Syntax 3
expression.Close

4. тынць


В макросе записывает - ActiveWindow.Close

А когда делаю так:

MWODoc  = MWODocs.OleFunction   ("Open", FileName.c_str(), false, true, false);
MWODoc.OlePropertyGet("ActiveWindow").OleFunction   ("Close");

Снова ошибка EOleSysError 'ошибка' ((
Записан
Garin
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 134


« Ответ #21 : 18 Февраль 2010, 16:19:14 »

Я не знаю кончно, но...ты когда случаеся ошибка из диспетчера не вырубаешь WORD?
Может у тебя просто путаница возникает в созданных документах?
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #22 : 18 Февраль 2010, 16:43:22 »

Я не знаю кончно, но...ты когда случаеся ошибка из диспетчера не вырубаешь WORD?
Может у тебя просто путаница возникает в созданных документах?

 Word вырубаю 
Путаницы не возникает, т.к. проверяю - все отлично ) Никаких путаниц )
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #23 : 18 Февраль 2010, 18:00:52 »

Решил так
MSWord.OlePropertyGet("ActiveWindow").OleProcedure("Close"); при "Visible"= true
Но при
 MSWord.OlePropertySet("Visible", false); вылазит ошибка - сбой при удаленном вызове процедуры.

А хотелось бы, чтобы окно ворда было невидимым ...
Записан
Ex_Soft
Участник


Сказали спасибо: +12/-10
Offline

Сообщений: 74


« Ответ #24 : 18 Февраль 2010, 23:05:20 »

Код
Document=Documents.OleFunction("Open", FileName.c_str(), false, true, false);
Pages=Document.OlePropertyGet("BuiltInDocumentProperties").OlePropertyGet("Item",wdPropertyPages).OlePropertyGet("Value");
Document.OleFunction("Close");
 
Записан
2rik
Участник


Сказали спасибо: +0/-0
Offline

Сообщений: 24


« Ответ #25 : 19 Февраль 2010, 11:31:13 »

Код
Document=Documents.OleFunction("Open", FileName.c_str(), false, true, false);
Pages=Document.OlePropertyGet("BuiltInDocumentProperties").OlePropertyGet("Item",wdPropertyPages).OlePropertyGet("Value");
Document.OleFunction("Close");
 

Пасиб) Так и сделал вчера) Работает )
А по поводу неверного определения числа страниц - кто нить знает, в чем может быть проблема ? )
https://cbuilder.ru/index.php/topic,4925.new.html#new
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.133 секунд. Запросов: 20.