OVH Cloud OVH Cloud

BVA Trier un tableau "array"

18 réponses
Avatar
Adrien Delcour
Bonjour =E0 tous.
J'=E9cris une macro qui devrait trier un tableau, le mot=20
tableau =E9tant pris au sens abstrait de l'anglais "array"=20
et non au sens concret de l'anglais "table". Il s'agit=20
donc d'une variable d=E9clar=E9e avec des parenth=E8ses.
La seule chose que j'aie trouv=E9e est la commande=20
WordBasic.SortArray, qui est indiqu=E9e dans la rubrique=20
d'aide "Equivalents Visual Basic des commandes Word Basic"=20
(=E0 la lettre T dans Word 2000 et =E0 la lettre S dans Word=20
2002...). Mais je ne parviens pas =E0 trouver de la=20
documentation sur cette fonction : quelle est sa syntaxe,=20
comment pr=E9cise-t-on l'ordre de tri (croissant ou=20
d=E9croissant)...? Quelqu'un pourrait-il soit me dire=20
comment on se documente sur cette fonction, soit m'en=20
indiquer une autre ? (Il me semble exclu de passer par un=20
tableau visuel - "table" en anglais.)
Merci d'avance.

10 réponses

1 2
Avatar
Pascal Engelmajer
--
Amicalement.
Pascal
"il n'y a pas de vent favorable pour celui qui ne sait pas ou il va."
Sénèque.
http://www.ilyapa.net/excel
"Adrien Delcour" a écrit dans le
message de news: 063701c3c92b$c3e8b390$
Bonjour à tous.
J'écris une macro qui devrait trier un tableau, le mot
tableau étant pris au sens abstrait de l'anglais "array"
et non au sens concret de l'anglais "table". Il s'agit
donc d'une variable déclarée avec des parenthèses.
La seule chose que j'aie trouvée est la commande
WordBasic.SortArray, qui est indiquée dans la rubrique
d'aide "Equivalents Visual Basic des commandes Word Basic"
(à la lettre T dans Word 2000 et à la lettre S dans Word
2002...). Mais je ne parviens pas à trouver de la
documentation sur cette fonction : quelle est sa syntaxe,
comment précise-t-on l'ordre de tri (croissant ou
décroissant)...? Quelqu'un pourrait-il soit me dire
comment on se documente sur cette fonction, soit m'en
indiquer une autre ? (Il me semble exclu de passer par un
tableau visuel - "table" en anglais.)
Merci d'avance.
Avatar
Pascal Engelmajer
salut,
il existe plusieurs manières de trier :
Sub BubbleTri(tabTri)
'algorithme de tri (type BubbleSort) pour des petits tableaux
'restitue le tableau trié

Dim I%, J%, K%, tmp

For I = LBound(tabTri) To UBound(tabTri)
J = I
For K = J + 1 To UBound(tabTri)
If tabTri(K) <= tabTri(J) Then J = K
Next K
If I <> J Then
tmp = tabTri(J): tabTri(J) = tabTri(I): tabTri(I) = tmp
End If
Next I
End Sub

'==========================
Option Explicit
Type pile 'pour QuickSort
mini As Integer
maxi As Integer
End Type
Dim t(1 To 250) As Integer

Sub quicksort()
Dim tMoyen As Long
Dim iPile As Long
Dim mini As Long
Dim maxi As Long
Dim moyen As Long
Dim borne1 As Long
Dim borne2 As Long
Dim tt As Long
Dim i As Long
Dim pile(1 To 128) As pile
iPile = 1
pile(iPile).mini = 1 'Premier indice du tablaeu
pile(iPile).maxi = UBound(t) 'Dernier indice du tableau
iPile = iPile + 1 ' pour que iPile, à la première itération du do, soit
égal à 1

Do
iPile = iPile - 1 'la pile diminue et le programme tri récursivement
les parties non triées
mini = pile(iPile).mini ' au départ 1
maxi = pile(iPile).maxi ' au départ à la dimension du tableau
Do
borne1 = mini
borne2 = maxi
moyen = (mini + maxi) 2 'recuperer la valeur au milieu du
tableau
tMoyen = t(moyen)
Do
Do While t(borne1) < tMoyen 'recherche d 'un element plus
grand
borne1 = borne1 + 1
Loop

Do While t(borne2) > tMoyen 'recherche d 'un element plus
petit
borne2 = borne2 - 1
Loop
If borne1 <= borne2 Then
'si les deux pointeurs ne se rencontrent pas
'permutation des elements designés par les pointeurs
tt = t(borne1)
t(borne1) = t(borne2)
t(borne2) = tt
borne1 = borne1 + 1
borne2 = borne2 - 1
End If
Loop While borne1 <= borne2 'si les pointeurs se chevauchent,
'arrêt de la boucle

If borne2 - mini < maxi - borne1 Then
'stockage dans la pile de la partie de tableau non triée
'on pourrait utiliser un appel récursif de quicksort en
remplaçant
'la procédure quicksort par une fonction
'quicksort(borneInf, borneSup) et éviter ainsi la gestion de
la pile et de la récursivité
'ça enlèverait du piment au programme
If borne1 < maxi Then
pile(iPile).mini = borne1
pile(iPile).maxi = maxi
iPile = iPile + 1 'la pile augmente
End If
maxi = borne2
Else
If mini < borne2 Then
pile(iPile).mini = mini
pile(iPile).maxi = borne2
iPile = iPile + 1 'la pile augmente
End If
mini = borne1
End If
Loop While mini < maxi
Loop While iPile <> 1
End Sub
'====================================== très simple de eric.rbt
Public Sub Trier_Tableau(ByVal LimiteInf As Integer, ByVal LimiteSup As
Long)
' cette procedure trie le tableau "Produit" dans l'ordre croissant
'syntaxe d'appel : call
Trier_Tableau(Nr_Premier_Enregistrement,Nr_Dernier_Enregistrement)
' en sortie la table (Produit) est triée dans l'ordre croissant

Dim i As Integer, j As Long
Dim Inter As Long
Dim transit As Long
Dim CTR As Long

i = LimiteInf 'Premier indice de ton tableu
j = LimiteSup 'dernier indice du tableau


transit = Produit((LimiteInf + LimiteSup) / 2) 'recuperer
la valeur au milieu du tableau

Do 'recherche
d'un element plus grand
Do While Produit(i) < transit
i = i + 1
Loop
'recherche
d'un element plus petit
Do While transit < Produit(j)
j = j - 1
Loop
'si les deux
pointeurs ne se rencontrent pas
'permutation
des elements designés par les pointeurs
If i <= j Then

Inter = Produit(i)
Produit(i) = Produit(j)
Produit(j) = Inter

i = i + 1
j = j - 1
End If
'si les
pointeurs se chevauchent, arret de la boucle
Loop Until i > j
'appel
récursif de l'algorithme de tri pour la partie de tableau nom trié
If LimiteInf < j Then
Call Trier_Tableau(LimiteInf, j)
End If
If i < LimiteSup Then
Call Trier_Tableau(i, LimiteSup)
End If
End Sub
//================== pour finir un exemple avec un tableau à deux dimensions
Dim tb(0 To 20, 0 To 1) As Variant
Sub test()
Dim i As Integer
For i = 0 To 20
tb(i, 0) = Int((100 * Rnd) + 1)
tb(i, 1) = Chr(i + 64)
Next i
Debug.Print "============ avant le tri ======================"
For i = 0 To 20
Debug.Print tb(i, 0) & " " & tb(i, 1)
Next i
Debug.Print "============ après le tri ======================"
Call tri(LBound(tb), UBound(tb))
For i = 0 To 20
Debug.Print tb(i, 0) & " " & tb(i, 1)
Next i
End Sub
Public Sub tri(ByVal tInf As Integer, ByVal tSup As Long)
' cette procédure tri le tableau "tb" dans l'ordre croissant
' appel : call tri(bInf,bSup)
' le tableau (tb) est triée dans l'ordre croissant
Dim i As Integer, j As Long
Dim i0 As Integer 'valeur intermédiaire colonne 1 ici un entier
Dim s1 As String 'valeur intermédiaire colonne 2 ici une chaine
Dim i0m As Integer 'valeur intermédiaire médiane colonne 1
i = tInf
j = tSup
i0m = tb((tInf + tSup) / 2, 0) 'recuperer la valeur médiane
Do 'recherche d 'une valeur
supérieure
Do While tb(i, 0) < i0m
i = i + 1
Loop 'recherche d 'une valeur inférieure

Do While i0m < tb(j, 0)
j = j - 1
Loop 'si les deux pointeurs ne se croise pas permutation des
elements pointés
If i <= j Then
i0 = tb(i, 0)
tb(i, 0) = tb(j, 0)
tb(j, 0) = i0
i1 = tb(i, 1)
tb(i, 1) = tb(j, 1)
tb(j, 1) = i1
i = i + 1
j = j - 1
End If 'si les pointeurs se croisent, fin Loop
Loop Until i > j 'appel récursif de la procédure
If tInf < j Then
Call tri(tInf, j)
End If
If i < tSup Then
Call tri(i, tSup)
End If
End Sub


--
Amicalement.
Pascal
"il n'y a pas de vent favorable pour celui qui ne sait pas ou il va."
Sénèque.
http://www.ilyapa.net/excel
Avatar
Bonjour Monsieur Engelmayer.
Je ne sais pas si je dois vous remercier, car vous semblez
vous payer ma tête.
Au cas où ce serait par erreur que votre message ne
contient rien, merci.
-----Message d'origine-----


--
Amicalement.
Pascal
"il n'y a pas de vent favorable pour celui qui ne sait
pas ou il va."

Sénèque.
http://www.ilyapa.net/excel
"Adrien Delcour" a
écrit dans le

message de news: 063701c3c92b$c3e8b390$
Bonjour à tous.
J'écris une macro qui devrait trier un tableau, le mot
tableau étant pris au sens abstrait de l'anglais "array"
et non au sens concret de l'anglais "table". Il s'agit
donc d'une variable déclarée avec des parenthèses.
La seule chose que j'aie trouvée est la commande
WordBasic.SortArray, qui est indiquée dans la rubrique
d'aide "Equivalents Visual Basic des commandes Word Basic"
(à la lettre T dans Word 2000 et à la lettre S dans Word
2002...). Mais je ne parviens pas à trouver de la
documentation sur cette fonction : quelle est sa syntaxe,
comment précise-t-on l'ordre de tri (croissant ou
décroissant)...? Quelqu'un pourrait-il soit me dire
comment on se documente sur cette fonction, soit m'en
indiquer une autre ? (Il me semble exclu de passer par un
tableau visuel - "table" en anglais.)
Merci d'avance.


.



Avatar
Merci pour ces algorithmes (et mes excuses d'avoir mal
orthographié votre nom dans mon précédent message).
Il est sans doute bon de savoir programmer soi-même
un algorithme de tri adapté à la situation, mais je trouve
tout de même étonnant que le VBA n'en fournisse pas un
tout fait, comme le faisait le Word Basic et comme le font
d'autres langages (bibliothèque standard du C++, Perl...)
Ceci dit, je vais sans doute suivre votre suggestion. Il
me semble, à première vue, que je n'ai pas encore
rencontré le dernier algorithme que vous indiquez. Merci
encore.

-----Message d'origine-----
salut,
il existe plusieurs manières de trier :
Sub BubbleTri(tabTri)
'algorithme de tri (type BubbleSort) pour des petits
tableaux

'restitue le tableau trié

Dim I%, J%, K%, tmp

For I = LBound(tabTri) To UBound(tabTri)
J = I
For K = J + 1 To UBound(tabTri)
If tabTri(K) <= tabTri(J) Then J = K
Next K
If I <> J Then
tmp = tabTri(J): tabTri(J) = tabTri(I): tabTri
(I) = tmp

End If
Next I
End Sub

'======================== ===

Option Explicit
Type pile 'pour QuickSort
mini As Integer
maxi As Integer
End Type
Dim t(1 To 250) As Integer

Sub quicksort()
Dim tMoyen As Long
Dim iPile As Long
Dim mini As Long
Dim maxi As Long
Dim moyen As Long
Dim borne1 As Long
Dim borne2 As Long
Dim tt As Long
Dim i As Long
Dim pile(1 To 128) As pile
iPile = 1
pile(iPile).mini = 1 'Premier indice du tablaeu
pile(iPile).maxi = UBound(t) 'Dernier indice du
tableau

iPile = iPile + 1 ' pour que iPile, à la première
itération du do, soit

égal à 1

Do
iPile = iPile - 1 'la pile diminue et le
programme tri récursivement

les parties non triées
mini = pile(iPile).mini ' au départ 1
maxi = pile(iPile).maxi ' au départ à la
dimension du tableau

Do
borne1 = mini
borne2 = maxi
moyen = (mini + maxi) 2 'recuperer la
valeur au milieu du

tableau
tMoyen = t(moyen)
Do
Do While t(borne1) < tMoyen 'recherche
d 'un element plus

grand
borne1 = borne1 + 1
Loop

Do While t(borne2) > tMoyen 'recherche
d 'un element plus

petit
borne2 = borne2 - 1
Loop
If borne1 <= borne2 Then
'si les deux pointeurs ne se
rencontrent pas

'permutation des elements designés
par les pointeurs

tt = t(borne1)
t(borne1) = t(borne2)
t(borne2) = tt
borne1 = borne1 + 1
borne2 = borne2 - 1
End If
Loop While borne1 <= borne2 'si les pointeurs
se chevauchent,

'arrêt de la
boucle


If borne2 - mini < maxi - borne1 Then
'stockage dans la pile de la partie de
tableau non triée

'on pourrait utiliser un appel récursif
de quicksort en

remplaçant
'la procédure quicksort par une fonction
'quicksort(borneInf, borneSup) et éviter
ainsi la gestion de

la pile et de la récursivité
'ça enlèverait du piment au programme
If borne1 < maxi Then
pile(iPile).mini = borne1
pile(iPile).maxi = maxi
iPile = iPile + 1 'la pile augmente
End If
maxi = borne2
Else
If mini < borne2 Then
pile(iPile).mini = mini
pile(iPile).maxi = borne2
iPile = iPile + 1 'la pile augmente
End If
mini = borne1
End If
Loop While mini < maxi
Loop While iPile <> 1
End Sub
'======================== ===============
très simple de eric.rbt
Public Sub Trier_Tableau(ByVal LimiteInf As Integer,
ByVal LimiteSup As

Long)
' cette procedure trie le tableau "Produit" dans
l'ordre croissant

'syntaxe d'appel : call
Trier_Tableau
(Nr_Premier_Enregistrement,Nr_Dernier_Enregistrement)

' en sortie la table (Produit) est triée dans l'ordre
croissant


Dim i As Integer, j As Long
Dim Inter As Long
Dim transit As Long
Dim CTR As Long

i = LimiteInf 'Premier indice de ton tableu
j = LimiteSup 'dernier indice du tableau


transit = Produit((LimiteInf + LimiteSup) /
2) 'recuperer

la valeur au milieu du tableau


Do

'recherche
d'un element plus grand
Do While Produit(i) < transit
i = i + 1
Loop

'recherche

d'un element plus petit
Do While transit < Produit(j)
j = j - 1
Loop

'si les deux

pointeurs ne se rencontrent pas

'permutation

des elements designés par les pointeurs
If i <= j Then

Inter = Produit(i)
Produit(i) = Produit(j)
Produit(j) = Inter

i = i + 1
j = j - 1
End If

'si les

pointeurs se chevauchent, arret de la boucle
Loop Until i > j

'appel

récursif de l'algorithme de tri pour la partie de tableau
nom trié

If LimiteInf < j Then
Call Trier_Tableau(LimiteInf, j)
End If
If i < LimiteSup Then
Call Trier_Tableau(i, LimiteSup)
End If
End Sub
//===================
pour finir un exemple avec un tableau à deux dimensions
Dim tb(0 To 20, 0 To 1) As Variant
Sub test()
Dim i As Integer
For i = 0 To 20
tb(i, 0) = Int((100 * Rnd) + 1)
tb(i, 1) = Chr(i + 64)
Next i
Debug.Print "============ avant le tri
======================"

For i = 0 To 20
Debug.Print tb(i, 0) & " " & tb(i, 1)
Next i
Debug.Print "============ après le tri
======================"

Call tri(LBound(tb), UBound(tb))
For i = 0 To 20
Debug.Print tb(i, 0) & " " & tb(i, 1)
Next i
End Sub
Public Sub tri(ByVal tInf As Integer, ByVal tSup As Long)
' cette procédure tri le tableau "tb" dans l'ordre
croissant

' appel : call tri(bInf,bSup)
' le tableau (tb) est triée dans l'ordre croissant
Dim i As Integer, j As Long
Dim i0 As Integer 'valeur intermédiaire colonne
1 ici un entier

Dim s1 As String 'valeur intermédiaire colonne 2
ici une chaine

Dim i0m As Integer 'valeur intermédiaire médiane
colonne 1

i = tInf
j = tSup
i0m = tb((tInf + tSup) / 2, 0) 'recuperer
la valeur médiane

Do 'recherche
d 'une valeur

supérieure
Do While tb(i, 0) < i0m
i = i + 1
Loop 'recherche d 'une valeur inférieure

Do While i0m < tb(j, 0)
j = j - 1
Loop 'si les deux pointeurs ne se croise pas
permutation des

elements pointés
If i <= j Then
i0 = tb(i, 0)
tb(i, 0) = tb(j, 0)
tb(j, 0) = i0
i1 = tb(i, 1)
tb(i, 1) = tb(j, 1)
tb(j, 1) = i1
i = i + 1
j = j - 1
End If 'si les pointeurs se croisent,
fin Loop

Loop Until i > j 'appel récursif de la procédure
If tInf < j Then
Call tri(tInf, j)
End If
If i < tSup Then
Call tri(i, tSup)
End If
End Sub


--
Amicalement.
Pascal
"il n'y a pas de vent favorable pour celui qui ne sait
pas ou il va."

Sénèque.
http://www.ilyapa.net/excel


.



Avatar
Geo
Bonjour ,


Merci pour ces algorithmes (et mes excuses d'avoir mal
orthographié votre nom dans mon précédent message).


Et aussi d'avoir été désagréable.

je trouve
tout de même étonnant que le VBA n'en fournisse pas un
tout fait, comme le faisait le Word Basic et comme le font
d'autres langages (bibliothèque standard du C++, Perl...)


et Foxpro

Tout à fait d'accord et les performances ne seraient surement pas
comparables
Un voeu de plus pour billou Noel

A+

Avatar
Geo
Bonjour Pascal,


salut,
il existe plusieurs manières de trier :


[ Couic]

Si tu as d'autres trucs en réserve, n'hésite pas à nous en faire part
:-)

As-tu apprécié les performances de ces programmes ?
En particulier, il me semble que la récursivité si elle est
intellectuellement intéressante, est coûteuse en ressources.
Tu me diras que je n'ai qu'à tester, mais si tu l'as fait, ça m'ira
très bien :-)
--

A+

Avatar
Geo
Bonjour Adrien ,


La seule chose que j'aie trouvée est la commande
WordBasic.SortArray, qui est indiquée dans la rubrique
d'aide "Equivalents Visual Basic des commandes Word Basic"
(à la lettre T dans Word 2000 et à la lettre S dans Word
2002...). Mais je ne parviens pas à trouver de la
documentation sur cette fonction : quelle est sa syntaxe,
comment précise-t-on l'ordre de tri (croissant ou
décroissant)...?


La réponse est là :
http://www.mvps.org/word/FAQs/MacrosVBA/WordBasicCommands.htm

J'aimerai bien trouver l'équivalent pour VB :-D

A+

Avatar
Pascal Engelmajer
salut,
personnellement j'utilise un tri non récursif.
Je dois donc gérer les piles...

--
Amicalement.
Pascal
"il n'y a pas de vent favorable pour celui qui ne sait pas ou il va."
Sénèque.
http://www.ilyapa.net/excel
"Geo" a écrit dans le message de news:

Bonjour Pascal,


salut,
il existe plusieurs manières de trier :


[ Couic]

Si tu as d'autres trucs en réserve, n'hésite pas à nous en faire part
:-)

As-tu apprécié les performances de ces programmes ?
En particulier, il me semble que la récursivité si elle est
intellectuellement intéressante, est coûteuse en ressources.
Tu me diras que je n'ai qu'à tester, mais si tu l'as fait, ça m'ira
très bien :-)
--

A+




Avatar
Adrien Delcour
Merci Geo pour l'adresse que vous m'indiquez.
Dans un autre message, vous me reprochez d'avoir été
désagréable avec Pascal Engelmajer. Quand on reçoit un
message qui contient en tout et pour tout une allusion aux
gens qui ne savent pas où ils vont, est-il si grave de
faire un merci conditionnel ? Si Pascal Engelmajer m'a
trouvé vexant, je lui en fais mes excuses, car ce n'était
pas mon intention. Je pourrais me justifier plus
longuement d'avoir envisagé que sa réponse fût ironique,
mais je suppose que les critiques ne sont permises que
de "most valuable person" à questionneur, et non
l'inverse. Ceci dit, encore merci à vous pour l'adresse et
à Pascal Engelmajer pour les algorithmes commentés.
-----Message d'origine-----
Bonjour Adrien ,


La seule chose que j'aie trouvée est la commande
WordBasic.SortArray, qui est indiquée dans la rubrique
d'aide "Equivalents Visual Basic des commandes Word
Basic"


(à la lettre T dans Word 2000 et à la lettre S dans Word
2002...). Mais je ne parviens pas à trouver de la
documentation sur cette fonction : quelle est sa
syntaxe,


comment précise-t-on l'ordre de tri (croissant ou
décroissant)...?


La réponse est là :
http://www.mvps.org/word/FAQs/MacrosVBA/WordBasicCommands.
htm


J'aimerai bien trouver l'équivalent pour VB :-D

A+

.




Avatar
nuindacil
Bonjour Adrien,

Je me permet de m'initier dans cette conversation qui reste tout de même
publique ! :-)
Je ne veux pas jouer la redresseuse de torts, mais Pascal (qui n'est
d'ailleurs pas à ma connaissance une "most valuable person" (en tous les
cas pas officiellement :-)) a dû, me semble-t-il, faire partir le
premier mail par erreur, car, en effet, complètement vide...
Et tu ne devrais pas prendre ombrage pour sa citation de Sénèque à
propos des gens qui ne savent pas où ils vont, car cette phrase fait
partie de sa signature et ne t'était absolument pas adressée...

J''espère que Pascal pourra nous le confirmer.

En tous les cas, que ceci ne t'empêche pas de passer un joyeux Noël.

nuindacil
mvp word
http://faq.ms.word.free.fr



Merci Geo pour l'adresse que vous m'indiquez.
Dans un autre message, vous me reprochez d'avoir été
désagréable avec Pascal Engelmajer. Quand on reçoit un
message qui contient en tout et pour tout une allusion aux
gens qui ne savent pas où ils vont, est-il si grave de
faire un merci conditionnel ? Si Pascal Engelmajer m'a
trouvé vexant, je lui en fais mes excuses, car ce n'était
pas mon intention. Je pourrais me justifier plus
longuement d'avoir envisagé que sa réponse fût ironique,
mais je suppose que les critiques ne sont permises que
de "most valuable person" à questionneur, et non
l'inverse. Ceci dit, encore merci à vous pour l'adresse et
à Pascal Engelmajer pour les algorithmes commentés.

-----Message d'origine-----
Bonjour Adrien ,



La seule chose que j'aie trouvée est la commande
WordBasic.SortArray, qui est indiquée dans la rubrique
d'aide "Equivalents Visual Basic des commandes Word



Basic"

(à la lettre T dans Word 2000 et à la lettre S dans Word
2002...). Mais je ne parviens pas à trouver de la
documentation sur cette fonction : quelle est sa



syntaxe,

comment précise-t-on l'ordre de tri (croissant ou
décroissant)...?


La réponse est là :
http://www.mvps.org/word/FAQs/MacrosVBA/WordBasicCommands.


htm

J'aimerai bien trouver l'équivalent pour VB :-D

A+

.







1 2