«Вызов отклонен вызываемым пользователем» - это то, что вы всегда получаете, когда Word находится в интерактивном состоянии, то есть при отображении диалога.Это не ограничивается Word.Это также происходит с Excel, например, когда пользователь редактировал ячейку.И это не должно быть очевидным в пользовательском интерфейсе.Когда вы начинаете редактировать ячейку, перемещаете фокус в другое приложение и возвращаетесь в Excel, пользовательский интерфейс не дает подсказки, но он все еще находится в «интерактивном» режиме и будет отклонять вызовы автоматизации с помощью «Вызов отклонен вызываемым пользователем»ошибка.
Поэтому, в основном, когда вы автоматизируете Word в сочетании с взаимодействием с пользователем (а не только с Word в фоновом процессе), вы должны быть готовы к получению и обработке этих ошибок.
Edit Если вы хотите узнать, находится ли Excel или Word в интерактивном режиме, прежде чем вызывать любой другой метод COM: просто спросите COM-сервер, «Готов» ли он:
Result := _GetActiveOleObject('Excel.Application');
try
aSharedInstance := not VarIsClear(Result);
if aSharedInstance then
Version := Result.Version; // If this produces an exception, then use a dedicated instance.
// In case checking the version does not produce an exception, but Excel still isn't
// ready, we'll check that as well.
// By the way, for some unclear reason, partial evaluation does not work on .Ready,
// so we'll do it like this:
if aSharedInstance and (StrToIntDef(StringBefore('.', Version), 0) >= EXCEL_VERSION_2002) then
aSharedInstance := Result.Ready;
except
aSharedInstance := False;
end;
if not aSharedInstance then
Result := CreateOleObject('Excel.Application');
Обновление Очевидно, что Word не имеет свойства "Готово" (кто бы ни сказал, что Microsoft была последовательной?).В этом случае вам нужно самостоятельно определить его готовность, вызвав простое (и быстрое) свойство перед фактическим вызовом и предположив, что, когда это вызывает исключение, Word не готов.В приведенном выше примере версия извлекается до свойства Ready.Если это вызывает исключение, мы просто предполагаем, что приложение (в данном случае Excel) не готово и действуем соответствующим образом.
Что-то вроде:
while Tries <= MaxTries do
try
Version := Word.Version;
Tries := MaxTries + 1; // Indicate success
Word.TheCallYouReallyWantToDo;
except
Inc(Tries);
sleep(0);
end;
Примечание Word.Version не выдает исключение, когда диалоговое окно открыто, поэтому бесполезно выяснять, готов ли Word.:( Вам придется экспериментировать, чтобы найти тот, который делает.