Le message "Call was rejected by callee" (l'appel a été rejeté par l'appelant) est ce que vous obtenez toujours lorsque Word est en mode interactif, c'est-à-dire lorsqu'il affiche un dialogue. Ce phénomène n'est pas limité à Word. Cela se produit également avec Excel, par exemple lorsque l'utilisateur modifie une cellule. Et il n'est pas nécessaire que cela soit évident dans l'interface utilisateur. Lorsque vous commencez à éditer une cellule, que vous déplacez le focus vers une autre application et que vous revenez à Excel, l'interface utilisateur ne vous donne aucun indice, mais elle est toujours en mode "interactif" et rejettera les appels d'automatisation avec l'erreur "Call was rejected by callee" (l'appel a été rejeté par le destinataire).
Ainsi, lorsque vous automatisez Word en conjonction avec l'interaction de l'utilisateur (et pas seulement avec Word dans un processus d'arrière-plan), vous devez être prêt à recevoir et à gérer ces erreurs.
Éditer Si vous voulez savoir si Excel ou Word est en mode interactif avant d'appeler une autre méthode COM, demandez simplement au serveur COM s'il est "prêt" :
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');
Mise à jour Apparemment, Word n'a pas de propriété "Ready" (qui a dit que Microsoft était cohérent ?). Dans ce cas, vous devez déterminer vous-même son état de préparation en appelant une propriété simple (et rapide) avant l'appel proprement dit, et en supposant que si cette propriété lève une exception, c'est que Word n'est pas prêt. Dans l'exemple ci-dessus, la version est récupérée avant la propriété Ready. Si cette dernière lève une exception, nous supposons que l'application (Excel dans ce cas) n'est pas prête et nous procédons en conséquence.
Quelque chose comme ça :
while Tries <= MaxTries do
try
Version := Word.Version;
Tries := MaxTries + 1; // Indicate success
Word.TheCallYouReallyWantToDo;
except
Inc(Tries);
sleep(0);
end;
Note Word.Version fait n lancent une exception lorsqu'une boîte de dialogue est ouverte, ce qui ne permet pas de savoir si Word est prêt :( Vous devrez expérimenter pour en trouver un qui le fasse.