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 :

[XL-2010] Question à propos de ADOX


Sujet :

Macros et VBA Excel

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut [XL-2010] Question à propos de ADOX
    Bonjour,

    J'ai réutilisé 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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    Option Explicit
     
    Sub Tst()
    Dim Cn As ADODB.Connection
    Dim oCat As ADOX.Catalog
    Dim Fichier As Variant
    Dim Feuille As ADOX.Table
    Dim Rst As ADODB.Recordset
    Dim texte_SQL As String
    Dim Ar() As String, i As Long
     
        Fichier = Application.GetOpenFilename("Fichier Excel, *.csv;*.xls")
        If Fichier = False Then Exit Sub
     
        Set Cn = New ADODB.Connection
        Set oCat = New ADOX.Catalog
     
        Cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Fichier & ";Extended Properties=Excel 8.0;"
     
        Set oCat.ActiveConnection = Cn
        For Each Feuille In oCat.Tables
            i = i + 1
            ReDim Preserve Ar(i)
            Ar(i) = Feuille.Name
        Next Feuille
     
        texte_SQL = "SELECT * FROM [" & Ar(1) & "]"
     
        Set Rst = New ADODB.Recordset
        Set Rst = Cn.Execute(texte_SQL)
     
        Range("A2").CopyFromRecordset Rst
     
        Set Feuille = Nothing
        Set oCat = Nothing
        Cn.Close
        Set Cn = Nothing
     
    End Sub
    Cependant, si j'ai bien compris, ce code permet de trier les noms de feuilles du classeur. Je cherche uniquement à récupérer le nom de la première feuille, quel qu’il soit.

    J'ai essayer des différentes manières ( sans utiliser ADOX et en utilisant Sheets(1)) et en essayer de modifier la boucle ForEach pour ne récupérer que la première valeur mais je ne trouve pas de solution. Pouvez vous m'aider à trouver une solution?

    Merci d'avance
    Tohrak

  2. #2
    Invité
    Invité(e)
    Par défaut Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dim SheetName as string
    SheetName=sheets(1).Name

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    Merci pour votre réponse.

    Cette commande me permet de récupérer le nom de la feuille du classeur actif, alors que je voudrais récupérer le nom de la première feuille du classeur auquel je suis connecter grâce au ADODB.

  4. #4
    Invité
    Invité(e)
    Par défaut
    pour récupérer le nom de la première feuille de ton classeur:


    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
    Sub Tst()
    Dim Cn As ADODB.Connection
    Dim oCat As ADOX.Catalog
    Dim Fichier As Variant
    Dim Feuille As ADOX.Table
    Dim Rst As ADODB.Recordset
    Dim texte_SQL As String
    Dim Ar() As String, i As Long
     
        Fichier = Application.GetOpenFilename("Fichier Excel, *.csv;*.xls")
        If Fichier = False Then Exit Sub
     
        Set Cn = New ADODB.Connection
        Set oCat = New ADOX.Catalog
     
        Cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Fichier & ";Extended Properties=Excel 8.0;"
     
        Set oCat.ActiveConnection = Cn
    '    Debug.Print oCat.Tables(0).Name
    '    For Each Feuille In oCat.Tables
    '        i = i + 1
    '        ReDim Preserve Ar(i)
    '        Ar(i) = Feuille.Name
    '    Next Feuille
     
        texte_SQL = "SELECT * FROM [" & oCat.Tables(0).Name & "]"
     
        Set Rst = New ADODB.Recordset
        Set Rst = Cn.Execute(texte_SQL)
     
        Range("A2").CopyFromRecordset Rst
     
        Set Feuille = Nothing
        Set oCat = Nothing
        Cn.Close
        Set Cn = Nothing
     
    End Sub
    Dernière modification par AlainTech ; 26/04/2014 à 00h07. Motif: Suppression de la citation inutile

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    texte_SQL = "SELECT * FROM [" & oCat.Tables(0).Name & "]"
    Cette ligne marche correctement. Mais elle ne me renvoie toujours pas la bonne valeur. Je m'explique: les classeurs que j'ouvre possèdent, normalement, deux feuilles. Seul la première m'intéresse car je dois récupérer les valeurs de cette première feuille. Il faut que je puisse récupérer les valeurs de la première feuille quelque soit le nom et quelque soit le nombre de feuilles existantes.

    Le code que vous m'avez proposé me renvoie ma deuxième feuille en Tables(0) et ma première feuille en Tables(1). Donc la question est: est-ce que il y a un tri alphabétique directement dans le oCat.Tables ou est-ce que le tableau est crée de manière "inverse" ( Avec la première feuille à la fin et la dernière feuille au début)

    Edit: D'après mes test le oCat.Tables tri déjà le nom des pages par ordre alphabétique du coup ça ne m'arrange pas trop (je dois principalement traité des feuilles qui s'appellent soit feuil1 soit sheet1) Pour le moment je ne vois que la solution de passer par un If avant mais si quelqu'un à une autre solution je suis preneur ( dans le cas où un client mettrais un autre nom à sa feuille)

  6. #6
    Expert éminent
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Points : 6 871
    Points
    6 871
    Par défaut
    Bonjour,

    Regarde si c'est ce que tu souhaite :
    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
     
    Sub Test()
     
        MsgBox NomFeuille("F:\MonClasseur.xls")
     
    End Sub
     
    Function NomFeuille(Fichier As String) As String
     
        Dim Con As Object
        Dim Cat As Object
        Dim Feuille As Object
     
        'crée les objets de connection au classeur
        Set Con = CreateObject("ADODB.Connection")
        Set Cat = CreateObject("ADOX.Catalog")
     
        Set Feuille = CreateObject("ADOX.Table")
     
        Con.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
                 & Fichier & _
                 ";Extended Properties=Excel 8.0;"
     
        Set Cat.ActiveConnection = Con
     
        'retourne le nom de la 1ère feuille
        NomFeuille = Replace(Cat.Tables(0).Name, "$", "")
     
        'mets fin à la connection
        Con.Close
     
    End Function
    Hervé.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    Mon problème n'est toujours pas résolu. J'ai des fichiers Excel avec deux feuilles ( soit Feuil1 et liste, soit Sheet1 et liste)

    oCat.Table(0).Name me renvoie "Feuil1$" dans le premier cas et "liste" dans le deuxième cas

    Je dois donc récupérer "Sheet1" avec oCat.Table(1).Name

    Cependant, il me faudrait une fonction qui me récupère automatiquement la première feuille ( pour pouvoir gérer les cas où le nom de la première feuille n'est pas Feuil1 ou Sheet1)

  8. #8
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut

    Bonjour, bonjour,

    pour un fichier texte .csv - cf ligne n°12 du code initial - forcément il n'y a qu'un seul onglet
    du nom du fichier sans son extension, inutile donc de l'ouvrir !

    Si ADO n'est pas maitrisé, pourquoi ne pas ouvrir directement le classeur ?
    Maintenant, un fois le nom de la première feuille récupérée, quel est donc le but ?

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    Je me suis inspiré du code initial mais je ne traite pas de fichier .csv

    Je travail actuellement sur l'optimisation d'une macro Excel qui ouvrait justement tous les fichiers. Mais c'est une grosse perte de temps lorsque le nombre de classeur a traité est grand.

    Grosso modo, j'ai un fichier Excel "upload.xls" qui récupère toute les données qui sont sur la première feuille des différents fichier Excel pour les recopier dans "upload.xls". Une fois les données dans ce fichier elles seront traitées.

    Du coup, j'ai crée un If qui traite si la feuille s'appelle "feuil1" ou "sheet1" mais les fichiers Excels à uploader viennent de clients ce qui ne garantie pas que le nom des feuilles seront toujours ceux la.

    (D'ailleurs au passage, est-ce qu'il existe un moyen de récupérer la dernière ligne où il y a écrit quelque chose quelque soit la colonne?)

  10. #10
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut

    Sauf erreur de ma part, oui en ADO seulement si les données sont contiguës …

    Sinon tel quel, recopier les données pour ensuite les traiter est un peu dommage, là pour le coup c'est une perte de temps,
    pourquoi ne pas les traiter directement sans les recopier ?

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Les données sont traités par la suite par des scripts que je maitrise pas du tout pour le moment. ( déjà qu'en VBA je suis débutant)

    J'essaie déjà pour le moment de récupérer toutes les donnés pour ensuite les traitées et je verrais par le suite s'il n'est pas plus judicieux de directement les traités plutôt que de les récupérer.

    Le problème pour connaître la dernière ligne est que les données ne sont pas contiguës, sinon je pourrais récupérer la dernière ligne en fonction de n'importe quel colonne mais le il faudrait que je connaisse la dernière ligne sur les 10 premières colonnes environ.

    Edit: J'ai trouver une solution pour récupérer la dernière ligne avec aucune cellule vide.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dernierLigne = Cells.Find("*", , , , xlByRows, xlPrevious).Row ' on récupère la dernière ligne où il y a quelque chose d'écrit
    Me reste toujours le problème pour récupérer la première feuille automatiquement.

    Merci pour votre aide.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Bon du coup je traite le problème du tri alphabétique de le oCat.Table(x).Name avec un if et c'est efficace pour 97% de mes fichiers

    1% des fichiers ont un nom différents que je vais essayer de traité différemment.

    Cependant, les 2% restant ont quelque chose qui m'intrigue. Les fichiers comportent deux feuilles: Sheet1 et Listes1

    Il passe dans le test suivant:
    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
    If oCat.Tables(0).Name = "Feuil1$" Or oCat.Tables(0).Name = "Objecti*" Then
                texte_SQL = "SELECT * FROM [" & oCat.Tables(0).Name & "]" ' On récupère le nom de la feuille
            ElseIf oCat.Tables(1).Name = "Sheet1$" Then
                texte_SQL = "SELECT * FROM [" & oCat.Tables(1).Name & "]" ' On récupère le nom de la feuille
            Else
                MsgBox oCat.Tables(0).Name
                MsgBox oCat.Tables(1).Name
                Dim ligneFin As Integer
                Sheets(8).Select
                Range("A1").Select
                If IsEmpty(ActiveCell) Then 'Si "A1" est vide on écrit dedans"
                    ActiveCell.Value = ("Le fichier:" & fichier & " n'a pas pu être traité!")
                    ActiveCell.Offset(0, 1).Select
                    ActiveCell.Value = ("La première feuille ne s'appelle ni 'Feuil1', ni 'Sheet1'")
                Else 'Sinon on écrit à la suite
                    Cells(((Cells.Find("*", , , , xlByRows, xlPrevious).Row) + 1), 1).Select
                    ActiveCell.Value = ("Le fichier: " & fichier & " n'a pas pu être traité!")
                    ActiveCell.Offset(0, 1).Select
                    ActiveCell.Value = ("La première feuille ne s'appelle ni 'Feuil1', ni 'Sheet1'")
                End If
    Les deux MsgBox sont la pour moi, pour récupérer le nom. Le premier m'affiche "Liste1$" et le deuxième "Listes$_xlnm#Print_Area" alors que dans d'autre cas où mes feuilles s'appellent "Sheet1" et "Liste" cela me renvoie bien la valeur "Sheet1".

    Edit: Dans certains cas le nom est 'Sheet1$' au lieu de Sheet1. Je n'arrive pas à récupérer la feuille en faisant "*Sheet*" ( La syntaxe est sûrement fausse)

    Est-ce que quelqu'un aurait une solution?

  13. #13
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut

    S'il y a moins de 100 000 lignes par fichier, autant ouvrir directement chaque fichier et les traiter directement
    et cela ne devrait pas être long avec du bon code …

  14. #14
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Bonjour,
    il y a peut être une autre façon de faire, ta notion de première feuille n'étant pas bien claire !
    Le code que vous m'avez proposé me renvoie ma deuxième feuille en Tables(0) et ma première feuille en Tables(1)
    elle est "première par rapport à quoi ?"

    Pourquoi ne teste tu pas le conteu de chaque feuille, il y a peut être un élèment toujours présent ?

    Ou si ta deuxième feuille s'appelle toujours "Liste" pourquoi ne pas les traiter sauf si son nom est "liste"

  15. #15
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Marc-L Voir le message

    S'il y a moins de 100 000 lignes par fichier, autant ouvrir directement chaque fichier et les traiter directement
    et cela ne devrait pas être long avec du bon code …
    Les fichiers en question font maximum 30 lignes avec seulement une dizaine qui nous intéresse. Et il y a environ 300 fichier à ouvrir.

    Citation Envoyé par Oliv- Voir le message
    Bonjour,
    il y a peut être une autre façon de faire, ta notion de première feuille n'étant pas bien claire !


    elle est "première par rapport à quoi ?" Première par rapport au classeur (Sheets(1) si c'était le classeur courant)

    Pourquoi ne teste tu pas le conteu de chaque feuille, il y a peut être un élèment toujours présent ?

    Ou si ta deuxième feuille s'appelle toujours "Liste" pourquoi ne pas les traiter sauf si son nom est "liste"
    Les fichiers sont des fichiers envoyés par des clients donc il peut y avoir potentiellement n'importe quoi.

    Sur les 300 derniers fichiers reçu le 3/4 ont une feuille 1="Sheet1" et une feuille 2="Listes"

    Les autres sont la plupart des "Feuil1" et "Listes" et quelques un ont juste une seule feuille "Objectifs 2013"

    Pour le moment je traite toutes les feuilles de ce cas de figure mais si un client envoie une fichier Excel avec un nom de feuille différent, impossible de le traiter.

    Dans tout les cas, c'est le feuille 1 qui possède les informations à récupérer, le feuille "Listes" ne m'est d'aucune utilité.

    Merci pour vos réponses

  16. #16
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    et quand tu as trouvé ta feuille comment traites tu la copie avec ADO ou Worbooks.open... ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            For Each sh In Sheets
                If sh.Name <> "Liste" Then 
    'traitement
                end if
            Next sh

  17. #17
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 26
    Points : 12
    Points
    12
    Par défaut
    Je traite avec ADO ( voir 2 poste de ma part plus haut ) avec le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    texte_SQL = "SELECT * FROM [" & oCat.Tables(0).Name & "]"
    qu'ensuite je copy dans ma feuille courante tel quel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Set Rst = New ADODB.Recordset
            Set Rst = Cn.Execute(texte_SQL)
            fichiersTraités = fichiersTraités + 1
            Sheets(1).Cells(numLigne, 2).CopyFromRecordset Rst

Discussions similaires

  1. Question à propos des compilateurs
    Par elf dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 20/07/2005, 17h00
  2. Question à propos des niveaux de transaction
    Par davy.g dans le forum Oracle
    Réponses: 3
    Dernier message: 18/01/2005, 15h31
  3. Petite question à propos du redbook...
    Par Michaël dans le forum OpenGL
    Réponses: 3
    Dernier message: 04/11/2004, 12h54
  4. Petite question à propos d'une requete
    Par ViBy dans le forum Langage SQL
    Réponses: 4
    Dernier message: 15/09/2004, 12h21
  5. Une question à propos des thread
    Par tscoops dans le forum C++Builder
    Réponses: 4
    Dernier message: 07/11/2003, 14h03

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