Modifier code avec variables tableau (Lbound/Ubound ...)

Sebast

XLDnaute Impliqué
Bonjour à toutes et à tous,

Utilisant des fichiers contenant souvent beaucoup d'enregistrements, j'aimerais me former à l'usage des variables tableaux.

Mes tentatives n'ont rien donné et je ne fais que m'embrouiller … :mad:


A partir du bout de code joint (fichier fictif et surtout peu volumineux), quelqu'un peut-il transformer ma Sub() en une version passant par un tableau (Lbound/Ubound) ?

Idéalement, le plus simple possible, par exemple sans recours à un scripting dictionary (si possible ?)
et avec des commentaires genre Pour Les Nuls (dont je suis !)

Même si au final l'idée est d'accélerer le traitement, je préfère procéder "pas à pas"

D'avance, un grand merci

Code:
' Objet : coller le libellé de la devise à partir de son code ISO 
Sub Trouver_la_devise()
 
' 1 - on définit le range
Dim DernLignDevise As Long
Dim PaysRange As Range
 
With Sheets("Devises")
    DernLignDevise = .Range("A" & Rows.Count).End(xlUp).Row
    Set PaysRange = .Range("A2:C" & DernLignDevise)
End With
 
' 2 on colle le nom complet de la devise via vlookup
With Sheets("Base")
Dim NomDevise As String
Dim DernLignBase As Long
Dim i As Long
DernLignBase = .Range("A" & Rows.Count).End(xlUp).Row
On Error Resume Next
 
        For i = 2 To DernLignBase
                    NomDevise = Application.WorksheetFunction.VLookup(.Cells(i, 3), PaysRange, 2, False)
                    .Cells(i, 4) = NomDevise
        Next i
        
End With
 
End Sub
 

Pièces jointes

  • Passer_en_mode_tableau.xlsm
    214.4 KB · Affichages: 34

Dranreb

XLDnaute Barbatruc
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Bonjour.

Personnellement je pense que je l'écrirais comme ça :
VB:
Sub TrouverLaDevise()
Dim T(), RDev As Range, L As Long, CodD As String, NomD As String
T = Feuil5.[C2].Resize(Feuil5.[A60000].End(xlUp).Row - 1).Value
Set RDev = Feuil4.[A2:B2].Resize(Feuil4.[A60000].End(xlUp).Row - 1)
For L = 1 To UBound(T)
   If T(L, 1) <> CodD Then CodD = T(L, 1): NomD = _
      RDev(WorksheetFunction.Match(CodD, RDev.Columns(1), 0), 2).Value
   T(L, 1) = NomD: Next L
Feuil5.[D2].Resize(UBound(T, 1)).Value = T
End Sub

Edit: Pas eu le temps de mettre des commentaires, déjeuner oblige. Et puis comme ça vous n'avez que les instructions à comprendre et pas les commentaires en plus. Mais vous pouvez en mettre à ce que vous ne comprenez pas, après éclaircissements de ma part si nécessaire.
 
Dernière édition:

Sebast

XLDnaute Impliqué
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Bonjour,

Merci beaucoup de vous être penché sur mon cas.


Avant de me plonger dans l’étude de ce tableau, je ne vois pas clair à cause d’aspects qui d’après moi ne relèvent de la syntaxe VBA propre aux tableaux.
J’ai essayé de réécrire la sub() selon un mode plus familier (pour moi) mais ça conduit à un résultat différent du vôtre [probablement dû au if then absence de else et : (deux points)]


a) Structure if then …
Les deux points remplacent-ils un passage à la ligne ?
Le else est-il présumé (si oui pouvez-vous le mettre car je crois que c’est la raison de la divergence entre vos résultats et les miens) ?


b) Adresses
Ne peut-on pas utiliser le nom explicite de la feuille (ex : « Base » ou « Devises » plutôt que Feuilk) ?
Ou est-ce propre aux tableaux ?

D’ailleurs, pourquoi écrit-on «row -1 » alors qu’on a bien défini par le [C2] qu’on démarre en ligne 2 donc qu’on tient compte des titres ?


c) Embranchement/condition
If T(L, 1) <> CodD Then CodD = T(L, 1)
J’ai du mal à comprendre car la valeur de CodD n’apparait pas avant et pourtant on s’en sert avec le if …


Si mes remarques ne sont pas spécifiques aux tableaux, puis-je vous demander d’écrire le code en en tenant compte (notamment les : et absence de else qui me perturbent beaucoup car ma rectif conduit à un autre résultat)



Merci d’avance
 

Dranreb

XLDnaute Barbatruc
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Les deux points remplacent-ils un passage à la ligne ?
Pas tout à fait: ils servent à séparer plusieurs instructions sur une même ligne logique, c'est à dire une ou plusieurs lignes physiques dont seule la dernière ne se termine pas par un " _" de continuation. La syntaxe du If où une instruction suit immédiatement le Then ne requiert pas de End If, mais seules les instructions sur la même ligne logique que le Then sont soumises à la condition.
Ne peut-on pas utiliser le nom explicite de la feuille (ex : « Base » ou « Devises » plutôt que Feuilk) ?
Ou est-ce propre aux tableaux ?
Seulement par consulation des collections Sheets ou Worksheets de l'objet Workbook. Je préfère travailler directement avec les objets Worksheet connus du projet VBA. Mais je leurs donne d'habitude des noms mnémoniques commençant par "F". C'est leur première propriété (Name) dans la fenêtre de propriétés. Ce n'est pas propre aux tableaux.
D’ailleurs, pourquoi écrit-on «row -1 » alors qu’on a bien défini par le [C2] qu’on démarre en ligne 2 donc qu’on tient compte des titres ?
Non, justement, je n'inclue pas les titres puisque je commence à la ligne 2. Le nombre de lignes de cette plage est donc le numéro de ligne de la dernière diminué de 1. S'il y a 2 lignes ce sont les 2 et 3, et 2 = 3-1.
If T(L, 1) <> CodD Then CodD = T(L, 1)
J’ai du mal à comprendre car la valeur de CodD n’apparait pas avant et pourtant on s’en sert avec le if …
Oui mais elle a quand même au départ une valeur initiale qui est celle d'une chaîne vide, ce qui est bien déjà différent du 1er élément du tableau.
Si mes remarques ne sont pas spécifiques aux tableaux, puis-je vous demander d’écrire le code en en tenant compte (notamment les : et absence de else qui me perturbent beaucoup car ma rectif conduit à un autre résultat)
Même l'autre syntaxe du If ne requiert pas de Else ici, mais un End If
VB:
Sub TrouverLaDevise()
Dim T(), RDev As Range, L As Long, CodD As String, NomD As String
T = Feuil5.[C2].Resize(Feuil5.[A60000].End(xlUp).Row - 1).Value
Set RDev = Feuil4.[A2:B2].Resize(Feuil4.[A60000].End(xlUp).Row - 1)
For L = 1 To UBound(T)
   If T(L, 1) <> CodD Then
      CodD = T(L, 1)
      NomD = RDev(WorksheetFunction.Match(CodD, RDev.Columns(1), 0), 2).Value
      End If
   T(L, 1) = NomD
   Next L
Feuil5.[D2].Resize(UBound(T, 1)).Value = T
End Sub
De toutes façon, je considère personnellement que les End If et Next font encore partie du bloc d'instructions qu'elles terminent (un peu comme un point fait encore partie de la phrase qu'il termine) et je les mets donc au moins au même niveau d'indentation qu'elles. Mais je trouve dommage de gâcher une ligne pour ces simples fin de blocs, je préfère chaque fois que possible les mettre derrière un ":" qui suit la dernière instruction.
 
Dernière édition:

Sebast

XLDnaute Impliqué
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Bonjour Danreb,

Désolé pour ce délai de réponse mais j’ai eu un contretemps …
Merci beaucoup d’avoir pris du temps pour répondre à mes questions et pour avoir adapté le code à mon niveau
C’est pour moi déjà beaucoup plus compréhensible, je peux désormais me concentrer sur ce qui fait la particularité des tableaux.

Du coup, mes questions d’ordre technique sont :

1) NomD = RDev(WorksheetFunction.Match(CodD, RDev.Columns(1), 0), 2).Value
Le vlookup que je proposais au début ne fait pas le job ? ou c’est plus rapide avec Match (voire indispensable avec les tableaux ?)


2) je ne comprends pas pourquoi on a, à trois lignes d’écart, les égalités
CodD = T(L, 1)

Puis …
T(L, 1) = NomD

C’est là j’imagine le cœur du fonctionnement des tableaux, même si dans le peu de littérature que j’ai à ce sujet je ne trouve pas d’explication


Au passage, y a-t-il un tuto de référence en la matière ?

Encore merci
 

Sebast

XLDnaute Impliqué
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Bonsoir,

merci beaucoup pour cette contribution et les commentaires très utiles (je suis novice en matière d'array donc ça m'aide à bien comprendre). C'est clair et didactique : merci
Avec quelle base as-tu appris les arrays : je n'ai pas de bouquin de référence

a +
 

Dranreb

XLDnaute Barbatruc
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Le vlookup que je proposais au début ne fait pas le job ? ou c’est plus rapide avec Match
Sais pas. C'est plus simple à mon avis. En formule non plus je n'utilise jamais RECHERCHEV. Toujours plutôt INDEX/EQUIV, et là INDEX revient simplement à extraire la bonne ligne.
je ne comprends pas pourquoi on a, à trois lignes d’écart, les égalités
CodD = T(L, 1)

Puis …
T(L, 1) = NomD
C'est parce que j'utilise le même tableau à la fois en entrée et en sortie puisqu'on n'a plus besoin du code qu'il contient une fois qu'on y a mis le nom à restituer qui lui correspond.
 

Sebast

XLDnaute Impliqué
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Bonsoir,

merci pour cette aide claire et didactique ainsi que les commentaires ciblés (je démarre les arrays donc les remarques pas à pas me sont très utiles).

Comment t'y es-tu mis (bouquin de référence, tuto ...) ?

à +
 

Dranreb

XLDnaute Barbatruc
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Comment t'y es-tu mis (bouquin de référence, tuto ...) ?
Alors ça je n'en sais vraiment plus rien, tellement c'est vieux !
Le concept de tableau en mémoire a toujours existé dans tous les langages de programmation dit évolués, à commencer par le FORTRAN.
En assembleur, trop proche du langage machine, ça revient à calculer des adresses par rapport à celle du début du tableau en multipliant l'indice auquel on veut accéder par la longueur commune en octets de chaque élément.
Mais vous avez l'air de vous en faire tout un monde, alors qu'il n'y a vraiment rien de compliqué. Qu'est-ce qui vous paraît encore hermétique au juste, qu'on balaye une bonne fois pour toutes cette zone d'ombre de votre conception ?
Il y a juste une particularité de l'interface VBA d'Excel, à savoir que la propriété Value d'un Range de plusieurs cellules contigües est toujours constituée d'un tableau à 2 dimensions d'éléments de type Variant, même pour une seule ligne ou une seule colonne. Un tableau à une seule dimension est toutefois accepter pour en garnir la Value d'un Range de cellules contigües dans une seule ligne.
 

Sebast

XLDnaute Impliqué
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Bonjour,

Merci pour vos contributions. Je vais faire mon marché parmi ces tutos.

Mais vous avez l'air de vous en faire tout un monde, alors qu'il n'y a vraiment rien de compliqué. Qu'est-ce qui vous paraît encore hermétique au juste, qu'on balaye une bonne fois pour toutes cette zone d'ombre de votre conception ?



A mon avis avec les arrays on saute une marche en matière de conceptualisation et donc de représentation des données

J’ai l’impression qu’avec une boucle classique, pour une ligne donnée, on définit le critère de recherche et dans la foulée on l’écrit dans la cellule voulue puis on passe à la ligne suivante

alors qu’avec les tableaux, on transfère tout en masse à la fin ...

mais je vais me soigner en pratiquant encore et encore


Personnellement, vous les employez parce que c’est plus puissant/rapide, code plus compact ou pour quelle raison ?

Encore merci pour l’aide et les conseils fournis par les uns et les autres
 

Dranreb

XLDnaute Barbatruc
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Bonjour.

Plus rapide essentiellement. Pour un traitement devant porter sur des données Excel il convient de limiter le plus possible le nombre d'accès au plages de cellules car il est très pénalisant en temps et dépend assez peu du nombre de valeurs de cellules transférées lors de chacun d'eux. Cela conduit tout naturellement à travailler avec des tableaux. Mais ce n'est pas la seule conséquence: pour installer une formule dans chaque cellule d'une plage verticale on ne peut pas utiliser de tableau, mais si, comme souvent, seul le numéro de ligne y diffère il convient de mettre la même FormulaR1C1 à toute la plage d'un coup plutôt qu'avec une boucle qui accède aux cellules individuellement.
 

Sebast

XLDnaute Impliqué
Re : Modifier code avec variables tableau (Lbound/Ubound ...)

Re,

merci pour ces précisions, c'est ce que je pressentais.
Traitant parfois des fichiers avec bcp d'enregistrements, je vais devoir m'y pencher sérieusement.


Encore merci et bon weekend
 

Statistiques des forums

Discussions
312 184
Messages
2 086 007
Membres
103 088
dernier inscrit
Psodam