Private Sub Worksheet_Change(ByVal Target As Range)
Dim x, n&
' Target est l'ensemble des cellules qui ont été modifiées. On cherche si la cellule A1 est parmi ces cellules.
' Si ce n'est pas le cas, on quitte la procédure puisque le mois n'a pas changé. Pour cela, on calcule l'intersection
' des cellules modifiées (Target) et de la cellule A1. On compare le résultat à l'ensemble vide (Nothing)
If Intersect(Range("a1"), Target) Is Nothing Then Exit Sub ' si la cellule A1 n'a pas changé, on ne fait rien
' on affiche toutes les colonnes. On considère la ligne 1 - rows(1). On en prend toutes les colonnes
' et on affiche toutes ces colonnes
Rows(1).EntireColumn.Hidden = False
' on va constuire une chaine de caractère représentant le premier jour du mois choisi. Pour cela,
' on construit un tableau à une dimension contenant les trois éléments (1 , mois choisi , année)
' avec l 'instruction Array. Array(1, range("a1"), 2022) qu'on peut aussi écrire Array(1, [a1], 2022).
' Ensuite, on utilise l'instruction JOIN qui prend comme argument un tableau T à une dimension et
' une chaine de caractères SEP. JOIN(T,SEP) va concatener les éléments du tableau en les séparant
' par la chaine SEP. Si SEP est omis, alors le séparateur est par défaut le caractère espace.
' donc si Ai contient mars alors JOIN(Array(1, [a1], 2022) va donner la chaine "1 mars 2022"
' ça revient à faire : 1 & " " & Range("a1").value & " " & 2022
' le résultat est ensuite converti de texte en vraie date par CDATE(JOIN(Array(1, [a1], 2022))
x = CDate(Join(Array(1, [a1], 2022)))
' il faut maintenant trouver le précédent lundi. Pour cela, on utilise Weekday(date,premier jour de la semaine)
' qui renvoie un nombre entre 1 et 7 représentant le jour de la semaine
' la paramètre premier jour de la semaine est pris égal à 2 qui veut dire que Weekday va considérer
' le lundi comme le premier jour de la semaine. Si date est un lundi alors weekday renverra 1,
' si date est un mardi alors weekday renverra 2, ..., si date est un dimanche alors weeeday renverra 7
' si x est un lundi, on doit soustraire 0 jour à x pour avoir le lundi (weekday(x,2)renvoie 1)
' si x est un mardi, on doit soustraire 1 jour à x pour avoir le lundi (weekday(x,2)renvoie 2)
' si x est un mercredi, on doit soustraire 2 jours à x pour avoir le lundi (weekday(x,2)renvoie 3)
' ...
' si x est un dimanche, on doit soustraire 6 jours à x pour avoir le lundi (weekday(x,2)renvoie 7)
' On voit donc qu'à partir de la date x du premier du mois, il faut soustraire à x le type de jour moins un
' soit x - (Weekday(x, 2) -1) qu'on peut aussi écrire
x = x - Weekday(x, 2) + 1
' dans la ligne 6, on recherche le n° de colonne de la date x (si la date est absente, on retourne 0)
' Pour cela, la formule excel sur la feuille de calcul serait : SIERREUR(EQUIV(date du lundi; 6:6; 0), 0)
'
' On va utiliser l'instruction Application.Evaluate(formule-texte) qui va évaluer (calculer)
' la formule-texte. Excemple Application.evaluate("11+2") renverra 13
' Il faut fabriquer l'instruction à évaluer (en anglais bien sûr!) en insérant comme paramètre la date du lundi
' soit "=IFERROR(MATCH(" & date-du-lundi & ",6:6,0),0)" qui donnerait =IFERROR(MATCH(date-du-lundi,6:6,0),0)
' on écrit donc ="IFERROR(MATCH(" & x & ",6:6,0),0)"
' mais cela ne marchera pas car pour des raisons (que je ne développerai pas), il faut transformer la date en nombre.
' Pour cela, on multiplie la date x par 1 : (1 * x)
n = Application.Evaluate("=IFERROR(MATCH(" & (1 * x) & ",6:6,0),0)")
' à ce stade n est soit le numéro de la colonne contenant la date du lundi x soit 0 (date non trouvée)
' si la date a été trouvée (x>0), alors on masque les colonnes 2 jusqu'à une colonne
' avant la colonne du lundi x soit la jusqu'à la colonne n-1
If n > 0 Then Range(Cells(1, 2), Cells(1, n - 1)).EntireColumn.Hidden = True
End Sub