Bonjour,
Je dispose d'un tableau structuré (T_Visiteurs) de 27 colonnes.
Je souhaite ne transférer, dans une variable tableau, qu'une douzaine de ces colonnes.
Quel serait, selon vous, la meilleure méthode?
Merci
Bonjour,
Je dispose d'un tableau structuré (T_Visiteurs) de 27 colonnes.
Je souhaite ne transférer, dans une variable tableau, qu'une douzaine de ces colonnes.
Quel serait, selon vous, la meilleure méthode?
Merci
Cordialement,
Franck
Salut Franck,
Je vois trois solutions:
- Copie intégrale du tableau structuré dans un nouveau tableau structuré, suppression des colonnes puis transfert vers l'array (suppose une structure Excel pour accueillir le tableau temporaire );
- Transfert vers un array temporaire avec toutes les colonnes, puis transfert par boucle sur un array final en ne prenant que les colonnes qui t'intéressent dans l'array temporaire;
- Bouclage sur les lignes du tableau structuré source et alimentation de l'array en boucles en ne reprenant que les colonnes qui t'intéressent (Lourd si gros tableau structuré).
Pour généraliser l'approche et permettre un temps de traitement raisonnable sur un gros tableau structuré, je privilégierais l'approche 2.
Avec le tableau structuré suivant, voici un code qui devrait te donner satisfaction, utilisant une fonction générique qui reçoit le tableau structuré et un array (de base 0) qui contient la liste des colonnes à garder.
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 Function getPartialArray(ls As ListObject, Columns) Dim temp Dim r As Long, c As Long temp = ls.DataBodyRange.Value ReDim t(1 To UBound(temp), 1 To UBound(Columns) + 1) For r = 1 To UBound(temp) For c = 0 To UBound(Columns) t(r, c + 1) = temp(r, ls.ListColumns(Columns(c)).Index) Next c Next r getPartialArray = t End Function Sub Test() Dim t t = getPartialArray(Range("t_Contacts").ListObject, VBA.Array("Prénom", "Service")) End Sub
"Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
---------------
Mes billets de blog sur DVP
Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
---------------
Bonjour,
Je suppose qu'évidemment les colonnes à charger en variable tableau ne se suivent pas.
Personnellement, je ferais cela en deux temps
- Utilisation du filtre avancé d'excel (AdvancedFilter) sans critère et avec une zone d'exportation contenant les étiquettes de colonnes à exporter
- Chargement de la zone exportée dans la variable tableau
ou bien peut-être le Power Query
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
Philippe, Pierre,
Merci de vos réponses.
Je vais tester ça, mais, à priori, serais plus "orienté" vers la solution 1 de Pierre ou celle de Philippe (finalement sensiblement identiques).
Pour tout vous dire, j'étais parti sur une idée plus "Range classique" (un peu dans l'idée 2 de Pierre), comme suit :
Mais, ce qui me dérange dans cette méthode, c'est l'abandon de l'utilité des tableau structurés, à savoir les noms de colonne...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 Const COL_ENTETE As String = "1;2;3;4;5;6;7;11;12;14;17;20" Dim TblDatas, entetes TblDatas = LObj.DataBodyRange.Value For i = 0 To UBound(entetes) For j = LBound(TblDatas, 1) To UBound(TblDatas, 1) Debug.Print TblDatas(j, entetes(i)) 'Avec dans l'idée de stocker ça dans une variable tableau Next Next
Avec ma solution, on ne peux pas insérer ni supprimer de colonnes. Ça reste figé.
Donc, je vais voir vos solutions.
Pas besoin de retour, je pense que ce sujet est résolu.
Cordialement,
Franck
Finalement, je suis parti sur l'idée de Pierre, avec sa fonction getPartialArray.
J'y ai juste ajouté un paramètre pour pouvoir séparer la ligne d'entêtes du DataBodyRange, etc...
Comme suit :
Code d'appel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 Function getPartialArray(ls As ListObject, temp, Columns) 'https://www.developpez.net/forums/d2091033/logiciels/microsoft-office/excel/transfert-certaines-colonnes-tableau-structure-vers-variable-tableau/#post11618243 Dim r As Long, c As Long ReDim t(1 To UBound(temp), 1 To UBound(Columns) + 1) For r = 1 To UBound(temp) For c = 0 To UBound(Columns) t(r, c + 1) = temp(r, ls.ListColumns(Columns(c)).index) Next c Next r getPartialArray = t End Function
ça m'épargne une feuille de stockage des entêtes pour la solution de Philippe.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Const COL_ENTETE As String = "ID;Date début;Date fin;Nom;Prénom" Dim TblEntete, TblDatas, t t = Split(COL_ENTETE, ";") TblEntete = getPartialArray(LObj, Range(LObj.Name & "[#headers]").Value, t) TblDatas = getPartialArray(LObj, LObj.DataBodyRange.Value, t)
Note : j'y viendrais peut-être un jour car cela permet de s'affranchir d'éventuelles modifications du code "en dur"...
Merci encore à tous deux.
Cordialement,
Franck
Bonjour le Fil,
Le fait de nommer Columns le dernier argument de la fonction ne risque-t'il pas de créer une ambigüité avec le Columns de la feuille active ?
Cordialement,
Patrice
Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.
Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur
Salut Patrice
Non, la variable locale est prioritaire. Le VBA va "au plus près" pour trouver de quoi on parle. Lorsque cette variable n'existe pas dans le projet VBA (procédure puis module de la procédure puis autre module public), le VBA cherche dans les bibliothèques si quelque chose du même nom existe et s'arrête sur la première occurrence trouvée, je pense dans l'ordre d'inclusion des bibliothèques. Or, les bibliothèques pour le VBA d'Excel sont d'abord la bibliothèque VBA (c'est normal) puis la bibliothèque Excel. VBA n'exposant pas de propriété Columns dans son modèle objet, le VBA va fouiller dans le modèle Objet Excel qui est écrit de façon à ce que sans préfixe, Columns pointe vers la feuille de travail active (si la feuille active est une feuille de travail!).
Heureusement d'ailleurs, car il serait impossible de devoir tenir compte de tout ce qui est nommé dans les librairies d'un projet avant de nommer nos propres variables. La bonne pratique ( mais je ne la suis pas, en tout cas pas toujours), serait de préfixer systématiquement les propriétés des objets auxquelles elles se rattachent, et donc d'utiliser ActiveSheet.Columns, et normalement en ayant vérifié que la feuille active est bien une worksheet. D'ailleurs, en l'absence d'une variable Columns dans la hiérarchie des portées de variables, on pourrait avoir un bug avec Columns.Count si la feuille active n'est pas une feuille de travail, mais une feuille de graphique
Comme dit plus haut, sans préfixe, le code va au plus près, c'est-à-dire d'abord dans la procédure, puis dans le module, puis dans un autre module standard (si une seule variable Columns a été déclarée Public, sinon une erreur de compilation est levée)
Au plus près => dans la procédure
Au plus près => dans le module contenant la procédure
Au plus près => dans un autre module standard
D'ailleurs, on pourrait avoir une variable Columns As Public dans plusieurs modules standard, comme d'ailleurs plusieurs procédures nommées de façon identique dans différents modules standard. Ca ne pose pas de problème, il suffit de les préfixer du nom du module. C'est une technique que j'utilise souvent dans mes développements, en tout cas pour les procédures et fonctions (pas pour les variables publiques).
Il faut savoir qu'un module standard n'est jamais qu'un module de classe statique (non instanciable, on ne sait pas faire pointer un objet vers lui) et que, normalement, on devrait préfixer les variables du nom du module [de classe] qui les contient...
Si, dans un projet, on a plusieurs variables du même nom dans des modules différents, une procédure ne possédant pas de variable de ce nom et se trouvant dans un module qui lui non plus ne possède pas de variable de ce nom ne peut pas utiliser la variable sans la préfixer du module dont elle dépend.
Enfin, même si l'on conçoit que ce soit déconseillé, on pourrait avoir dans une procédure une variable Columns dans un module qui possède une variable Columns. Cedernier cas est évidemment un cas d'école.
"Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
---------------
Mes billets de blog sur DVP
Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
---------------
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager