Un tab VBA à 2 dim rempli par un tab VBA à 1 dimension

Bonsoir,

je cherche à remplir un tableau sous VBA à deux dimension par l'intermédiaire d'un tableau VBA à une dimension.

J'imagine une boucle, à la première rotation les deux tableaux ont la même taille, mais à partir de la deuxième rotation, le deuxième tableau acquière sa deuxième dimension, afin de se retrouver avec un tableau représentant une plage à deux dimension.

Le premier tableau est une récupération de 5 valeurs se trouvant sur une ligne allant de la colonne B à F

Sur le fichier joint, ces lignes sont les unes sous les autres mais en fait dans la réalité c'est la même ligne, mais des calculs interviennent entre temps et la ligne de valeurs change à chaque rotation...

En J14 le transfert du tablo1, ceci fonctionne, à chaque tour il y a bien les nouvelles valeurs.

En J15 et lignes inférieures, on devrait retrouver un équivalent de la zone des colonnes B à J.

Comment faut-il faire ?

Le passage par le premier tableau Est-ce une bonne idée ?

Ne faut-il pas prendre les données directement sur la feuille pour les mettre dans le tablo2 ?

En plus je m'aperçois que les données source ne sont pas en ligne mais en colonne, par contre le résultat sera en ligne lors du ransfert du tablo2 sur la feuille, à quel moment utiliser le "transpose" ?

Merci par avance.

Le fichier :

@ bientôt

LouReeD

Salut LouReed,

à priori, j'utiliserais un seul tableau avec REDIM PRESERVE mais comment se passe le recalcul de tes valeurs? Lors de la même boucle en fonction de l'itération, j'imagine?

A+

Bonsoir,

merci pour la réponse, en fait j'ai une feuille avec une plage de calcul qui abouti à une colonne de résultat.

Ces calculs sont fait suite à un filtrage de données.

La boucle sert à filtrer les données en fonction d'une suite de critère, du coup la plage de calcul "calcule" est la colonne de résultat se met à jour, cette liste de résultat je souhaite la mettre dans un tableau, qui se remplis au fur est à mesure, et à la fin du traitement je transfert ce tableau VBA sur une plage de cellule de la feuille "résultat".

A l'heure actuelle je remplis la feuille résultat au fur et à mesure de la boucle mais cela dure plusieurs secondes, alors l'idée de tout (presque) faire sous VBA m'est venue, je suis partie sur l'idée de deux tableau pour "gagner" du temps lors de la récupération de la colonne de résultat... Mais sinon si un seul tableau est possible alors pour quoi pas, mais je crois que sur les tableaux VBA le redim preserve ne fonctionne que sur la dernière dimension donc le tableau aurait la forme tablo(nombre de colonne = 17, nombre de ligne variable)

et du coup je suis en "transpose" au niveau des données... non ?

Merci encore

@ bientôt

LouReeD

Re,

comme ceci?

Un double-clic démarre la macro...

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
'
Dim tData()
'
Cancel = True
For x = 0 To 19
    iIdx = iIdx + 1
    ReDim Preserve tData(5, iIdx)
    For y = 1 To 5
        Cells(y, 2) = y + x
        tData(y - 1, iIdx - 1) = Cells(y, 2)
    Next
Next
Range("J14").Resize(UBound(tData, 2), UBound(tData, 1)).Value = WorksheetFunction.Transpose(tData)
'
End Sub

A+

Bonjour LouReeD, curulis57,

mais je crois que sur les tableaux VBA le redim preserve ne fonctionne que sur la dernière dimension

tu pourrais inverser le tablo pour l'alimenter puis ré-inverser le tableau

Sheets("Feuil1").[A1].Resize(UBound(tablo)) = Application.Transpose(Application.Transpose(tablo))

Bonjour LouReed, Salut à tous !

Le premier tableau est une récupération de 5 valeurs se trouvant sur une ligne allant de la colonne B à F

Sur le fichier joint, ces lignes sont les unes sous les autres mais en fait dans la réalité c'est la même ligne, mais des calculs interviennent entre temps et la ligne de valeurs change à chaque rotation...

Si je comprends bien, tu recalcules une ligne pour en ajouter à chaque fois les valeurs à un tableau et affecter le tableau ensuite...

J'en déduis que tu dois déclencher un recalcul après chaque récupération (un des problèmes éventuels sera que le recalcul soit achevé avant prélèvement suivant de valeurs...)

Dans cette hypothèse, tu devrais avoir un nombre de recalculs fini, donc une boucle comportant un nombre de tour égal au nombre de recalculs ?

Je suggère pour le prélèvement un tableau dynamique à une dimension, une variable (Integer) à la fois variable de boucle et d'incrémentation du tableau [encore que dans l'hypothèse d'un nombre de recalculs fini, le tableau peut être prédimensionné au nombre de recalculs -1 !], et une variable Range.

Tu affectes ta ligne de 5 valeurs à une variable Range (qui répercutera les modifications de valeurs à chaque recalcul). Que le tableau soit incrémenté au fur et à mesure ou préalablement dimensionné tu affectes à chaque tour les valeurs de la plage à un élément du tableau. Le résultat est un tableau à une dimension contenant des tableaux (les lignes...). Un tel tableau s'affecte à une plage par double transposition.

Sub Test()
    Dim tablo(), n%, plage As Range
    Set plage = ActiveSheet.Range("B1:F1")
    For n = 0 To nbRecalculs - 1
        ReDim Preserve tablo(n)
        tablo(n) = plage.Value
        'ici instructions de Recalcul
    Next n
    ActiveSheet.Range("J15").Resize(n, 5).Value = WorksheetFunction.Transpose( _
     WorksheetFunction.Transpose(tablo))
End Sub

J'ai conservé ici l'incrémentation dans la boucle, mais si le nombre de recalculs est prédéfini, la boucle aussi, et le tableau peut être dimensionné au départ...

Cordialement.

curulis57 bonsoir,

j'ai testé ce jour sur le fichier original ta structure, est avec 250 rotation sur 17 colonnes, cela mettait à la louche 15 secondes sur mon poste... Merci tout de même.

Merci @ vous sabV pour l'idée de la double transpose

Maréchal, je viens de tester votre code sur 17 colonnes et 250 rotations et à la louche cela prend entre 1.5 et 2 secondes !

Adjuger ! Merci à vous et en fait c'est ce que je ne savais pas traduire en VBA, mais votre idée de plage nommée d'une ligne qui en fait est un tableau à une dimension pour l'inscrire dans le deuxième tableau, et bien oui c'est ce que je cherchais à faire en me doutant que ce serait la solution la plus rapide, mais impossible de le faire.

Tout ceci pour résoudre un des obstacle à ma futur création d'application ! Merci encore.

Par contre le tableau final est dans le même sens que la ligne de départ... Et comme dit à la fin de mon premier message, les 17 valeurs sont en colonnes, et là je cale encore, de plus les valeurs de la plage sont en alphanumérique...

@ bientôt

LouReeD

Bonjour à tous,

@LouReeD

dit moi si ça convient,

j'ai ajouté une simulation temporaire de recalcul pour le test

Salut LouReed !

As-tu fait une double transposition ?

Bonsoir,

avec le bouton bleu, j'ai mis en place le code du Maréchal, et cela fonctionne très bien, à peine deux secondes.

Avec le bouton rouge et la zone rouge et des valeurs alphanumériques, en essayant d'adapter le code, je me retrouve avec une incompatibilité de type lors du "collage" final du tableau...

Le fichier :

@ bientôt

LouReeD

Salut LouReed,

Bien le bonjour MFerrand, sabV,

merci, MFerrand! J'ignorais que l'on pouvait adresser un tableau de 1 dimension de cette manière! Très, très intéressant!

Si j'ai bien compris... 0,3 sec pour 1 boucle de 250 X 17 lignes...

La macro démarre sur un double-clic.

Dim tData(), rCel As Range
'
Cancel = True
Application.ScreenUpdating = False
'
Set rCel = Range("B1:B17")
'
For x = 0 To 250
    For y = 1 To 17
        Cells(y, 2) = Split(Columns(y + x).Address(ColumnAbsolute:=False), ":")(1)
    Next
    ReDim Preserve tData(x)
    tData(x) = WorksheetFunction.Transpose(rCel.Value)
Next
Range("J15").Resize(x, 17).Value = WorksheetFunction.Transpose(WorksheetFunction.Transpose(tData))
'
Application.ScreenUpdating = True

A+

9pb-loureed.xlsm (25.30 Ko)

Bonsoir curulis57,

et merci @ vous trois !

Le résultat est là et il fait 0.7 seconde sur ma machine...

Après les vacances je vous tiens au courant du fonctionnement sur le fichier original...Et la machine qui va avec !

Reste à voir combien de temps prendront les calculs intermédiaire qui sont à base de filtre dans un tableau...

Un grand merci au Maréchal et à très bonne participation de curulis57 et sabV !

@ bientôt

LouReeD

Re à tous !

J'ai perdu le fil, je dois fatiguer... Je ne vois plus quelle plage doit être récupérée et dans quel sens elle doit se retrouver dans le tableau final...

Si ça marche tant mieux ! A l'occasion tu me diras si tu as un peu de temps... Bonnes vacances.

re,

voici mon test avec la nouvelle version,

Bonjour,

plus de soucis de mon coté, j'ai un code qui fonctionne.

Maréchal, vous n'êtes pas fatigué, c'est moi qui n'a pas su faire la bonne demande

En fait la plage à recopier 250 fois dans un tableau qui s'agrandi au fur et à mesure (car en fait le 250 est variable) est verticale, par contre chaque plage copiée doit être affichée horizontalement ensuite.

Voilà sauf erreur d'appréciation le code de curulis57 fonctionne.

Il me reste plus qu'à le tester sur la machine "officielle" !

Merci @ tous

@ bientôt

LouReeD

Hello !

Là j'en suis à la phase réveil en douceur après tidéjeuné mais encore au premier café qui suit : pas encore prêt pour des manipulations complexes mais je peux retrouver le point où les choses m'avaient échapé, noté que ta ligne à récupérer était une colonne, mais c'est ensuite que je ne ne savais plus si elle restait colonne ou devenait ligne...

@+

Salut MFerrand,

bienvenue dans le monde des Eveillés!

C'est un grand mystère et une grande découverte pour moi cette possibilité d'adresser un tableau à une dimension avec une plage de valeurs!

Je vais creuser cela et très certainement y trouver une tripotée d'applications!

Grand merci pour tes lumières!

A+

Salut Curulis,

En effet, cela a de multiples applications, et je n'en ai pas encore fait complètement le tour...

Je n'ai rien inventé, j'avais trouvé une allusion en circulant, il y a pas mal de temps, trouvé l'idée intéressante, fait quelques essais, infructueux... et je n'avais pas poursuivi. Jusqu'à il y a environ un an où un demandeur s'essayait à opérer ainsi sans y parvenir à partir d'un tuto qu'il avait trouvé...

Le tuto dont je n'ai pas gardé les références étant relativement plus complet, j'ai pu trouver les points où je faisais fausse route...

La méthode décrite consistait en :

  • prélèvement en tableau de la plage source (affectation d'une plage à une variable Variant qui produit un tableau VBA à 2 dimensions,
  • parcours de ce tableau pour repérer les lignes répondant aux conditions cherchées, et prélèvement de ces lignes entières en utilisant INDEX, pour les affecter à un tableau unidimensionnel incrémenté au fur et à mesure,
  • affectation du tableau à une plage par double transposition.

Adaptation si tu prèlèves directement à partir de la plage source sans passer par un tableau, pas besoin d'utiliser INDEX, le prélèvement fonctionne de la même façon que l'affectation d'une plage à une variable Variant.

Mais dans le cas général de parcours d'une plage, passer par l'intermédiaire d'un tableau présente des avantages car plus rapide, et la fonction INDEX offre le cas échéant des possibilités supplémentaires.

Supposons que tu affectes une plage dont tu dois extraire des lignes sous condition à une variable aa. Tu parcours le tableau produit.

For i = 1 To UBound(aa)  'ou à partir de 2 si tu as une en-tête
    If aa(i, x) = Condition Then 'x=colonne testée pour la condition
        Redim Preserve Tablo(n) 'Tablo=tableau dynamique de résultats à 1 dimension, n variable d'incrémentation
        Tablo(n) = WorksheetFunction.Index(aa, i, 0) 'Index renvoie la matrice ligne entière en mettant l'index colonne à 0
        n = n + 1
    End If
Next i

Possibilités supplémentaires offertes par Index : supposons que tu doives prélever sur la ligne seulement les colonnes (au hasard !) : 1, 3, 9, 5 dans cet ordre :

        Tablo(n) = WorksheetFunction.Index(aa, i, Array(1, 3, 9, 5))

va te renvoyer exactement la ligne que tu veux obtenir comme résultat.

Bonne journée à toi.

Rechercher des sujets similaires à "tab vba dim rempli dimension"