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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    Octobre 2019
    Messages
    52
    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 : 52
    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 expérimenté
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2013
    Messages
    122
    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 : 122
    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 Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 466
    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
    Membre averti Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    Octobre 2019
    Messages
    52
    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 : 52
    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
    13 114
    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 : 13 114
    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 Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 466
    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
    Membre averti Avatar de Obelix84
    Homme Profil pro
    Retraité (ancien ingénieur système sur gros systèmes Bull/Ibm)
    Inscrit en
    Octobre 2019
    Messages
    52
    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 : 52
    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.

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