Обе проблемы, о которых вы упомянули, а именно, как избежать диалогового окна «Преобразовать файл» и всплывающего запроса о сохранении данных, скопированных в буфер обмена, можно избежать, указав правильные значения в вызовах автоматизации Word.
1. Избегание диалогового окна «Преобразование файла»
Обновите строку кода, открывающую документ, до
WordDocument := WordApp.Documents.Open('D:\Corpus\Adyg\Hudmir.pdf', ConfirmConversions := False);
. Это приведет к открытию документа без вызова диалога подтверждения преобразования.
Предполагая, что это работает, вы сможете восстановить второй и третий аргументы, чтобы у вас было
WordDocument := WordApp.Documents.Open('D:\Corpus\Adyg\Hudmir.pdf', true, false, ConfirmConversions := False);
Обратите внимание, что синтаксис
WordApp.Documents.Open([...], ConfirmConversions := False)
был добавлен в то же время время (в D2) одновременно с OLE-автоматизацией через OleVariants, для поддержки необязательных аргументов, передаваемых вызовам автоматизации.
PS: с этим изменением вы можете обнаружить, что ваш вызов Sleep излишен. Я говорю «может», потому что мой тестовый код в первую очередь не нуждался в этом.
2. Избегание запроса на сохранение содержимого буфера обмена.
Это приглашение появляется, если вы пытаетесь закрыть Word с помощью автоматизации, когда скопировали большой объем данных в буфер обмена.
Чтобы избежать этого, просто замените
WordApp.Quit;
на
WordApp.Quit(SaveChanges := False);
Это должно быть все, что вам нужно. Тот факт, что это работает, немного нелогичен: поскольку вы сохранили данные из своего WordDocument, вы можете ожидать, что использование WordDocument - это способ очистки данных буфера обмена (см. Теперь лишнее обновление ниже). Однако, установив тестовое приложение с несколькими флажками, которые управляют значениями параметров для WordDocument.Close и WordApp.Close, и протестировав различные варианты их настроек, я установил, что только значение SaveChanges, переданное в WordApp.Quit, влияет это поведение и позволяет избежать диалогового окна (если бы оно было отображено в противном случае).
Остальная часть этого ответа может быть проигнорирована, но я оставил его, поскольку он может помочь будущим читателям с подобными проблемами. Я также добавил тег VBA в q, так как я нашел множество вопросов о том, как избежать запроса сохранения буфера обмена в вопросах VBA, но ни одно из них не содержало окончательного решения, которое бы работало с кодом здесь.
+++++++++++++++++++++++++++++++++++++++++
Обновление ОП сообщил, что приведенный выше код может привести к появлению запроса от Word, когда он закрывается, сообщая, что в буфере обмена имеется большой объем данных, и спросил, возможно ли автоматизировать ответ на запрос. Подсказка.
Google нашел несколько предложений о том, как избежать приглашения, но я обнаружил, что ни одно из них не работает надежно при работе с 17-мегабайтным PDF-файлом. Метод, показанный ниже, к которому я пришел экспериментально, действительно , кажется, работает надежно, но не так просто, как хотелось бы.
Причина, по которой возникает запрос, заключается в том, что Word очевидно, устанавливает внутренние указатели на содержимое буфера обмена, поэтому мне было интересно, сработает ли для текста Range меньший размер, а затем отбросить его перед закрытием документа. Я столкнулся с 2 проблемами:
вызов vRange.End: = 1 не имел никакого эффекта
попытка вызова vRange.Set_Text: = '' вызвало исключение, утверждая, что vRange не поддерживает метод Set_Text, несмотря на тот факт, что интерфейс Range в модуле импорта Word2000.Pas для MS Word явно поддерживает. Итак, приведенный ниже код выбирает объект Range, содержащийся в варианте vRange, и вызывает для него Set_Text. Это работает, но означает, что вам нужно добавить Word2000.Pas (или один из последних модулей импорта Word) в предложение Uses.
Обратите внимание, что я удалил вызов объекта GetActiveOle для избегать возникновения исключительной ситуации при ее сбое, что приводит к прерыванию отладки.
procedure TForm1.Button1Click(Sender: TObject);
var
Clipboard:TClipboard;
WordApp,
WordDocument: OleVariant;
vRange : OleVariant;
iRange : Range; // or WordRange for D10.3.1+
begin
try
WordApp := CreateOleObject('Word.Application') ;
WordApp.visible := true;
WordApp.DisplayAlerts := False;
try
WordDocument := WordApp.Documents.Open('D:\aaad7\aaaofficeauto\test.pdf', ConfirmConversions := False); //, true, false);
vRange := WordDocument.range;
Label1.Caption := IntToStr(vRange.Start) + ':' + IntToStr(vRange.End);
vRange.copy;
sleep(1000);//Otherwise it fails
RichEdit1.Clear;
RichEdit1.PasteFromClipboard;
// vRange.Set_Text(' '); // This provokes a "Method Set_Text not supported by automation object" exception
// SO ...
// Pick up the Range interface contained in the vRange variant
iRange := IDispatch(WordDocument.range) as Range;
// and call Set_Text on it to set the Range's text to a single space
iRange.Set_Text(' ');
// Clear the iRange interface
iRange := Nil;
finally
// beware that the following discards and changes to the .Pdf
// so if you want to save any changes, you should do it
// before calling iRange.Set_Text
WordDocument.close(False, False, False);
WordDocument := UnAssigned;
end;
finally
WordApp.Quit(False, False, False);
WordApp := Unassigned;
end;
end;
Протестировано с MS Word 2010 на Windows 10 64-bit /