Excel et Word
Bonjour,
je cherche depuis plusieurs jours et rien, alors si qqun peut m'aider ...
Voilà, je cherche à faire en sorte qu'un bouton, ouvre un document présent dans un répertoire. Ce document est un fichier word.
Je voudrais laisser à l'utilisateur la possibilité de faire les changement désirés et qu'une fois qu'il à fini et qu'il veuille quitter son fichier word, pouvoir intercepter la fermeture, renommer le fichier d'une autre façon (en mettant la date du jour à la fin) et en historisant dans un dossier Archive, le fichier d'origine.
Je voudrait en gros garder le contrôle des Event word à partir de mes macro Excel.
Est-ce que quelqu'un peut m'aider?
Je vous en remercie par avance !
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonjour,
Il faut bien sûr ajouter la bibliothèque de référence Microsoft Word et ensuite
Etape 1 : Référencer et activer les événements Word dans "This Workbook" comme ceci
Dim Wd As Word.Application
Private WithEvents EvtsWord As Word.Application
Private WithEvents EvtsDoc As Word.Document
Private Sub Workbook_Open()
'création instance application Word
Set Wd = CreateObject("Word.Application")
'active les événements de l'application Word
Set EvtsWord = Wd.Application
End Sub
Private Sub EvtsWord_WindowActivate(ByVal Doc As Word.Document, ByVal Wn As Word.Window)
'active les événements du document actif de Word
Set EvtsDoc = Wd.ActiveDocument
End Sub
Private Sub EvtsDoc_Close()
Stop
'<votre macro>
End Sub
Etape 2: créer votre module comme suit, en rappelant l'instance de l'application Word créée à l'ouverture du classeur
Dim Wd As Word.Application
Sub ouverture_document()
'récupération application Word
Set Wd = GetObject(, "Word.Application")
'ouverture fichier Word
nom_fichier = "D:\Documents\test1.docx"
Wd.Documents.Open Filename:=nom_fichier
Wd.Visible = True 'affichage application
End Sub
Pour que cela fonctionne, une seule instance de l'application Word doit s'exécuter.
C'est une bonne piste merci.
par contre, je ne comprends pas pourquoi, qd j’exécute ta macro, ca fonctionne la première fois, mais pas la seconde, je tombe sur une erreur 429 : "un composant activex ne peut pas créer un objet"
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Cela signifie que tu fermes le premier document et que tu essaies d'en ouvrir un autre.
La fermeture du premier document implique l'arrêt de l'instance de l'application Word. tu ne peux pas ouvrir un second document sans redémarrer une instance Word.
Pour le moment, une instance Word n'est démarrée qu'à l'ouverture de ton classeur.
Merci bcp pour ton aide.
encore une question, j'ai voulu adapté ton code, en mettant le contenu de Thisdocument dans un module et en créant un module de class pour le reste.
mais visiblement, je perd le contrôle.
tu as une explication?
le modul de classe myWord :
Option Explicit
Dim wd As Word.Application
Public WithEvents EvtsWord As Word.Application
Public WithEvents EvtsDoc As Word.Document
Private Sub Class_Initialize()
'création instance application Word
On Error Resume Next
Set wd = GetObject(, "Word.application")
If Err.Number = 0 Then
Set wd = GetObject(, "Word.application")
Else
Set wd = CreateObject("Word.Application")
Set wd = GetObject(, "Word.Application")
End If
'active les événements de l'application Word
Set EvtsWord = wd.Application
'récupération application Word
'Set wd = GetObject(, "Word.Application")
End Sub
Private Sub EvtsDoc_Open()
MsgBox "Word ouvert"
End Sub
Private Sub EvtsWord_WindowActivate(ByVal Doc As Word.Document, ByVal Wn As Word.Window)
'active les événements du document actif de Word
Set EvtsDoc = wd.ActiveDocument
End Sub
Private Sub EvtsDoc_Close()
MsgBox "Word fermé"
'Stop
'<votre macro>
End Sub
le module remplaçant thisoducment:
Public wd As Word.Application
Sub test_ouverture_document()
Dim wdt As New MyWord
Dim nom_fichier As String
'récupération application Word
'Set wd = GetObject(, "Word.Application")
'ouverture fichier Word
nom_fichier = "C:\document.docx"
wdt.EvtsWord.Documents.Open fileName:=nom_fichier
wdt.EvtsWord.Visible = True 'affichage application
End Sub
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Je vais regarder et te fournir une réponse demain.
Merci c'est gentil.
En fait, si tu veux des détails sur mon idée de macro c'est:
- Faire un bouton qui :
- soit charge le document word (si c'est du word) s'il n'y a qu'un seul document dans le répertoire
- soit ouvre une box pour laisser l'utilisateur le choix du fichier à ouvrir s'il y en à plusieurs.
- si le fichier était déjà ouvert (sans passer par la macro), je désire que excel capture le moment de sa fermeture ou de sa sauvegarde.
- si le fichier n'est pas ouvert, qu'on l'ouvre avec word (si c'est un word) et qu'on détecte sa fermette ou son enregistrement
- si il y a plein de fichier word d'ouvert, je veux uniquement avoir le contrôle sur le fichier qui m’intéresse.
Voilà, l'idée étant bien-sur de tout faire dans mon outil excel, sans avoir besoin de créer des macros dans chacun de mes autres documents que je désire ouvrir (word ou excel)
D'avance merci
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonjour,
Avant d'examiner plus spécifiquement ta demande, correction de ton code ci-dessous
module de classe MyWord
Option Explicit
Public WithEvents EvtsWord As Word.Application
Public WithEvents EvtsDoc As Word.Document
Private Sub EvtsWord_DocumentOpen(ByVal Doc As Word.Document)
MsgBox "Document Word ouvert"
End Sub
Private Sub EvtsDoc_Close()
MsgBox "Document Word fermé"
End Sub
Macro de base
Dim wd As Word.Application
Dim wdt As New MyWord
Sub test_ouverture_document()
Dim nom_fichier As String
'création instance application Word
Set wd = CreateObject("Word.Application")
'active les événements de l'application Word
Set wdt.EvtsWord = wd.Application
'ouverture fichier Word
nom_fichier = "D:\document.docx"
wd.Documents.Open Filename:=nom_fichier
wd.Visible = True
'active les événements du document actif
Set wdt.EvtsDoc = wd.ActiveDocument
End Sub
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
voici un code qui devrait être conforme à ta demande
module de classe MyWord
Option Explicit
Public WithEvents EvtsWord As Word.Application
Public WithEvents EvtsDoc As Word.Document
Private Sub EvtsWord_DocumentOpen(ByVal Doc As Word.Document)
MsgBox "Document Word avant ouverture"
End Sub
Private Sub EvtsDoc_Close()
'désactive les événements du document actif
Set EvtsDoc = Nothing
MsgBox "Document Word avant fermeture"
End Sub
Private Sub EvtsWord_WindowActivate(ByVal Doc As Word.Document, ByVal Wn As Word.Window)
'active les événements du document actif de l'instance word correspondante
Set EvtsDoc = GetObject(Doc.Path & "\" & Doc.Name).Application.ActiveDocument
End Sub
module d'ouverture Document
Dim wd As Word.Application
Dim wdt As New MyWord
Sub ouvrir_doc(nom_doc)
Dim nom_fichier As String
'création ou récupération instance application Word
On Error Resume Next
Set wd = GetObject(, "Word.application")
If Err.Number <> 0 Then Set wd = CreateObject("Word.Application")
Err.Clear
'active les événements de l'application Word
Set wdt.EvtsWord = wd.Application
'ouverture fichier Word
wd.Documents.Open Filename:=nom_doc
wd.Visible = True
End Sub
Votre Macro
Sub votre_macro()
' ajouter référence Microsoft Scripting Runtime
Dim fso As New FileSystemObject
Dim dossier As Folder
Dim fichier As File
Dim fd As Object
Dim nom_dossier, ext_fichier As String
Dim selection As Boolean
'ouverture fichier Documents unique
nom_dossier = "C:\Docs"
Set dossier = fso.GetFolder(nom_dossier)
For Each fichier In dossier.Files
ext_fichier = fso.GetExtensionName(fichier.Path)
If ext_fichier = "docx" Then Exit For
Next
If ext_fichier = "docx" And dossier.Files.Count = 1 Then
Call ouvrir_doc(fichier.Path)
Exit Sub
End If
'affichage fichiers à sélectionner
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.InitialFileName = nom_dossier
.Filters.Add "Documents", "*.docx", 1
.Title = "Sélectionner fichier(s) Documents"
.AllowMultiSelect = True
.InitialView = msoFileDialogViewDetails
.ButtonName = "Sélection fichier(s) Documents"
.Show
End With
'ouverture fichiers sélectionnés
sélection = False
For Each fichier In fd.SelectedItems
sélection = True
Call ouvrir_doc(fichier)
Next
If Not sélection Then
MsgBox "Aucune sélection effectuée"
End If
End Sub
C'est pas mal du tout, mais pour une raison que j'ignore, les événements se déclenchent qu'à la première ouverture du fichier.
Essai d'ouvrir et fermer 2 fois de suite, la deuxième fois, aucune msgbox n’apparaît.
J'ai trouvé!
Il suffit de vider la variable, voir toute :
Private Sub EvtsDoc_Close()
'désactive les événements du document actif
Set EvtsDoc = Nothing
ThisWorkbook.Activate
MsgBox "Document Word avant fermeture"
End
End Sub
Bonjour,
j'ai encore besoin d'aide. La macro actuelle me permet de garder le contrôle sur un seul document à la fois.
Comment faire si je veux en ouvrir 5 ou 10 différents, et garder le contrôle sur chacun d'entre eux?
je pense qu'il faudrait que je modifie ici, afin d'avoir une liste qui puisse d'incrémenter automatiquement, mais je maîtrise mal les listes...
Private Sub EvtsWord_WindowActivate(ByVal Doc As Word.Document, ByVal Wn As Word.Window)
'active les événements du document actif de l'instance word correspondante
Set EvtsDoc = GetObject(Doc.Path & "\" & Doc.Name).Application.ActiveDocument
End Sub
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bravo, c'est bien ça, il faut effectivement réinitialiser la variable mais il faut le faire au départ sinon elle ne sera plus activée pour les documents suivants. Comme ceci
Dim wd As Word.Application
Dim wdt As New MyWord
Sub ouvrir_doc(nom_doc)
Dim nom_fichier As String
'initialise les événements de l'application Word
Set wdt.EvtsWord = Nothing
'création ou récupération instance application Word
On Error Resume Next
Set wd = GetObject(, "Word.application")
If Err.Number <> 0 Then Set wd = CreateObject("Word.Application")
Err.Clear
'active les événements de l'application Word
Set wdt.EvtsWord = wd.Application
'ouverture fichier Word
wd.Documents.Open Filename:=nom_doc
wd.Visible = True
End Sub
Par ailleurs, j'ai simplifié le module de classe MyWord car en fait, nul besoin des événements Document
Option Explicit
Public WithEvents EvtsWord As Word.Application
Private Sub EvtsWord_DocumentOpen(ByVal Doc As Word.Document)
MsgBox "Document Word avant ouverture"
End Sub
Private Sub EvtsWord_DocumentBeforeClose(ByVal Doc As Word.Document, Cancel As Boolean)
MsgBox "Document Word avant fermeture"
End Sub
Correction d'une erreur dans le module "Votre macro" au niveau de la variable relative aux éléments sélectionnés
**************** ajouter référence Microsoft Scripting Runtime *******************
Sub Votre_macro()
Dim fso As New FileSystemObject
Dim dossier As Folder
Dim fichier As File
Dim fd As Object
Dim nom_dossier, ext_fichier As String
Dim selection As Boolean
Dim élément As Variant
'ouverture fichier Documents unique
nom_dossier = "D:\Docs"
Set dossier = fso.GetFolder(nom_dossier)
For Each fichier In dossier.Files
ext_fichier = fso.GetExtensionName(fichier.Path)
If ext_fichier = "docx" Then Exit For
Next
If ext_fichier = "docx" And dossier.Files.Count = 1 Then
Call ouvrir_doc(fichier.Path)
Exit Sub
End If
'affichage fichiers à sélectionner
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.InitialFileName = nom_dossier
.Filters.Add "Documents", "*.docx", 1
.Title = "Sélectionner fichier(s) Documents"
.AllowMultiSelect = True
.InitialView = msoFileDialogViewDetails
.ButtonName = "Sélection fichier(s) Documents"
.Show
End With
'ouverture fichiers sélectionnés
sélection = False
For Each élément In fd.SelectedItems
sélection = True
Call ouvrir_doc(élément)
Next
If Not sélection Then
MsgBox "Aucune sélection effectuée"
End If
End Sub
Merci beaucoup pour ton aide.
j'avais en effet corrigé ta macro
J'ai encore besoin de toi. Par hasard, tu ne saurais pas comment a partir de ma macro sous exce, arriver à afficher une boite de dialogue dans le doc word.
En gros, je réussi maintenant à catcher la sauvegarde, je fais mes affaires, et je veux lui afficher une boite de dialogue "Sauvegarde effectué" dans le word.
Actuellement la boite de dialogue s'affiche dans Excel. et pour que l'utilisateur le voit, je dois mettre word en arrière plan... j'aurais préférer mettre excel en premier plan. si tu as une astuce pour ça aussi je suis preneur.
Option Explicit
Public WithEvents EvtsWord As Word.Application
Private Sub EvtsWord_DocumentBeforeSave(ByVal Doc As Word.Document, SaveAsUI As Boolean, Cancel As Boolean)
Doc.Words.Application.WindowState = wdWindowStateMinimize
Dim newName As String
Dim PartiARemplacer() As String
PartiARemplacer = Split(Doc.Name, "_")
newName = Left(Doc.FullName, (Len(Doc.FullName) - Len(PartiARemplacer(UBound(PartiARemplacer))))) & Format(Now, "YYYYMMDD-hhmm")
Doc.SaveAs2 Filename:=newName, FileFormat:=wdFormatDocumentDefault
MsgBox "Document sauvegardé sous le nom : " & Doc.Name
End Sub
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonjour,
j'ajouterai ces 2 instructions
MsgBox "Document sauvegardé sous le nom : " & Doc.Name
ActiveWindow.WindowState = xlNormal
Cancel = True
Le "cancel= true" enlève la boite de dialogue apparaissant en cas d'"enregistrer sous"
Le coté "cancel" ne fait rien chez moi, la fenêtre s'affiche qd meme si je fais enregistrer sous.
Sinon, ta solution est un bon palliatif, mais je préférerais afficher la popup dans word
- Messages
- 4'092
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Cancel = True fonctionne parfaitement chez moi et nous avons a priori la même version d'Excel.
Essaie de le placer en première instruction
Private Sub EvtsWord_DocumentBeforeSave(ByVal Doc As Word.Document, SaveAsUI As Boolean, Cancel As Boolean)
Cancel = True
Doc.Application.WindowState = wdWindowStateMinimize