IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Activer un fichier via son handle et le sortir du mode protégé [XL-2010]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur étude
    Inscrit en
    Novembre 2016
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur étude

    Informations forums :
    Inscription : Novembre 2016
    Messages : 50
    Par défaut Activer un fichier via son handle et le sortir du mode protégé
    Bonjour,

    pourriez-vous m'aider, svp?
    A partir d'un classeur Excel, je télécharge un autre classeur Excel situé sur l'intranet de notre groupe.
    Je souhaiterais simplement copier-coller l'unique onglet de ce classeur téléchargé dans le classeur de départ.

    Mon problème se situe au niveau du mode protégé... quand on utilise IE, le classeur s'ouvre sans que le mode protégé soit activé; par contre, en utilisant Firefox (plus rapide, plus fiable), le classeur s'ouvre avec le mode protégé activé, ce qui ne permet pas de récupérer directement l'onglet en question.

    J'ai donc pensé basculer sur ce classeur téléchargé à partir de son handle puis tenter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ActiveWorkbook.Unprotect
    mais ça ne fonctionne pas... En effet, même si le classeur vient bien au premier plan, pour Excel, Activeworkbook est à Nothing...

    Quelqu'un aurait-il une petite idée, svp?

    Voici quelques lignes de code à partir de trouvailles faites sur Internet

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    Option Explicit
     
    Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
    Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
    Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
     
    Public instance
    Public Const GW_HWNDNEXT = 2
     
    Sub macro()
     
    instance = Null
     
    'je passe les lignes qui permettent de lancer le téléchargement à partir de Firefox
     
    If Not WaitFichier(60) Then
        'fichier chargé en moins de 60s
        SetForegroundWindow instance 'je passe le fichier au premier plan
        ActiveWorkbook.Unprotect 'je tente de supprimer le mode protégé... mais Excel ne reconnait pas ActiveWorkbook
     
        Dim Wb As Excel.Workbook
        Dim Appli As Excel.Application
     
        On Error Resume Next
     
        Set Appli = GetObject(, "Excel.Application")
     
        For Each Wb In Appli.Workbooks
            If Left(Wb.Name, Len("nomdufichier")) = "nomdufichier" Then 'permet d'éviter les numéros d'instances du type "nomdufichier (2)", etc.
                '... et il ne sait donc pas trouver le fichier quand il est en mode protégé...
            End If
        Next Wb
    End If
     
    End Sub
     
    Public Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean
    'permet de trouver la fenêtre désirée
        Dim lhWndP As Long
        Dim sStr As String
        GetHandleFromPartialCaption = False
        lhWndP = FindWindow(vbNullString, vbNullString)
        Do While lhWndP <> 0
            sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
            GetWindowText lhWndP, sStr, Len(sStr)
            sStr = Left$(sStr, Len(sStr) - 1)
            If InStr(1, sStr, sCaption) > 0 Then
                GetHandleFromPartialCaption = True
                lWnd = lhWndP
                Exit Do
            End If
            lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
        Loop
     
    End Function
     
     
    Public Function WaitFichier(pTimeOut As Long) As Boolean
    ' Attend que le fichier soit chargé
    ' pTimeOut est un time out en secondes (WaitFichier vaut True si Timeout)
    Dim lhWndP As Long
    Dim lTimer As Double
    lTimer = Timer
    Do
       DoEvents
       If GetHandleFromPartialCaption(lhWndP, "nomdufichier") = True Then instance = lhWndP: Exit Do 'on attribue la valeur du handle à la variable instance
       If pTimeOut > 0 And Timer - lTimer > pTimeOut Then
           WaitFichier = True
           Exit Do
       End If
    Loop
    End Function
    Merci par avance pour l'aide.

    Yohann

  2. #2
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 84
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Bonjour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ActiveWorkbook.Unprotect 'je tente de supprimer le mode protégé... mais Excel ne reconnait pas ActiveWorkbook
    quel "activeworkbook" ? Un fichier téléchargé n'est pris en compte dans la colloection WorkBooks qu'à partir du moment où il est OUVERT.
    Où, quand et comment l'as-tu donc ouvert ? On le le voit pas dans ton code.

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur étude
    Inscrit en
    Novembre 2016
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur étude

    Informations forums :
    Inscription : Novembre 2016
    Messages : 50
    Par défaut
    Bonjour,

    c'est bien ce que je dis dans mon post:

    - j'ai squizzé les lignes gérant le téléchargement et l'ouverture du fichier (voir le commentaire ligne 16)
    - bien qu'il est ouvert, il n'est pas pris en compte dans la collection WorkBooks parce qu'il est en mode protégé - ce n'est qu'à partir du moment où le classeur n'est plus en mode protégé qu'il est pris en compte dans la collection

    Voici la manière dont je gère le téléchargement et l'ouverture (en gras)*:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    Option Explicit
    
    Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
    Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
    Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
    
    Public instance
    Public Const GW_HWNDNEXT = 2
    
    Sub macro()
    
    Dim manavig
    manavig = Shell("C:\Program Files (x86)\Mozilla Firefox\firefox.exe https://chemin/nomdufichier.xls")
    
    instance = Null
    
    If Not WaitConnexion(5) Then
        'apparition du pop-up d'identification en moins de 5s
        'gestion du pop-up grâce à des SendKeys (pour entrée login et mot de passe)
    End If
    
    If Not WaitFichier(5) Then
        'ouverture du pop-up demandant si on ouvre ou si on enregistre le fichier (on choisit d'ouvrir) le fichier en moins de 5s
        'gestion du pop-up grâce à des SendKeys (pour seulement simuler la touche Entrée de manière à ouvrir le fichier)
    Else
        MsgBox "Le site ne s'est pas chargé suffisamment rapidement!", vbOKOnly + vbExclamation
        Exit Sub
    End If
    
    If Not WaitFichier(60) Then
        'fichier chargé en moins de 60s
        SetForegroundWindow instance 'je passe le fichier au premier plan
        ActiveWorkbook.Unprotect 'je tente de supprimer le mode protégé... mais Excel ne reconnait pas ActiveWorkbook
    
        Dim Wb As Excel.Workbook
        Dim Appli As Excel.Application
       
        On Error Resume Next
       
        Set Appli = GetObject(, "Excel.Application")
       
        For Each Wb In Appli.Workbooks
            If Left(Wb.Name, Len("nomdufichier")) = "nomdufichier" Then 'permet d'éviter les numéros d'instances du type "nomdufichier (2)", etc.
                '... et il ne sait donc pas trouver le fichier quand il est en mode protégé...
            End If
        Next Wb
    End If
    
    End Sub
    
    Public Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As Boolean
    'permet de trouver la fenêtre désirée
        Dim lhWndP As Long
        Dim sStr As String
        GetHandleFromPartialCaption = False
        lhWndP = FindWindow(vbNullString, vbNullString)
        Do While lhWndP <> 0
            sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
            GetWindowText lhWndP, sStr, Len(sStr)
            sStr = Left$(sStr, Len(sStr) - 1)
            If InStr(1, sStr, sCaption) > 0 Then
                GetHandleFromPartialCaption = True
                lWnd = lhWndP
                Exit Do
            End If
            lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
        Loop
        
    End Function
    
    Public Function WaitConnexion(pTimeOut As Long) As Boolean
    ' Attend que le pop-up d'identification soit chargé
    ' pTimeOut est un time out en secondes (WaitFichier vaut True si Timeout)
    Dim lhWndP As Long
    Dim lTimer As Double
    lTimer = Timer
    Do
        DoEvents
       If GetHandleFromPartialCaption(lhWndP, "Authentification requise") = True Then Exit Do
       If pTimeOut > 0 And Timer - lTimer > pTimeOut Then
           WaitConnexion = True
           Exit Do
       End If
    Loop
    End Function
    
    Public Function WaitFichier(pTimeOut As Long) As Boolean
    ' Attend que le fichier soit chargé
    ' pTimeOut est un time out en secondes (WaitFichier vaut True si Timeout)
    Dim lhWndP As Long
    Dim lTimer As Double
    lTimer = Timer
    Do
       DoEvents
       If GetHandleFromPartialCaption(lhWndP, "nomdufichier") = True Then instance = lhWndP: Exit Do 'on attribue la valeur du handle à la variable instance
       If pTimeOut > 0 And Timer - lTimer > pTimeOut Then
           WaitFichier = True
           Exit Do
       End If
    Loop
    End Function
    Sinon, j'ai trouvé aussi ceci sur Internet, ce à quoi je rajoute quelques lignes pour tente de sortir du mode protégé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Dim wbProtected As Workbook
    Dim fich
    If Application.ProtectedViewWindows.Count > 0 Then
        For Each fich In Application.ProtectedViewWindows
            If Left(Wb.Name, Len("nomdufichier")) = "nomdufichier" Then
                Set wbProtected = Application.ProtectedViewWindows(1).Workbook
            End If
        MsgBox wbProtected.Name
        Next
    End If
    wbProtected.Activate
    wbProtected.Edit
     
    wbProtected.Unprotect
    On retrouve bien le fichier, mais je n’arrive pas à sortir du mode protégé...

    Merci pour ton aide.

    Yohann

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur étude
    Inscrit en
    Novembre 2016
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur étude

    Informations forums :
    Inscription : Novembre 2016
    Messages : 50
    Par défaut
    Bon, j'ai enfin trouvé.

    Au final, pas besoin d'activer le fichier en utilisant le handle.

    Je vous livre les dernières lignes du code. On vérifie si on trouve le fichier dans la collection WorkBooks (au cas où il ne serait pas en mode protégé), auquel cas on fait le traitement. Si jamais il ne s'y trouve pas, on regarde les fichier en mode protégé et quand on l'a trouvé, on fait le traitement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    'on commence par vérifier dans la collection WorkBooks
        Dim Wb As Excel.Workbook
        Dim Appli As Excel.Application
     
        On Error Resume Next
     
        Set Appli = GetObject(, "Excel.Application")
     
        For Each Wb In Appli.Workbooks
            If Left(Wb.Name, Len("nomdufichier")) = "nomdufichier" Then
                Wb(Sheets(1)).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) 'en l'occurence, il s'agit de copier-coller l'onglet du fichier téléchargé dans notre classeur
                Application.DisplayAlerts = False
                Wb.Close 'on ferme le fichier téléchargé
                Application.DisplayAlerts = True
                Exit Sub
            End If
        Next Wb
     
    'sinon on regarde les fichiers en mode protégé
    Dim wbProtected As Workbook
    Dim fich
    Dim i
    If Application.ProtectedViewWindows.Count > 0 Then 'si on a bien des fichiers en mode protégé
        For Each fich In Application.ProtectedViewWindows
            If Left(fich.Caption, Len("nomdufichier")) = "nomdufichier" Then
                fich.Activate 'on l'active
                Application.ActiveProtectedViewWindow.Edit 'on le passe en mode non protégé
                Set wbProtected = ActiveWorkbook
                Sheets(1).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) 'on fait le traitement
                Application.DisplayAlerts = False
                wbProtected.Close 'et on ferme le fichier téléchargé
                Application.DisplayAlerts = True
            End If
        Next
    End If
    Yohann

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 06/06/2008, 15h20
  2. Réponses: 2
    Dernier message: 03/11/2006, 10h36
  3. [C# 2.0] Comment ouvrir un fichier via son application?
    Par arasium dans le forum Windows Forms
    Réponses: 4
    Dernier message: 05/10/2006, 12h33
  4. Réponses: 1
    Dernier message: 24/05/2006, 21h21
  5. Réponses: 3
    Dernier message: 12/07/2005, 13h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo