2009-04-01 8 views
9

J'espère qu'un expert VB/VBA pourra m'aider. Considérez ce qui suit: L'utilisateur ouvre un document dans Word 2003 et dans la macro Normal.dot AutoOpen, nous examinons document en cours et si il a été ouvert en cliquant sur un lien sur une page Web et répond à certaines autres applications spécifiques critères, fermer le flux continu « copie » et ouvrez le document source (qui se trouve sur un lecteur partagé, nous pouvons supposer que l'utilisateur a accès à):Ouverture/activation de documents Word dans une macro VBA

Documents.Open origDoc 
Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges 
Documents(origDoc).Activate 

With ActiveDocument 
    ''# Do work 
End With 

Ma pensée était que je devais appeler Activate pour faire en sorte que l'original document était le ActiveDocument, mais j'obtiens une erreur 4160 'Nom de fichier incorrect' sur l'appel .Activate. Si je commente l'appel à .Activate, il apparaît que ActiveDocument est défini sur le document origDoc, même si d'autres documents sont déjà ouverts (je ne suis pas sûr de la manière dont la collection de documents est gérée, et comment Word détermine la suivante ActiveDocument si vous fermez le ActiveDocument en cours par programmation)

Ainsi, appeler .Open sur un document définit explicitement le document comme ActiveDocument? En outre, l'appel .Activate sur le document déjà actif provoque une erreur?

Je n'ai pas vraiment été en mesure de trouver beaucoup de documentation à ce sujet, alors merci d'avance pour toutes suggestions et idées!

+0

Vous avez probablement géré la copie en flux du document comme ActiveDocument dans votre code. Il vaudrait beaucoup mieux assigner cet objet document à une variable au début de votre code et utiliser votre variable dans le reste du code. Comme d'autres l'ont souligné, vous fermez probablement la mauvaise version du document dans la deuxième ligne de code. Aussi, il serait sage d'assigner l'objet document "original" à une variable quand vous l'ouvrez. – robartsd

Répondre

1

Vous avez une erreur ici:

Document(origDoc).Activate 

devrait être document s.

Oui, vous pouvez activer le document actif. Rien ne se passe alors.

Oui, le document ouvert devient actif. Si vous n'êtes pas sûr, utilisez Documents.Open(origDoc).Activate.

+0

Merci d'avoir repéré la faute de frappe, malheureusement, c'était seulement dans mon message, pas le code réel. Si vous êtes autorisé à activer le document ouvert, alors pourquoi ai-je une erreur 4160 sur l'appel .Activate? – echoesofspring

+0

Que contient exactement origDoc? – GSerg

1

Vous ne devriez pas utiliser l'objet ActiveDocument en premier lieu à moins que ce ne soit absolument nécessaire, car il est très peu fiable. L'approche privilégiée serait celle-ci:

Documents(ActiveDocument.FullName).Close SaveChanges:=wdDoNotSaveChanges 

Dim doc as Document 
Set doc = Documents.Open(origDoc)   
With doc 
    'Do work 
End With 
+2

Il me manque évidemment quelque chose ici. Vous dites de ne pas utiliser 'ActiveDocument', mais allez-y et utilisez-le dans votre exemple de code? – Sabuncu

-1

Prenez garde qu'il ya une variété de problèmes qui peuvent être rencontrés:

  1. si vous voulez rouvrir le document après l'avoir fermé une fois .. ..Word/Windows NE DOIT PAS 'libérer' le nom de fichier et vous obtenez un message 'fichier occupé', ou un message à propos de 'créant une copie temporaire'. pour faire face à ce problème, j'ai dû développer un système élaboré de création/sauvegarde et rangeant plusieurs versions de tous les autres documents que j'ouvre/manipule dans mes applications Word en raison de cette faille de conception dans Office Open/Close/Save méthodes.

  2. Utilisez la propriété ReadOnlyRecommended mis à False avec le .Open méthode

  3. se référant à l'objet de document (doc nommé, ci-dessus) peut provoquer erreurs graves si vous ne garantit pas que l'objet doc existe encore avant de l'essayer et de le manipuler. Rappelez-vous toujours, que Word est une plate-forme d'application «ouverte» .... et l'utilisateur peut faire des choses que vous n'avez pas compté sur ... dans la dernière milliseconde environ. Ce conseil est valable pour tout autre objet ou propriété que vous souhaitez manipuler dans Word.

  4. si vous manipulez la collection Documents (ou tout autre) sans assurant que le document ou un autre objet est toujours là et valide avant de supprimer ou de le déplacer dans la collection vous pouvez
    get « overflow de pile » les erreurs. Particulièrement si vous essayez et fermer/supprimer des objets dans une collection commençant à .item(1). Vous devez supprimer les éléments d'une collection de la dernière et n'oubliez pas que les idicies de collection et les pointeurs changent chaque fois que vous .add/.remove/.close des éléments d'eux.

4

La réponse simple est oui. En ouvrant le document avec votre code, vous en faites le document actif, que vous fermez ensuite dans la ligne suivante et que vous essayez d'activer dans le suivant, ce qui échoue parce que le document n'est plus ouvert. VBA en général semble fonctionner de cette façon. Il est important de faire attention avec ActiveDocument, car il n'est pas toujours évident de savoir quelles actions, en code ou ailleurs, vont rendre un document 'actif' (je n'ai aucune preuve, mais même une sauvegarde automatique pourrait le faire). En cas de doute, il vaut mieux faire référence à un document via la collection Documents, bien que cela puisse également provoquer des erreurs si le document n'est plus ouvert, et vous devrez peut-être recourir à itération dans la collection pour être sûr que le document est en fait, ouvert. Je rencontre beaucoup de choses avec Excel VBA, et Word VBA semble fonctionner de la même manière à cet égard.

En outre, VBA est floconneux sur la libération d'objets d'application. Si vous ne faites pas attention, vous finirez avec plusieurs processus WINWORD, visibles dans le gestionnaire de tâches, que vous les fermiez ou les quittiez dans votre code. Le code que j'ai trouvé pour contourner cela équivaut à simuler le processus de sélection de END PROCESS dans le gestionnaire de tâches. Cela fonctionne, mais il devrait y avoir une meilleure solution.

+0

VBA? Floconneux? Pourquoi je n'ai jamais entendu de telles accusations! – franklin

Questions connexes