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

  1. #1
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    octobre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2012
    Messages : 3
    Points : 3
    Points
    3

    Par défaut ListObject ListRows et Tableau

    Dans mon workbook , j'ai une worksheet qui contient des "tableaux" (tableaux au sens de l'IHM utilisateur final de l'application Excel comme illustré ci apres

    Nom : Excel-Table.PNG
Affichages : 2727
Taille : 29,1 Ko
    Ces tableaux (Tables en anglais) sont représentés par un object de classe ListObject que l'on trouve à l'aide de la propriété ListObjects de la worksheet

    Je souhaite gérer le contenu de chaque tableau via une UserForm pour ajouter supprimer un éléments de ce tableau (le contenu de chaque Tableau est dynamique et les tableaux sont créés depuis la UserForm)
    Je ne parviens pas à utiliser la propriété Resize pour dimensionner ce tableau au nombre d'elements que je souhaite y stocker (mise a jour du tableau)
    J'ai essaye dans le code qui suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
         loTable.Resize loTable.Cells(1, 1)   ' loTable est un tableau a une colonne
    et j'obtiens le message suivant
    Nom : vba-error-msgbox.PNG
Affichages : 2235
Taille : 2,5 Ko

    Alors que la doc indique que ca existe https://msdn.microsoft.com/en-us/lib.../ff838369.aspx

    Dans le code qui suit loTable est un Tableau et strItems un tableau VBA (array) contenant les valeurs a stocker dans le Tableau (Table)
    Je le fais un peu bourin en effacant une a une les lignes puis j'enregistre a nouveau ligne a ligne
    Pour redimensionner je pensais qu'il y aurait peut etre un moyen de la faire en une instruction.
    De plus le code est particulièrement lent (on voit les lignes disparaitre/apparaitre une a une - c'est acceptable pour une vingtaine d'elements pour pres de 200 ca va pas le faire)
    Avez vous une soluce ?

    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
     
    Sub ViewManager_SaveViewAttribute(ByRef strItems() As String, ByRef loTable As ListObject)
        Dim i As Integer
        Dim olrs As ListRows
     
        Set olrs = loTable.ListRows
        For i = olrs.Count To 1 Step -1
            olrs(i).Delete
        Next i
        For i = 1 To UBound(strItems)
                olrs.Add
                olrs(olrs.Count).Range.Cells(1, 1).Value = strItems(i)
                Debug.Print ">" & strItems(i) & " saved to table ''" & loTable.Name & "''"
        Next i
    End Sub
    Idem pour stocker la valeur je trouve l'instruction suivante un peu lourde
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    olrs(olrs.Count).Range.Cells(1, 1).Value

  2. #2
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    juillet 2012
    Messages
    4 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : juillet 2012
    Messages : 4 820
    Points : 9 318
    Points
    9 318
    Billets dans le blog
    5

    Par défaut

    Bonjour,

    tu as mal lu "la doc"

    l'argument "Range" utilisé n'est en aucun cas lié au ListObjects

    ton exemple à toi provoque une erreur, car pour faire référence à une cellule (ou tout "Range") du tableau, tu dois fournir à VBA le référentiel spatial :

    - le tableau entier ? C'est à dire le .Range du ListObject
    - la zone de données ? Le DataBodyRange
    - la zone d'en-têtes ? Le HeaderRowRange
    etc...


    un exemple en utilisant le Range du Listobject
    Via un Tableau unidimensionnel (hard codé pour l'exemple), on redimensionne le tableau et on injecte les éléments en bas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Option Base 1
    Sub toto()
    Dim Tableau: Tableau = Array("toto", "titi", "tata")
        With ActiveSheet.ListObjects(1)
            .Resize .Range.Resize(.Range.Rows.Count + UBound(Tableau), .Range.Columns.Count)
            .Range.Cells(.Range.Rows.Count - UBound(Tableau) + 1, 1).Resize(UBound(Tableau), 1).Value = Application.Transpose(Tableau)
        End With
    End Sub

  3. #3
    Candidat au Club
    Homme Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    octobre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : octobre 2012
    Messages : 3
    Points : 3
    Points
    3

    Par défaut

    Merci pour cette reponse
    dans l'exemple qu tu donnes le bloc With porte bien sur un objet de class ListObject : ActiveSheet.ListObjects(1)
    et .Resize equivaut a ActiveSheet.ListObjects(1).Resize
    ai je rate quelque chose ?

    A l'analyse détaillée ce code retaille le "Tableau" (pas un array VBA un "Tableau" - Table en anglais) - loTable dans le code qui suit - en l'agrandissant d'autant de lignes que l'array d'entree contient ce qui n'est pas mon intention. De plus il a un effet de bord decrit en fin de ce post

    Je souhaite retailler le Tableau a la dimension du array
    Meme en changeant le code par rapport a cette exigence ca ne semble pas bien fonctionner

    J'ai essaye le morceau de code adapté comme ci apres
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Sub ViewManager_SaveViewAttribute(ByRef strItems() As String, ByRef loTable As ListObject)
        Dim iCount As Integer
        iCount = UBound(strItems)
        With loTable
            .Resize .Range.Resize(iCount, 1)
            .Range.Cells(1, 1).Resize(iCount, 1).Value = Application.Transpose(strItems)
        End With
    End Sub
    avant execution : titi, tata, cost sizer, sont 3 tableaux differents
    Nom : avant.PNG
Affichages : 2233
Taille : 14,4 Ko
    apres execution : en colonne I il y a bien ajout des données mais plus de tableau créé au préalalble en colonne H la ou j'aurais du ajoute les donnes (voir image suivante)
    Nom : apres.PNG
Affichages : 2250
Taille : 17,5 Ko
    Nom : intermediaire.PNG
Affichages : 2269
Taille : 16,4 Ko
    Images attachées Images attachées   

  4. #4
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    février 2010
    Messages
    5 867
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : février 2010
    Messages : 5 867
    Points : 10 896
    Points
    10 896

    Par défaut

    Bonjour

    A noter que les tableaux se "resizent" dynamiquement quand on ajoute des données sous la dernière ligne (sauf feuille protégée) on qu'on supprime des lignes...
    Chris

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  5. #5
    Expert éminent

    Homme Profil pro
    Curieux
    Inscrit en
    juillet 2012
    Messages
    4 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : juillet 2012
    Messages : 4 820
    Points : 9 318
    Points
    9 318
    Billets dans le blog
    5

    Par défaut

    Bonjour,

    outre le redimensionnement automatique expliqué par 78chris (j'ai juste repris sa méthode de redimensionnement pour rester sur son sujet) .... là je ne comprend plus vraiment ce que tu veux

    tes copies écran jettent encore + la confusion, car on a presque l'impression qu'il faut créer le listobject au lieu d'en redimensionner un qui existe

    Reprenons à 0 :

    1) la procédure utilise pour paramètres :

    - un tableau (array) unidimensionnel contenant des string
    - un tableau (listobject) unidimensionnel existant (??)

    2) Elle doit :

    - effacer le DataBodyRange (les données) pour les remplacer par ton Array de string ?
    OU
    - ajouter au DataBodyRange existant ton Array de string ?
    OU
    - créer un ListObject à côté du dernier ListObject de la feuille et le remplir avec le Array ?

  6. #6
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    février 2010
    Messages
    5 867
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : février 2010
    Messages : 5 867
    Points : 10 896
    Points
    10 896

    Par défaut

    Bonjour à tous

    Au vue des copies d’écrans : il n'est pas conseillé de juxtaposer des tableaux d'une colonne.

    Cela n'est pas très lisible pour l'utilisateur et n'apporte rien.

    Quelle est la finalité opérationnelle de ces tableaux ?
    Chris

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  7. #7
    Membre régulier
    Homme Profil pro
    Architecte technique
    Inscrit en
    juin 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : juin 2015
    Messages : 213
    Points : 72
    Points
    72

    Par défaut

    Citation Envoyé par 78chris Voir le message
    Bonjour

    A noter que les tableaux se "resizent" dynamiquement quand on ajoute des données sous la dernière ligne (sauf feuille protégée) on qu'on supprime des lignes...
    bjr,

    habituellement, oui, mais depuis 1 semaine cela ne veut plus fonctionner sur un tableau chez moi...
    :-(
    je ne sais pas si c'est à cause du grand nb de lignes que j'ajoute (via macro depuis un autre fichier) ???
    car quand j'en ajoute qq-unes à la main, ça fonctionne tjs...

    la solution que j'ai trouvée est de "resizer" le tableau (via macro à la suite du paste).
    et pour le faire même si le nb de colonnes du tableau change, j'ai codé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        dernierecolonne = Split(Range("a2").CurrentRegion.Address, "$")(3) 'pour avoir les lettres de la colonne et non son n°
        ActiveSheet.ListObjects("Tableau9").Resize Range("$A$2:$" & dernierecolonne & "$" & StartRow + NbLines - 1)
    ("dernierecolonne" trouvé sur https://www.developpez.net/forums/d4...ees-d-feuille/, et StartRow + NbLines - 1 = n° de dernière ligne copiée non vide dans le tableau)

    ma maigre contribution...

    bien cordt

  8. #8
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    février 2010
    Messages
    5 867
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : février 2010
    Messages : 5 867
    Points : 10 896
    Points
    10 896

    Par défaut

    Bonjour

    Le problème vient sans doute de la façon dont ton code ajoute des infos : il vaudrait mieux contrôler cela que corriger après coup.
    Chris

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  9. #9
    Membre régulier
    Homme Profil pro
    Architecte technique
    Inscrit en
    juin 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : juin 2015
    Messages : 213
    Points : 72
    Points
    72

    Par défaut

    je fais :

    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
        Workbooks.Open Filename:=HNO_FullFileName, UpdateLinks:=0
     
        Sheets("export_RDU").Select
        Application.CutCopyMode = False
     
        'suppression des filtres
        Range("A2").Select
        Selection.AutoFilter
        Selection.AutoFilter
     
        'recherche de la 1ere ligne vide
        StartRow = ActiveSheet.Columns(1).Find("*", , , , xlByColumns, xlPrevious).Row + 1
        Range("B" & StartRow).Select
        Windows(Ast_FullFileName).Activate
        Selection.Copy
        Windows(HNO_FullFileName).Activate
        ActiveSheet.Paste
    ce qui fonctionnait avant...

  10. #10
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    février 2010
    Messages
    5 867
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : février 2010
    Messages : 5 867
    Points : 10 896
    Points
    10 896

    Par défaut

    Bonjour

    Pour annuler un filtre 2 Selection.AutoFilter ne me parait pas la meilleure solution.

    De même trouver la dernière ligne d'un tableau se fait par d'autres méthodes que pour une plage.

    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
         With ActiveSheet.ListObjects(1)
            .AutoFilter.ShowAllData
            y = .ListRows.Count
        End With
    Y donne le nombre de lignes du tableau hors titre.

    On peut éventuellement ajouter une ligne et coller dedans :
    Chris

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  11. #11
    Rédacteur

    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    janvier 2010
    Messages
    8 588
    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 : 8 588
    Points : 20 276
    Points
    20 276
    Billets dans le blog
    8

    Par défaut

    Bonjour Chris,
    Au vue des copies d’écrans : il n'est pas conseillé de juxtaposer des tableaux d'une colonne.
    Cela n'est pas très lisible pour l'utilisateur et n'apporte rien.
    Je partage tout à fait ta remarque.
    Je m'apprêtais à le signaler lorsque j'ai lu ta réponse.

    Bonjour Pascal
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Set olrs = loTable.ListRows
        For i = olrs.Count To 1 Step -1
            olrs(i).Delete
        Next i
    A la place d'une boucle qui supprime toutes les lignes, j'utilise plutôt cette ligne de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    olrs.DataBodyRange.Rows.Delete
    En testant au préalable s'il y a bien des données soit avec cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Not (olrs.DataBodyRange Is Nothing) Then ...
    soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If olrs.ListRows.Count Then...
    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
    Quelques contributions : USERFORM - Créer, Consulter, Modifier et Supprimer des enregistrements à l'aide d'un formulaire - Géolocalisation d'une adresse avec Excel et Google sans VBA

  12. #12
    Membre régulier
    Homme Profil pro
    Architecte technique
    Inscrit en
    juin 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : juin 2015
    Messages : 213
    Points : 72
    Points
    72

    Par défaut

    Citation Envoyé par 78chris Voir le message
    Bonjour

    Pour annuler un filtre 2 Selection.AutoFilter ne ma parait pas la meilleure solution.

    De même trouver la dernière ligne d'un tableau se fait par d'autre méthode que pour une plage.

    ...
    re,

    je suis bien conscient que mon code est loin d'être optimal et "propre".
    j'ai lu qq part sur un forum qu'il faut oublier de se servir du mode enregistrement de macro, mais c'est la 1ere méthode que j'emploie, ensuite je cherche sur les forums et enfin je pose une question en désespoir de cause.
    je n'ai pas de formation VBA - et on ne m'enverra pas en suivre, donc je fais avec les moyens du bord, désolé...
    on n'arrête pas de me dire au boulot que passer du temps à faire/améliorer/corriger les macros c'est bien gentil, mais le boulot est plus important, donc c'est tjs à l'arrach...

    donc tout ce qui est "objet" dans VBA me semble être de l'hébreux
    même si je réalise en lisant les réponses des forums que cela a l'air d'être très performant...

    un jour, qd j'aurai du temps...

    cordt

  13. #13
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    février 2010
    Messages
    5 867
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : février 2010
    Messages : 5 867
    Points : 10 896
    Points
    10 896

    Par défaut

    Bonjour Philippe
    Citation Envoyé par Philippe Tulliez Voir le message
    Bonjour Chris,
    Je partage tout à fait ta remarque.
    Je m'apprêtais à le signaler lorsque j'ai lu ta réponse....
    En fait weyb06 s'est raccroché à un fil ancien et sa question concerne juste le non allongement automatique du tableau.

    weyb06 : je ne critique pas ton code pour le principe mais pour t'aider à éviter le problème que tu évoques. Tu demandes de l'aide, on essaie de t'en apporter mais si tu le prends mal...
    Listobject est juste le nom correspondant à Tableau (qui mal traduit depuis 2007 est une listes de données) : rien d'hébreu là-dedans...
    Comprendre qu'un Tableau, un graphique, un onglet... sont des objets Excel fait partie du B A BA si tu veux coder et même sans coder il est utile de le savoir...

    Tu pourras dire à ton boulot que le temps perdu à bidouiller "avec les moyens du bord" coûte plus cher en temps (et donc en €) qu'une formation, généralement prise en charge au moins partiellement par l'opca auquel cotise ton entreprise.
    De plus un code erroné peut créer des erreurs de calcul dans un classeur important et occasionner des problèmes parfois coûteux...
    Chris

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  14. #14
    Membre régulier
    Homme Profil pro
    Architecte technique
    Inscrit en
    juin 2015
    Messages
    213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : juin 2015
    Messages : 213
    Points : 72
    Points
    72

    Par défaut

    oui effectivement je me suis raccroché à un "vieux" fil de discussion, étant tombé dessus en faisant mes recherches et comme il n'était pas clos, j'ai voulu (pour une fois que je le pouvais!) apporter une solution.

    ce n'est pas que je le prends mal à cause de vous, loin de là, je remercie grandement ici tous ceux qui ont pris de leur temps pour me répondre d'ailleurs !

    c'est tout un ensemble qui fait que je commence à fatiguer, à cause des bugs, erreurs, "mauvaises programmations" et autres choses qui (pourquoi ???) ne fonctionnent plus du jour au lendemain, et comme vous le dîtes, font perdre bcp de temps - et surtout d'énergie...
    (il n'y a pas qu'au boulot, à la maison aussi... du coup ca commence à faire bcp...)

    je vais faire le forcing pour une formation VBA, mais comme c'est pas forcément mon cœur de métier...

    bien cordt

Discussions similaires

  1. Mécompréhension: ListObject et tableau Excel
    Par c.piette dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 08/04/2015, 16h22
  2. Réponses: 4
    Dernier message: 22/08/2014, 14h43
  3. [XL-2007] Redimensionner un tableau (ListObject) jusqu’à la dernière ligne
    Par Excel_man dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 28/04/2013, 01h17
  4. [XL-2007] Insertion ligne dans un tableau (ListObject) sur feuille protégée
    Par Damran dans le forum Conception
    Réponses: 4
    Dernier message: 22/08/2012, 16h32
  5. [XL-2010] objet Range issu d'un tableau (listobject)
    Par XBS17 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 01/10/2011, 12h18

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