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 :

Erreur d'exécution, '1004': la méthode 'Sheets' de l'objet '_Global' a échoué


Sujet :

Macros et VBA Excel

  1. #1
    Nouveau membre du Club Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    Octobre 2019
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : Octobre 2019
    Messages : 31
    Points : 30
    Points
    30
    Par défaut Erreur d'exécution, '1004': la méthode 'Sheets' de l'objet '_Global' a échoué
    Bonjour,

    cela fait plusieurs jours que je bute sur ce problème et mes connaissances Excel ne sont pas suffisantes pour le résoudre.

    Lorsque j'exécute une macro depuis une invite de commande sous windows 11 j'obtiens une erreur 1004. Si j'exécute la même macro manuellement, tout se passe bien.
    Que me manque-t-il pour que cela fonctionne correctement dans les deux cas ?

    Pour les besoins de cette question, j'ai simplifié au maximum. Le classeur Excel contient une feuille avec 10 lignes. La macro se contente d'afficher le nombre de lignes. Dans la réalité, j'ai plusieurs feuilles et la macro réalise une mise à jour de ces feuilles.

    J'utilise l'invite de commande pour automatiser ces mises à jour en lançant une procédure batch programmée.

    L'erreur 1004 a lieu sur la ligne en gras
    Erreur d'exécution, '1004': la méthode 'Sheets' de l'objet '_Global' a échoué

    Code macro Nblig dans Module1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub Nblig()
        Dim num
        
        Sheets("Feuil1").Select
        num = ActiveSheet.UsedRange.Rows.Count
        MsgBox "Nombre de lignes " & num
        Application.Quit
    End Sub
    Code de Workbook_open dans ThisWorkbook
    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
     
    Private Declare PtrSafe Function GetCommandLine Lib "kernel32" Alias "GetCommandLineA" () As LongPtr
    Private Declare PtrSafe Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As LongPtr) As Long
    Private Declare PtrSafe Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As LongPtr) As Long
     
    Private Function GetCmd() As String
       Dim lpCmd As LongPtr
       lpCmd = GetCommandLine()
       GetCmd = Space$(lstrlen(ByVal lpCmd))
       lstrcpy ByVal GetCmd, ByVal lpCmd
    End Function
    Private Sub Workbook_Open()
    Dim macmdline As Variant
    Dim monparam As Variant 'déclare une variable
    Dim macmd As Variant 'déclare une variable
     
        macmdline = GetCmd 'affecte la valeur de la ligne de commande
        If Not IsNull(macmdline) Then 'si la variable est nulle
            If Len(macmdline) > 0 Then 'on s'assure qu'il y a eu une ligne de commande passée
                If InStr(macmdline, "/cmd") > 0 Then
                    macmdline = Replace(macmdline, ThisWorkbook.FullName, "", , , vbTextCompare)
                    monparam = Split(macmdline, "/cmd")
                    MsgBox monparam(1)
                    macmd = Split(monparam(1), " ")
                    'MsgBox "0=>" & macmd(0) & "<="
                    Application.Run Mid(macmd(0), 2)
                End If
            End If
        End If
    End Sub
    Ligne d'appel dans l'invite de commande Windows
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    call "C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE" /cmd/Nblig "test.xlsm"

  2. #2
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2013
    Messages : 108
    Points : 171
    Points
    171
    Par défaut
    Bonjour

    erreur 1004 la feuille n'existe pas

    je vous propose de remplacer

    Sheets("Feuil1").Select

    Par :

    Dim sh as WorkSheet
    Dim shName as String
    Dim shIndex as Long
    Dim sMsg as String
    For Each sh in ThisWorkbook.WorkSheets
    sMsg= sMsg & vbCrlf & "Code=" & sh.CodeName
    sMsg= sMsg & "Name=" & sh.Name
    sMsg= sMsg & "Index=" & Cstr(sh.Index)
    Next
    Msgbox sMsg

    Pour les paramètres de la ligne de commande, je verrai plutot /mNbLig au lieu de /cmd...

    A lire :
    https://support.microsoft.com/fr-fr/...5-441737deb3a6

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 175
    Points : 1 724
    Points
    1 724
    Par défaut
    Salut,

    Je dirait grand classique:
    Contexte implicite.
    Je m'explique:
    Sheets("Feuil1").Select Est implicitement ActiveWorkbook.Sheets("Feuil1").Select
    ActiveWorkbook désigne t'il le classeur qui contient le code ? Rien n'est moins sûr.

    num = ActiveSheet.UsedRange.Rows.Count Est implicitement ActiveWorkbook.ActiveSheet (et voir ma remarque ci-dessus).

    Il n'y a pas 36 solutions: Soit explicite afin de toujour savoir sans ambiguité de quoi tu parles:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Dim Ws as Excel.Worksheet
    Set Ws = ThisWorkbook.Worksheets("Feuil1")
     
    Dim Num As Long
    Num = Ws.UsedRange.Rows.Count
    PS: Sauf besoin impérieux, on évite de balader la sélection dans tous les sens.
    D'une part c'est lent (très lent),
    D'autre part, visuellement, ca fait ressembler ton classeur à un sapin de Noël, c'est horrible.

  4. #4
    Nouveau membre du Club Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    Octobre 2019
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : Octobre 2019
    Messages : 31
    Points : 30
    Points
    30
    Par défaut
    Merci de vos réponses.

    @deedolith
    Effectivement la solution proposée fonctionne. Merci.

    Mais comment faire pour que le code fonctionne sur Sheets("Feuil1").Select ?

    En fait si j'ai bien compris ton explication, le classeur sur lequel je pense travailler n'est pas le bon classeur puisque j'utilise les valeurs par défaut.
    N'y a-t-il pas une technique qui permette de fixer la valeur par défaut du classeur ?

    Je rappelle que dans la réalité j'ai plusieurs feuilles et que la macro fait la mise à jour de ces différentes feuilles.

    Voici la macro. Le code est certainement horrible, mais il a l'avantage de fonctionner (en manuel)... Je l'ai constitué grâce à l'enregistreur de macro.

    Le principe:
    - Dans la feuille Catlg j'ai une table constituée avec l'import d'un fichier .cvs
    - À chaque MAJ de ce fichier, je mets à jour cette table et je récupère le nombre de lignes
    - Dans la feuille Centra j'ai tout un tas de colonnes qui référencent la table Catlg
    - La ligne 1 ce sont les titres que je garde
    - Je garde également la ligne 2 qui contient toutes les formules
    - J'efface toutes les lignes depuis la 3
    - Je sélectionne la ligne 2
    - Je tire cette ligne jusqu'au nombre de lignes de la table Catlg
    - Je recommence le même processus pour une autre feuille qui s'appelle Résumé
    - Je sauvegarde le classeur et je sors

    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
     
    Sub Updt()
        Dim num
     
        Sheets("Catlg").Select
        ActiveWorkbook.Connections("Requête - Catlg").Refresh
        num = ActiveSheet.UsedRange.Rows.Count
        ActiveWorkbook.Save
     
        Sheets("Centra").Select
        Range("A3:N65536").ClearContents
        Range("A2:N2").Select
        Selection.AutoFill Destination:=Range("A2:N" & num), Type:=xlFillDefault
        Range("A1").Select
     
        Sheets("Résumé").Select
        Range("A3:B65536").ClearContents
        Range("A2:B2").Select
        Selection.AutoFill Destination:=Range("A2:B" & num), Type:=xlFillDefault
        Range("A1").Select
     
        ActiveWorkbook.Save
        Application.Quit
    End Sub
    Le processus n'est pas fini puisque après, j'ai une autre macro qui fait un autre travail sur ces feuilles. Mais si la macro Updt fonctionne, j'arriverai à m'en sortir en appliquant les mêmes solutions.

  5. #5
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    12 842
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 12 842
    Points : 28 754
    Points
    28 754
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Le principe:
    - Dans la feuille Catlg j'ai une table constituée avec l'import d'un fichier .cvs
    - À chaque MAJ de ce fichier, je mets à jour cette table et je récupère le nombre de lignes
    Pour importer le fichier csv, il serait plus simple d'utiliser Power Query (intégré à Excel depuis la version 2016 et pour les versions antérieures c'est un Add-In
    Dans la feuille Centra j'ai tout un tas de colonnes qui référencent la table Catlg
    - La ligne 1 ce sont les titres que je garde
    - Je garde également la ligne 2 qui contient toutes les formules
    Power Query va créer un tableau structuré ce qui aura comme avantage de ne plus devoir faire les mises à jour car à chaque actualisation, la mise à jour sera automatique
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 175
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 175
    Points : 1 724
    Points
    1 724
    Par défaut
    Citation Envoyé par Obelix84 Voir le message
    N'y a-t-il pas une technique qui permette de fixer la valeur par défaut du classeur ?
    ThisWorkbook renvoie une référence sur le classeur qui contient le code.

  7. #7
    Nouveau membre du Club Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    Octobre 2019
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : Octobre 2019
    Messages : 31
    Points : 30
    Points
    30
    Par défaut
    @Deedolith
    Merci de votre réponse.

    J'ai essayé de m'en servir, mais je n'y arrive pas, j'ai toujours l'erreur 1004.

    Comment faut-il que je modifie le code pour que cela fonctionne lorsque le lancement se fait depuis cmd ?

    @Philippe Tulliez
    En admettant que j'arrive à me servir de Power Query cela va-t-il fonctionner lorsque l'appel a lieu depuis cmd de windows ?

    @Tous
    Je rappelle que mes macros aussi mal écrites soient-elles fonctionnent lorsque je les utilise manuellement. Mon problème est de faire en sorte qu'elles fonctionnent lorsque l'appel a lieu depuis cmd de windows, ce qui me permet d'automatiser les processus.
    Cela fait beaucoup de temps que je bute sur ce problème qui est certainement trivial et connu, et c'est pour ça que j'ai fait un appel "au secours" sur ce forum que je pense être un des meilleurs du net sur tous les problèmes techniques liés à l'informatique. À 80 ans, je ne cherche pas à développer mes connaissances en VBA, mais simplement à résoudre un problème bloquant pour ce que je veux faire. Merci de m'aider.

  8. #8
    Membre averti Avatar de Nain porte koi
    Homme Profil pro
    a
    Inscrit en
    Novembre 2023
    Messages
    259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : a

    Informations forums :
    Inscription : Novembre 2023
    Messages : 259
    Points : 347
    Points
    347
    Par défaut
    hello,

    essayez ce code
    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
    Sub Updt()
        Dim num
     
        With ThisWorkbook
     
            With .Sheets("Catlg")
                .Connections("Requête*-*Catlg").Refresh
                num = .UsedRange.Rows.Count
                .Save
            End With
     
            With .Sheets("Centra")
                .Range("A3:N65536").ClearContents
                .Range("A2:N2").AutoFill Destination:=.Range("A2:N" & num), Type:=xlFillDefault
            End With
     
     
            With .Sheets("Résumé")
                .Range("A3:B65536").ClearContents
                .Range("A2:B2").AutoFill Destination:=.Range("A2:B" & num), Type:=xlFillDefault
            End With
     
            .Save
     
        End With
     
        Application.Quit
    End Sub
    JièL
    Membre des AMIS
    Anti Macro Inutilement Superfétatoire

  9. #9
    Membre éclairé Avatar de Valtrase
    Homme Profil pro
    Jeune retraité...
    Inscrit en
    Janvier 2016
    Messages
    394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Jeune retraité...
    Secteur : Boutique - Magasin

    Informations forums :
    Inscription : Janvier 2016
    Messages : 394
    Points : 693
    Points
    693
    Par défaut
    Bonjour à tous,
    Je propose une autre approche glanée sur la toile.
    Ne pas utiliser les API Windows mais une variable d'environnement, pour le test j'ai définie cette variable MyCommandLine comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set MyCommandLine=/C:\ /True /False
    suit le lancement du classeur, Changer votre répertoire de destinnation pour l'ouverture du classeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    start "xl" excel.exe /e "D:\Utilisateurs\Valtrase\Desktop\Test command line.xlsm"
    • Adapter le chemin du répertoire
    • Ne pas supprimer le /e qui semble être obligatoire

    Chez moi j'arrive à récupèrer les variables plus un petit complément...

    Nom : 000497.png
Affichages : 30
Taille : 25,0 Ko

    Pour le post c'est ICI:

    Et pour le fichier :
    Test command line.xlsm
    Jean-Paul sous Office 365 et Windows 10/11 (Intel I7 16Go)

    Si vous avez trouvé réponse à votre question penser à la passer en Vous avez aimé la discussion alors un fait toujours plaisir.
    Le savoir n'a de valeur que s'il est partagé.
    La vérité de demain se nourrit de l'erreur d'hier. Antoine de Saint-Exupéry

  10. #10
    Nouveau membre du Club Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    Octobre 2019
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)

    Informations forums :
    Inscription : Octobre 2019
    Messages : 31
    Points : 30
    Points
    30
    Par défaut
    @Nain porte koi
    Merci de vous être penché sur mon problème. Mais la solution proposée génère d'autres erreurs, en particulier sur .connections

    @Valtrase
    C'est une autre approche du lancement des commandes. Merci.

    @Tous
    Comme mes macros actuelles fonctionnent si elles sont lancées en manuel, je me suis dit que le problème ne venait pas des macros, mais de l'environnement dans lequel elles s'exécutaient et j'ai cherché dans cette voie et... eurêka !

    J'ai modifié les coches dans les paramètres du centre de gestion de la confidentialité :
    - Mode protégé (supprimé les deux premières, mais pas celle d'Outlook)
    - Paramètres des macros (j'ai activé le mode non recommandé...)
    - Paramètres ActiveX (j'ai activé le mode non recommandé..)
    - Emplacements approuvés (j'ai rajouté le dossier où se trouvent les fichiers Excel et csv)

    Et tout s'est mis à fonctionner correctement comme par miracle...!

    Je remercie tous ceux qui se sont penchés sur mon problème, mais comme dit le proverbe "Aide-toi, le ciel t'aidera."...

    J'attends encore quelques jours avant de passer le sujet en résolu.

Discussions similaires

  1. Réponses: 0
    Dernier message: 21/07/2016, 13h46
  2. [XL-MAC 2011] "Erreur d'exécution « 1004 »: La méthode « Range » de l'objet « _Global » a échoué"
    Par 123-deea dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 14/06/2016, 10h37
  3. Réponses: 9
    Dernier message: 31/03/2015, 19h06
  4. Réponses: 6
    Dernier message: 08/01/2009, 11h06
  5. [VB6] La méthode 'Sheets' de l'objet '_Global' a échoué (erreur 1004)
    Par koriteki dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 22/04/2008, 16h29

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