Comprendre un code
Bonjour
Est ce que quelqu'un peut me commenter ce code:
que veut dire :
With Sheets ("BD")=Selection le feuille Base de données OK
For i = 2 To .Range("B"& rows.Count).end(xlup).row ????
If.Range("B"&i)=ActiveSheet.Name Then ????
Merci
a+
Thierry
Bonsoir,
je ne suis pas un expert...
With Sheets ("BD") =Selection le feuille Base de données OK
en fait le WITH signifie que l'on simplifie l'écriture du code, cela veut dire "Avec la feuille BD"
For i = 2 To .Range("B"& rows.Count).end(xlup).row ????
For est une boucle qu'on pourait traduire par : de i = 2 à i = .Range("B"& rows.Count).end(xlup).row
.Range("B"& rows.Count).end(xlup).row c'est ici que la simplification d'écriture "commence" :
le "." devant Range est compris par le code comme : Sheets("BD").Range....
Rows.count, on compte le nombre de ligne que comporte la feuille
on va à la fin "end" et on remonte xlup pour trouver la dernière cellule pleine de la feuille
.row revoit le numéro de ligne de la feuille Excel où se trouve cette dernière cellule pleine de la colonne B
donc en colonne B si la dernière cellule pleine est en ligne 27 : .Range("B"& rows.Count).end(xlup).row revoit 27
la boucle irait donc de i=2 à i=27 , il y aura donc 26 "rotations"
If.Range("B"&i)=ActiveSheet.Name
ici on fait un test d'égalité "=" entre la cellule .Range("B" & i) sous entendu "value" (on reconnaît encore la simplification d'écriture)
lors de la boucle i prend les valeurs de 2 à 27 (dans notre exemple) donc au premier tour de boucle i vaut 2
ici on test si la valeur de la cellule B2 est égal au nom de la feuille active (Activesheet.name) en effet le symbole "&" permet de concaténer deux valeur "LouR" & "eeD" = LouReeD !
si c'est égal alors (then) on fait ce qui suit
Mais il me manque le reste du code pour continuer...
@ bientôt
LouReeD
Bonjour
Loureed et Meri beaucoup pour ces explication .
Je te mets le reste du code si tu asle tempq de le commenter.
Option Explicit
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim i As Integer, Numéro_Colonne As Byte, Classe As Single, der_Lig As Integer, Volume As Single
If ActiveSheet.Name = "Divers" Then
Range("A9:V21").ClearContents
With Sheets("BD_Divers")
For i = 2 To .Range("B" & Rows.Count).End(xlUp).Row
If .Range("B" & i) = ActiveSheet.Name Then
Classe = .Range("B" & i)
Select Case Classe
Case Is = 1
Numéro_Colonne = 5
Case Is = 2
Numéro_Colonne = 7
Case Is = 3
Numéro_Colonne = 9
Case Is = 4
Numéro_Colonne = 11
Case Is = 5
Numéro_Colonne = 13
Case Is = 6
Numéro_Colonne = 15
Case Is = 7
Numéro_Colonne = 17
Case Else
Numéro_Colonne = 19
End Select
Volume = .Range("G" & i)
der_Lig = Cells(Rows.Count, 2).End(xlUp).Row
Cells(der_Lig + 1, 1) = .Range("C" & i)
Cells(der_Lig + 1, Numéro_Colonne) = .Range("F" & i)
Cells(der_Lig + 1, 22) = Cells(der_Lig + 1, 22) + Volume
End If
Next i
End With
End If
End Sub
Merci encore
A+
Thierry
Bonjour,
un essai d'explication :
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
' définition des variables cela permet à VBA d'alouer la bonne taille de mémoire à la variable
' ce qui permet de prendre moins de place en mémoire et d'aller un peu plus vite au niveau de l'éxécution du code je crois
Dim i As Integer, Numéro_Colonne As Byte, Classe As Single, der_Lig As Integer, Volume As Single
If ActiveSheet.Name = "Divers" Then ' si on est bien sur la feuille "Divers"
Range("A9:V21").ClearContents " on efface les données des cellules de la plage A9:V21"
With Sheets("BD_Divers") ' avec la feuille "BD_Divers" (simplification d'écriture par la suite)
For i = 2 To .Range("B" & Rows.Count).End(xlUp).Row ' on lance une boucle qui va de I=2 à I= numéro de la dernière ligne pleine de la feuille en prenant en référence la colonne B
If .Range("B" & i) = ActiveSheet.Name Then ' si la valeur de la cellule B & &valeur de I
'donc pour la première boucle si la valeur de la cellule B2 de la feuille BD_Divers = le nom de la feuille ative
Classe = .Range("B" & i) 'alors la variable Classe prend la valeur de la cellule B2 (dans la première boucle)
Select Case Classe ' ici on se trouve sur un "aiguillage" en fonction de la valeur de la variable Classe
Case Is = 1 ' si Classe" vaut 1
Numéro_Colonne = 5 ' alors la variable Numéro_Colonne = 5
Case Is = 2 ' si Classe vaut 2 etc....
Numéro_Colonne = 7
Case Is = 3
Numéro_Colonne = 9
Case Is = 4
Numéro_Colonne = 11
Case Is = 5
Numéro_Colonne = 13
Case Is = 6
Numéro_Colonne = 15
Case Is = 7
Numéro_Colonne = 17
Case Else
Numéro_Colonne = 19
End Select ' on sort de l'aiguillage
Volume = .Range("G" & i) ' la variable Volume est égale à la valeur de la cellule G2 de la feuille BD_Divers (dans la première boucle)
der_Lig = Cells(Rows.Count, 2).End(xlUp).Row ' on cherche le numéro de la dernière ligne pleine de la feuille active en prenant en référence la colonne 2 c'est à dire B
' grace à ce numéro de ligne trouvé on inscrit différente valeur sur la ligne du dessous : der_lig + 1
Cells(der_Lig + 1, 1) = .Range("C" & i)
Cells(der_Lig + 1, Numéro_Colonne) = .Range("F" & i)
Cells(der_Lig + 1, 22) = Cells(der_Lig + 1, 22) + Volume
End If ' on sort du "If"
Next i ' on reboucle tant I n'est pas égal à sa valeur maxi
End With ' on arrête de "travailler" avec la feuille BD_Divers
End If ' on sort du premier "If"
End Sub ' fin de procédure
N'hésitez pas dans l'écriture de vos codes de créer des "décalages" en fonction de ce que vous écrivez :
la for Next est plus visible si ce qu'il y a à faire dans la boucle est décalé par rapport aux instructions de boucle, tout comme le With et le EndWith...
Indentez vos codes !
Grâce à la touche du clavier.
@ bientôt
LouReeD
Bonjour,
Je me permet un petit complément aux explications de LouReed (que je salue !)
Un bloc With... End With ne se contente pas de raccourcir l'écriture du code, il en permet surtout une exécution beaucoup plus rapide car VBA met l'expression en mémoire pour s'y référer directement. C'est un des meilleurs moyens d'optimisation du code. (Je recommande toujours d'utiliser de tels blocs d'instruction systématiquement chaque fois qu'on le peut...)
Le point faible du code soumis, c'est que les expressions non qualifiées (Cells, sans point devant) réfèrent elles à la feuille active, que VBA doit chercher, ce à chaque ligne, ce qui n'accélère pas le code... Il aurait été bon d'utiliser une variable pour la feuille active (qui aurait permis un accès plus rapide...)
En ce qui concerne l'instruction Select Case, l'utilisation de Is est obligatoire seulement avec les opérateurs de comparaison > et <
Et l'opérateur = peut être omis. On pouvait donc écrire plus rapidement : Case 1.... Case 2.... Case 3....
Mais au cas particulier, on pouvait raccourcir encore plus l'instruction :
Select Case Classe
Case 1 To 7
Numéro_Colonne = Classe * 2 + 3
Case Else
Numéro_Colonne = 19
End Select
Cordialement.
Bonjour MFerrand !
La tête du palmarès vous fait peur ?!
En effet, j'ai l'impression de moins vous voir sur les posts...
par contre le With je vais m'en servir plus souvent !
J'ai même lu quelque part que plutôt de mettre [A1].value, si on s'en sert souvent, il vaut mieux mettre cette valeur "sous variable VBA" pour éviter les "pertes de temps" d'accès à la feuille de la part de VBA, Est-ce vrai ?
Ceci dit, si on s'en sert qu'une fois dans le code cela devient inutile car pour remplir la variable il y a forcément un accès à la feuille...
Qu'en dites vous Maréchal ?
@ bientôt
LouReeD
Je t'avais annoncé mon intention de ralentir !
Pour With tu as raison... je pense que ça accèlère, y compris lorsque le With s'applique à des variables. Maintenant, quand tu utilises : [A1], ne pas confondre le type de notation (dite compacte par Microsoft, qui appellererait de fait la méthode Evaluate), mais où la plage n'est pas non plus qualifiée... A ce titre, ActiveSheet.[A1] sera plus rapide parce qu'on appelle directement la feuille active...
Quand tu ne peux mettre sous With, je pense qu'une variable reste ce qui est le plus rapide d'accès... Evidemment pour un appel unique, il faut cibler mais inutile d'initialiser une variable ou un instruction With. Le gain est dans la répétition.
Bonne soirée.
Bonjour
Merci Loureed et Mfernant
Pour toutes ces explication
Thierry
Bonsoir,
Ferrand le Maréchal et non pas Fernant !
@ bientôt
LouReeD
Bonsoir,
en effet je viens de relire votre post de présentation dans le forum consacré à cela !
Suis je bête ? Non fiévreux simplement....
@ bientôt
LouReeD