Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2021 Vos avis SVP: Une fonction TRANSPOSE() à améliorer

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

p'tit vieux

XLDnaute Occasionnel
Bonjour à tous,
Pour mes codes VBA, j'ai écris une première version de ma fonction Transpose() que je vais mettre à votre disposition dans sa version 1.0.0.
Toutefois, je voudrais votre avis sur l'intérêt de rajouter des options complémentaires à celle-ci.

Dans un premier temps j'ai écris une fonction Transpose() afin de lever la limite des 65536 lignes de la fonction "WorkSheetFunctions.Transpose" d'Excel.
Pour mes besoins j'ai ajouté les possibilités suivantes:
- Choisir la base départ du tableau (Base 0 ou 1)
- Pouvoir convertir un texte/valeur simple dans un tableau 2D T(1,1)

Rien d'exceptionel, mais pratique.

Donc je vous propose de me soumettre vos idées.

Par exemple, j'ai pensé à:
- Si on transmet T(0 to 0, 0 to N) ou T(1 to N, 1 to 1) Transpose() renvoie un tableau 1D T(0 to N) ou T(1 to N) suivant la base choisie
- Transposer ET ne renvoyer que les n premieres lignes
- Transposer ET ne renvoyer de la ligne n° X à n° Y

Voilà pour ces quelques idées.
A votre avis laquelle ou lesquelles de celles-ci ont-elles un intérêt.

Et vous, vos autres idées qui vous paraitraient utiles?
Ensuite suivant vos propositions ….
Je nommerai un 1er Ministre du développement 🤣
Mais non! Je publierai une nouvelle version (Pas sérieux ces P'tit Vieux)

Merci pour vos avis et suggestions.

ATTENTION!
Ici il n'est pas question de faire des recherches de texte/valeur ou autre truc du genre.
 
Dernière édition:
Bonsoir la compagnie des inverseurs de valeurs,
La seule chose est fait elle ce qu'on lui demande bien et aussi vite que possible ?
Le reste c'est du blabla ... Sauf à trouver des bugs ou proposer une/des améliorations fonctionnelles (supplémentaires ?)
Je suis bien d'accord avec ça.
Des solutions concrètes, des propositions et des corrections si besoin de corriger des bugs dans une approche positive, constructive et collaborative.
Les critiques récurrentes systématiquement négatives de la production des autres qui induisent des justifications incessantes c'est désagréable et non productif. C'est du vent.
 
Dernière édition:
Bonjour les retourneurs de cases,
J'ai encore modifié le fichier du Post #212 pour être plus "carré" dans les commentaires relatifs au paramètre LikeExcel. C'est mon coté perfectionniste et itératif qui vous créé ces problèmes de récupérations multiples (pour ceux qui sont intéressés) , désolé.

Edit: Et encore pour simplifier le tableau des paramètres de test de la fonction
 
Dernière édition:
Bonsoir les Maîtres du salto arrière des cellules volantes,

@p'tit vieux a trouvé un bug (ce qui est quand même un exploit vu que c'est moi qui ai fait le code en toute modestie comme d'hab ! ).
En plus @p'tit vieux m'a obligé à changer le nom de la fonction, vous vous rendez compte ?

Il s'agit de WorksheetFunction.Transpose() qui, sur une valeur, retourne simplement la valeur, ce que mon code initial a raté au niveau du test.

Cette spécificité a eu quelques conséquences un peu plus importantes que prévues et a nécessité de ré-écrire certaines parties et aussi de mettre à jour les commentaires explicatifs.

Ceux qui sont intéressés à la chose peuvent retrouver le fichier modifié en Post #212
 
Je sens comme une pointe d'ironie si ce n'est du sarcasme là. 😱
Douterais tu de ma capacité à faire planter un code?
C'est que je fais de mieux 🤣

En plus @p'tit vieux m'a obligé à changer le nom de la fonction, vous vous rendez compte ? Regarde la pièce jointe 1209108
Comme pour le reste, je ne t'ai pas obligé à rien.
Pour le changement de nom, je crois que je suis encore en capable de le faire. Mais je te l'ai suggéré avec déférence et politesse.

😁😆🤣
 
Bonjour à tous les deux
ce matin je me suis dit je vais quand même essayer le post 202 (le dernier fichier fourni par @Dudu2)
je l'ai donc ouvert et glisser son module(Module_Transpose2D)dans mon fichier histoire d'avoir tout à portée de main
dans mon fichier j'ai fait un petit tableau dans le quel je vais paramétrer la creation d'un tableau 2D avec des valeurs afin de faire les tests avec des valeurs la fonction générer_table
voici ce petit tableau

je vais donc créer un table(1 to 50000, -2 to 100)
ensuite avec ma version TransposeXV3 je transposerais
et je vais transposer avec des nouvelles bases qui sont -5 pour la première dimension du tableau original et 7 pour la 2d dimension du tableau original
je dois donc à l'arrivée me retrouver avec un tableau transposé
T2(7 to 109 ,-5 to 49994)

j'ai donc ajout un bouton pour tester la fonction de @Dudu2
et je fait dans sa macro affectée le même appel qu'avec ma version 3
voici l'appel pour DUDU2

VB:
Sub test_V_DUDU2()
    Dim Avant, TiM#
    Set Rng2 = Range("tb_newbase")
    générer_table
    Avant = "Tests Version DUDU" & vbCrLf & "avant t(" & LBound(t) & " To " & UBound(t) & ", " & LBound(t, 2) & " To " & UBound(t, 2) & ")" & vbCrLf
    TiM = Timer
    Tf = Transpose2D(t, NewBase1, NewBase2)  'avec les nouvelles bases pour T donc tf sera tf(5 to x,-2 to y)
    TiM = (Timer - TiM) * 1000
   
    MsgBox Avant & vbCrLf & "Après tf(" & LBound(Tf) & " To " & UBound(Tf) & " , " & LBound(Tf, 2) & " To " & UBound(Tf, 2) & vbCrLf & vbCrLf & "Avec timer VBA *1000 :" & Round(TiM, 3) & " ms"
   
    MsgBox "contrôle de cohérence" & vbCrLf & "t(" & UBound(t) & ", " & UBound(t, 2) & ") = " & t(UBound(t), UBound(t, 2)) & vbCrLf & _
            "tf(" & UBound(Tf) & ", " & UBound(Tf, 2) & ") = " & Tf(UBound(Tf), UBound(Tf, 2))
End Sub

et voici l'appel pour ma version 3

Code:
Sub test_V_3()
    Dim Avant, TiM#
    Set Rng2 = Range("tb_newbase")
    générer_table
    Avant = "Tests TransposeXV3" & vbCrLf & "avant t(" & LBound(t) & " To " & UBound(t) & ", " & LBound(t, 2) & " To " & UBound(t, 2) & ")" & vbCrLf
    TiM = Timer
    Tf = TransposeXV3(t, NewBase1, NewBase2) 'avec les nouvelles bases pour T donc tf sera tf(5 to x,-2 to y)
    TiM = (Timer - TiM) * 1000
   
    MsgBox Avant & vbCrLf & "Après tf(" & LBound(Tf) & " To " & UBound(Tf) & " , " & LBound(Tf, 2) & " To " & UBound(Tf, 2) & vbCrLf & vbCrLf & "Avec timer VBA *1000 :" & Round(TiM, 3) & " ms"
   
    MsgBox "contrôle de cohérence" & vbCrLf & "t(" & UBound(t) & ", " & UBound(t, 2) & ") = " & t(UBound(t), UBound(t, 2)) & vbCrLf & _
            "tf(" & UBound(Tf) & ", " & UBound(Tf, 2) & ") = " & Tf(UBound(Tf), UBound(Tf, 2))
End Sub

comme vous pouvez le constatez c'est le nom de la fonction appelée qui change tout le reste es pareil
et dans les msgbox je me sert des lbound et ubound pour écrire le message

et bien testons voir

test pour dudu2


bon ben ça m'a l'air parfait ça
control de cohérence message suivant


bon ben ça m'a l'air parfait tout ca
509 ms pour 50000 sur 100
on est un peu au dessus de nos première version mais avec tout ce qui a été ajouté on va dire que c'est bien

testons voir ma version 3
ma version 3 c'est la version 2 qui a été modifiée dans ces argument
c'est a dire que mes argument lBase1 et lBase2 ne ramenne plus les bases a 0 ou 1 mais comme celle de dudu2 donne la possibilité de descendre dans le negatif et inversement
et nous allons faire ce test avec les mêmes données que le test effectué avec la version de @Dudu2

bon ben c'a m'a l'air pareil le resultat est bon
sauf que j'ai quand même quasiment 80 ms de moins
voyons voir le controle de cohérence



bon ben c'est sans surprise on est bon

et voila le code de ma fonction
et pour tout vous dire le fait d'être parti sur un changement de base au choix n'a fait qu'en réduire le code
VB:
'VERSION 3 LES BASE SONT PARAMETRABLES
'Algoritmi Divide ut imperes = divide and conquer algorithm
 'Lbase1 et lBase2 ne sont plus les repositionneur de base mais deviennent les nouvelles bases
Function TransposeXV3(t, Optional lBase1& = 0, Optional lBase2& = 0)
    'Ajout du change base V 1.2.1 -- 08/12/2024
    'patricktoulon    V 1.4 -- 13/12/2024
    'version 1.3 avec un select case
       Dim y&, i&, C&, T2(), x&, q&
    If TypeOf t Is Range Then If t.Areas.Count = 1 Then t = t.Value Else TransposeXV3 = t: Exit Function
    If Not IsArray(t) Then TransposeXV3 = t: Exit Function
    If IsEmpty(t) Then TransposeXV3 = t: Exit Function
    On Error Resume Next
    y = UBound(t, 2)
    Select Case True
        Case Err
            ReDim T2(lBase1 To UBound(t) - LBound(t) + lBase1, lBase1 To Ubd1)
            For i = LBound(t) To UBound(t): T2(lBase2 + x, lBase1) = t(i): x = x + 1: Next
            On Error GoTo 0
        Case Else
            ReDim T2(lBase2 To UBound(t, 2) - LBound(t, 2) + lBase2, lBase1 To UBound(t) - LBound(t) + lBase1)
            For i = LBound(t) To UBound(t)
                For C = LBound(t, 2) To UBound(t, 2): T2(lBase2 + q, lBase1 + x) = t(i, C): q = q + 1: Next
                    x = x + 1
                    q = 0
                Next
            End Select
        TransposeXV3 = T2
    End Function
en ce qui concerne le "like excel" comme je n'y adhère pas je ne l'ai pas fait mais c'est 2 lignes de plus
et si vous voulez je vous les donnes
juste pour info avec un dim t(1to 100000,1 to 100 je suis à 835 ms
je dépose le fichier qui a servi a faire cette démo
vous vouliez du productif , collaboratif , des propositions
messieurs vous êtes servis
et je suis resté fidèle a ma vision des choses et ma version initiale et ma façon de coder

Patrick 😉
 

Pièces jointes

Dernière édition:
juste une petite correction comme j'ai supprimé la variabilisation inutile puisque les calculs sont fait qu'une fois lors du redim
j'avais laisser une variable pour le 1D
correction:
VB:
 Case Err
            ReDim T2(lBase1 To UBound(t) - LBound(t) + lBase1, lBase1 To UBound(t))
 
Bonjour @patricktoulon,
messieurs vous êtes servis
et je suis resté fidèle a ma vision des choses et ma version initiale et ma façon de coder
C'est vrai que tu as fourni une solution avec un fichier et c'est très bien !
Et c'est vrai aussi que ton code va plus vite que le mien.
Mais est-ce que tu sais pourquoi ? Moi oui ! 😉 Et ça n'a rien à voir avec les boucles.

Benchmark en l'état:


Benchmark cause identifiée:


Ceci dit, involontairement, tu m'as apporté un enseignement sur le VBA que je vais mettre à profit pour améliorer le dernière version de Transpose2D.

Et je vais toujours un poil plus vite car il y a encore des calculs dans tes indiçages que tu pourrais d'ailleurs éviter.
 
Messieurs les Renverseurs de Tables,
Fort de l'enseignement involontairement fourni par @patricktoulon que je remercie pour ça au passage, j'ai modifié le fichier du Post #212 pour y inclure le bénéfice. Et c'est vraiment pinuts, à peine visible mais ça influe de façon relativement importante sur la performance !
 
Bonjour @Dudu2
je n'ai pas utilisé le benchmark mais simplement le timer de vba pour que les tests soient équitables
même si il y a un effet de bord mais on le subit tout les deux

en fait je vais plus vite car je ne variabilise pas inutilement

le redimensionnement ne doit être fait qu'une fois on est d’accords

pour le 1D
ReDim T2(lBase1 To UBound(t) - LBound(t) + lBase1, lBase1 To UBound(t))

pour le 2D
ReDim T2(lBase2 To UBound(t, 2) - LBound(t, 2) + lBase2, lBase1 To UBound(t) - LBound(t) + lBase1)

terminé j'ai mon tableau final

bon nous avons une 2eme détail qui nous différencie aussi
toi tu considère les argument base1 et base2 comme celle du tableau final
alors que moi lbase 1 et lbase 2 sont les nouvelles base du tableau initiale
que j'inverse uniquement dans le redim
mais ce n'est qu'un détail

c'est quoi le truc que je t'ai apporté involontairement ?
 
Dernière édition:
en fait je vais plus vite car je ne variabilise pas inutilement
Je te l'ai dit, ça n'a rien à voir avec ça. Tu n'y es pas. La cause est ailleurs et je te laisse chercher.

Corrigée (le fichier du Post #212), cette cause rend les codes à peu près équivalents sauf, comme je l'ai déjà dit, que Transpose2D va en moyenne un chouia plus vite car tes indices sont encore calculés ce qui peut être très simplement évité.

 

Pièces jointes

ben je ne vois pas on fait la même chose
toi
VB:
jtt = LB2
            For it = LBound(t, 1) To UBound(t, 1)
                itt = LB1
                For jt = LBound(t, 2) To UBound(t, 2)
                    tt(itt, jtt) = t(it, jt)
                    itt = itt + 1
                Next jt
                jtt = jtt + 1
            Next it
moi
VB:
For i = LBound(t) To UBound(t)
                For C = LBound(t, 2) To UBound(t, 2): T2(lBase2 + q, lBase1 + x) = t(i, C): q = q + 1: Next
                    x = x + 1
                    q = 0
                Next

d'ailleurs rien que la pour moi la logique c'est que LB1 ET JTT sont en fait baseout1 et baseout2 au depart
tu les a direct au départ me semble t il non
quoi je ne sais pas il faut tester
apres si c'est pas ça je ne sais pas
 
Sauf si tu changes ta boucle pour ne pas avoir d'indice calculé:
VB:
x = lBase1
            For i = LBound(t) To UBound(t)
                q = lBase2
                For C = LBound(t, 2) To UBound(t, 2): T2(q, x) = t(i, C): q = q + 1: Next
                x = x + 1
            Next
Ça sert à rien de promener lBase1 et lBase2 dans la boucle vu que ce sont des valeurs fixes.
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
2
Affichages
1 K
Réponses
1
Affichages
2 K
Réponses
18
Affichages
4 K
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…