Comment tester en VBA si un docmnt Word est deja ouvert

helpvb Messages postés 32 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 22 avril 2009 - 22 févr. 2007 à 18:46
helpvb Messages postés 32 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 22 avril 2009 - 23 févr. 2007 à 23:11
Bonjour
Je travaille en reseau et j ai tout simplement besoin de savoir depuis du code VBA (sous excel) si un document Word est deja ouvert par un autre utilisateur afin le cas echeant de lui envoyer un message bloquant
Merci d avance

10 réponses

jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
22 févr. 2007 à 21:16
Moi, je suis bête et bourrin ... chaussé de très gros sabots....
Je ne ferais alors pas dans la dentelle et irais ainsi  (en remplaçant ce que j'ai mis en rouge par ce qui est révêlateur de ton fichier... genre "toto.xls, oar exemple)

Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetActiveWindow Lib "user32" () As Long


Private Const GW_HWNDFIRST = 0 ' retourne le handle de la fenêtre au sommet de l'ordre z.
Private Const GW_HWNDLAST = 1  ' handle de la fenêtre au bas de l'ordre z.
Private Const GW_HWNDNEXT = 2  ' handle de la fenêtre suivante.
Private Const GW_HWNDPREV = 3  ' handle de la fenêtre précédente.


 


 


Private Sub Command1_Click()
  machaine = UCase("cui.reg")
  Dim currwnd, longueur, parent As Long
  Dim NomTache As String
  Dim lok As Integer
  Form1.List1.Clear
  currwnd = GetWindow(Screen.ActiveForm.hwnd, GW_HWNDFIRST)
  ' Nous recherchons maintenant les handles suivants et extrayons les noms des fenêtres.
  lok = 0
  While currwnd <> 0
    parent = GetParent(currwnd)
    longueur = GetWindowTextLength(currwnd)
    NomTache = Space$(longueur + 1)
    longueur = GetWindowText(currwnd, NomTache, longueur + 1)
    NomTache = Left$(NomTache, Len(NomTache) - 1)
    If InStr(UCase(NomTache), machaine) > 0 Then
       MsgBox "boom" & vbCrLf & "que oui, qu'il est ouvert !"
    End If
    If (longueur > 0) And (NomTache <> Form1.Caption) Then
        NomTache = UCase(NomTache)
        lok = lok + InStr(NomTache, "EXCEL")
        Form1.List1.AddItem NomTache
    End If
    currwnd = GetWindow(currwnd, GW_HWNDNEXT)
    DoEvents
  Wend
End Sub




 
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
22 févr. 2007 à 21:20
Excuse-moi :
J'ai laissé "trainer" du residus de mes essais :

OUAAALAAA  donc, corrigé et simplifié :

Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetActiveWindow Lib "user32" () As Long


Private Const GW_HWNDFIRST = 0 ' retourne le handle de la fenêtre au sommet de l'ordre z.
Private Const GW_HWNDLAST = 1  ' handle de la fenêtre au bas de l'ordre z.
Private Const GW_HWNDNEXT = 2  ' handle de la fenêtre suivante.
Private Const GW_HWNDPREV = 3  ' handle de la fenêtre précédente.


Private Sub Command1_Click()
  machaine = UCase("cui.reg")
  Dim currwnd, longueur, parent As Long
  Dim NomTache As String
  Dim lok As Integer
  Form1.List1.Clear
  currwnd = GetWindow(Screen.ActiveForm.hwnd, GW_HWNDFIRST)
  ' Nous recherchons maintenant les handles suivants et extrayons les noms des fenêtres.
  lok = 0
  While currwnd <> 0
    parent = GetParent(currwnd)
    longueur = GetWindowTextLength(currwnd)
    NomTache = Space$(longueur + 1)
    longueur = GetWindowText(currwnd, NomTache, longueur + 1)
    NomTache = Left$(NomTache, Len(NomTache) - 1)
    If InStr(UCase(NomTache), machaine) > 0 Then
       MsgBox "boom" & vbCrLf & "que oui, qu'il est ouvert !"
    End If
    currwnd = GetWindow(currwnd, GW_HWNDNEXT)
    DoEvents
  Wend
End Sub


 
0
helpvb Messages postés 32 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 22 avril 2009
23 févr. 2007 à 11:30
Bonjour

Je n ai rien compris a ton code :-(
Je cherche un moyen simple de tester tout simplement depuis mon code VBA sous excel si le document "toto.doc" est deja ouvert par un autre utilisateur, une instruction du genre:
    If Wrd.Documents("toto.xls").ReadOnly then 
         Msgbox ("Fichier deja ouvert ! Vous devez le fermer prealablement".)
         End
   End if

Merci d avance
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
23 févr. 2007 à 11:41
C'est pourtant simple !

1) Fais un petit projet avec mon code
2) ouvre ton document toto.doc depuis l'explorateur, par exemple
3) dans le code, remplace 
machaine = UCase("cui.reg")
par
 machaine = UCase("toto.doc")

Lance... et vois ce qui se passe

Ferme ensuite le document toto.doc et lance ===>>> et vois la différence ...

C'est pour moi très clair.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
helpvb Messages postés 32 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 22 avril 2009
23 févr. 2007 à 11:46
mais je suis en vba !
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
23 févr. 2007 à 11:48
Oui ?

Bon ! en VBA !


Et alors ?
0
helpvb Messages postés 32 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 22 avril 2009
23 févr. 2007 à 11:56
si ce n est pas abusé pourrais tu m integrer ton petit bout de code dans un document excel vierge car je n y arrive pas (ca ne marche pas)
J executerai ton xls
Merci d avance
PS: si ok peux te laisser mon email
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
23 févr. 2007 à 12:03
Désolé, mais je n'ai pas VBA.

Je sais pourtant que le code que je t'ai donné là fonctionne également sous VBA ouisqu'il ne fait appel qu'à des fonctions de l'Api de Windows.


 


Tu auras peut-être un problème avec cette ligne :


currwnd = GetWindow(Screen.ActiveForm.hwnd, GW_HWNDFIRST)

où il te faudra peut-être remplacer Screen.ActiveForm.hwnd par le hwnd de ta fenêtre.
Un VBAiste passant par là te  dira surement par quoi le remplacer

C'est le seul point sur lequel il y a un doute possible


 
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
23 févr. 2007 à 13:04
Bon...
Je vois que les VBAistes ne passent pas par là (t'aurais du poster dans le sous-forum VBA, aussi... tu aurais eu plus de chances ...)

Alors nouys allons essayer avec 2 essais :

le premier :

remplacer Screen.ActiveForm.hwnd par Application.hwnd

si celà marche, parfait !

sinon (deuxième essai) :

remplacer Screen.ActiveForm.hwnd par 0

fais-nous savoir, s'il te plait ...
0
helpvb Messages postés 32 Date d'inscription jeudi 7 septembre 2006 Statut Membre Dernière intervention 22 avril 2009
23 févr. 2007 à 23:11
j ai fait differemment car ta solution proposee me semble tres complexe et ne marche pas sous vba J ai donc trouve une solution en 3 ou 4 lignes de codes...
En gros je ferme systematiquement le document word avec un on error puis je tente un open via l instruction open file as input write en trappant l erreur  --> Si l erreur se declenche je sais que le document word est deja ouvert par un autre utilisateur Voili voilou Et ca marche
Merci de ton aide

Sinon dans la meme lignée ...(je ne sais plus si je vais oser, aller si j ose )
 je cherche un moyen simple (toujours depuis du code vba executé depuis Excel) de ne pas afficher la fenetre office qui est proposee a l utilisateur lorsque je tente d ouvrir un document word deja ouvert (fenetre ou l utilisateur doit repondre au radio bouton : Ouvrir en lecture seule, Etre notifie quand il se libere,...)
Merci
0
Rejoignez-nous