Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissance ?

Charly88

XLDnaute Occasionnel
Bonsoir, j'ai une question générale sur les tableaux 2D.

Depuis que j'utilise des tableaux dynamiques, à deux dimensions, dans mes macros, j'ai toujours le sentiment de ne pas en comprendre la logique ligne-colonne du fait du Redim Preserve qui ne permet de rajouter une unité qu'à la dernière dimension.
Lorsque je fais un tableau excel avec 3 colonnes de caractéristiques et un nombre indéfinis de lignes comme autant de cas, je vais me localiser avec cells(n° de ligne, n° de colonne) ... Sous VBA, je traite ce même tableau avec Tab(n° de colonne, n° de ligne).
Pour un cas supplémentaire, dans le tab Excel, je "rajouterais" une unité à la première dimension, dans le tableau VBA, je la rajoute à la seconde.

Et ma pauvre tête s'emmêle parfois les pinceaux si je suis trop gourmand niveau caractéristiques-"colonnes".
Enfin, dès que je veux renvoyer mon tableau sur une feuille, je finis par un application.transpose(Tab)... C'est un détail minuscule mais que je continue à trouver "bizarre".

Est-ce un problème de ma part, ma logique de construction ou de compréhension de construction qui n'est pas bonne ?
 

Dranreb

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Bonsoir
Non, non, j'ai toujours trouvé et continue de trouver bizarre que ce soit la dernière dimension qui puisse être redimensionnée !
Il n'y a qu'une explication à cela: les tableaux VB sont organisés transposés en mémoire. Ou plutot: c'est la première dimension et non la dernière qui explore les éléments contigus, la suivante les table contigües de dimension 1ère, enfin la dernière accède aux "grands tableaux" définis par les dimensions précédentes. C'est comme ça. Ce n'est pas toujours nécessaire pour autant de travailler sur un tableau transposé du résultat dont on ne connait pas à l'avance le nombre de lignes. Une fonction personnalisée destinée à être appelée en formule matricielle peut rendre un tableau plus grand que la plage Application.Caller, ça ne gène pas.
Cordialement
 

Misange

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Bonjour
Oui c'est assez perturbant. Il faut admettre que la logique excellienne n'est pas toujours intuitive.
En pratique tu dois transposer de façon à ce que la dimension à redimensionner (joli !) soit en dernier puis tu retransposes pour mettre dans la feuille...
Quelques pages sur ce sujet
Ce lien n'existe plus
 

Efgé

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Bonjour Charly88, Dranreb, Misange, le fil, le forum
J'ai une vision très "personnelle" de ce problème que je laisse à votre apréciation.
Un tableau à une dimention de type
VB:
dim Tablo(1 to 3)
donne une seule ligne de 3 colonnes.
Un tableau à deux dimentions
VB:
Dim Tablo(1 To 3, 1 To 5)
donne un tableau "en mémoire" de 3 lignes sur 5 colonnes.
Si l'on déclare
VB:
Tablo(1,5)= "Toto"
, on se place bien sur la 1er ligne en colonne 5.
Donc, on redimentionne les colonnes et non les lignes. Le redimentionnement interviens souvent quand on ne connai pas le nombre de lignes final du tableau. On ajoute des colonnes en "mémoire" et,au final, on transpose le tableau pour retomber sur nos pattes.

Enfin, c'est comme ça que le concois...

Cordialement
 

Dranreb

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

En quoi cela justifie que Visual Basic range en emplacements contigus en mémoire les données d'une même colonne au lieu de celles d'une même ligne comme lorsqu'il n'y en a qu'une ?
À+
 

Efgé

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Re
Je m'explique,
Toujours "pour moi", il me semble que la dernière dimention représente les colonnes. Dans un tableau à une dimention, la dernière est la première....
Faire
VB:
Dim Tablo(1 To 3)
Reviens à
VB:
Dim Tablo(1 To 1, 1 To 3)
.
Je ne sais pas si mon explication est claire.... ...ni très "accadémique".
Cordialement
 

Dranreb

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Eh bien oui donc Dim Tablo(1 to 2, 1 to 3) devrait être un tableau de 2 fois 1 to 3 et pas de 3 * 1 to 2 comme c'est le cas au vu de son rangement en mémoire
Cordialement.
 

Misange

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Un tableau à une dimention de type
VB:
dim Tablo(1 to 3)
donne une seule ligne de 3 colonnes.
Ce n'est pas tout à fait exact :
si je te dis
lundi, mardi, mercredi...
je crée un array mais il n'y a dans ce cas d'un tableau à une seule dimension aucune notion de ligne ou de colonne. C'est une simple liste. Tu te réfères à la position de l'élément dans la liste et redimensionner ce type d'array est intuitif.
Un tableau à deux dimentions
VB:
Dim Tablo(1 To 3, 1 To 5)
donne un tableau "en mémoire" de 3 lignes sur 5 colonnes.
Si l'on déclare
VB:
Tablo(1,5)= "Toto"
, on se place bien sur la 1er ligne en colonne 5.
Donc, on redimentionne les colonnes et non les lignes.

Dans ton exemple il n'y a pas de problème de redimensionnement ! tu parles de la position d'un élément simplement.
Le redimentionnement interviens souvent quand on ne connai pas le nombre de lignes final du tableau. On ajoute des colonnes en "mémoire" et,au final, on transpose le tableau pour retomber sur nos pattes.

Le problème ne se pose pas dans ton exemple : si tu veux effectivement changer le nombre de colonnes; tu peux redimensionner l'array sans le transposer parce que la dernière dimension de ton array ce sont des colonnes.

Code:
Sub redimarray2D()
Dim Tblo() As Integer 'l'array est déclaré et dimensionné de façon dynamique
Dim a As Integer
Dim i As Integer, j As Integer

ReDim Tblo(3, 3) 'au premier redimensionnement, on définit les limites des deux dimensions
'remplissage d'un array de 9 éléments (3x3)

For j = 1 To 3
    For i = 1 To 3
        a = i * 10 + j
        Tblo(i, j) = a
    Next i
Next j
'on étend cet array dans une de ses dimensions pour lui ajouter 6 nouveaux éléments (3x2)

For j = 4 To 5
'la boucle extérieure est celle de la dimension qui varie (la dernière de l'array)
    ReDim Preserve Tblo(1 To 3, 1 To j)
    For i = 1 To 3
        a = i * 10 + j
        Tblo(i, j) = a
    Next i
Next j
End sub

Mais on veut très souvent augmenter le nombre de lignes, voire le nombre de lignes ET de colonnes.
Tu ne pourrais pas dans l'exemple précédent le faire sans transposer ton tableau de façon à ce que les lignes (i) représentent le 2° élément de ton array.
Ca oblige effectivement à une petite gymnastique...

par exemple pour redimensionner les deux dimensions de l'array, on doit passer par un array temporaire :

Code:
Sub redimarray2D_en2D()

Dim Tblo() As Integer
Dim Tmp() As Integer
Dim a As Integer
Dim i As Integer, j As Integer

ReDim Tblo(3, 4)
For i = 1 To 3
    For j = 1 To 4
        a = i * 10 + j 'c'est juste pour avoir des valeurs dans l'array pour l'exemple !
        Tblo(i, j) = a
    Next j
Next i

ReDim Tmp(3, 4) 'on dimensionne l'array temporaire à la même dimension que l'array initial
'on copie l'array de départ vers l'array temporaire
Tmp = Tblo


'redimensionner l'array initial (ce qui le détruit)
ReDim Tblo(5, 7)
'le remplir avec les données stockées dans l'array temp

'les deux arrays n'ayant pas les mêmes dimensions on ne peut pas cette fois copier l'un vers l'autre globalement
'il faut faire cela élément par élement
For i = LBound(Tmp, 1) To UBound(Tmp, 1)
    For j = LBound(Tmp, 2) To UBound(Tmp, 2)
        Tblo(i, j) = Tmp(i, j)
    Next j
Next i

'ajouter les nouvelles données
For i = 1 To 5
    For j = 5 To 7
        a = i * 100 + j
        Tblo(i, j) = a
    Next j
Next i
For i = 4 To 5
    For j = 1 To 4
        a = i * 100 + j
        Tblo(i, j) = a
    Next j
Next i
end sub
 

Efgé

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Re à tous,
Donc, on redimentionne les colonnes et non les lignes.
J'ai effectivement utilisé un (trop grand) raccourci, pour dire qu'en redimentionnant la seconde dimention du tableau, on redimentionne les colonnes . Ce n'était pas assez clair, je le confesse :D
Merci pour la demonstration de l'agrandissement des deux dimentions, ça me sera surement utile un jour ou l'autre.
Cordialement
 

kjin

XLDnaute Barbatruc
Re : Tableau dynamique 2 dimensionsPreserve, "inversion" ligne-colonne : méconnaissa

Bonjour,
Un tableau peut avoir jusqu'à 60 dimensions,...c'est rare j'en conviens, Ce lien n'existe plus...et je pense qu'il s'agit avant tout de savoir comment organiser les données du tableau
Si le tableau compte plusieurs dimensions et si on souhaite en préserver le contenu, seule la taille d'une seule dimension sera modifiable...la dernière
A+
kjin
 

Discussions similaires

Statistiques des forums

Discussions
312 176
Messages
2 085 961
Membres
103 066
dernier inscrit
bobfils