Sub AfficherCongé(sh As Worksheet)
Dim Tablo, N, RES() As Variant, i&, j&, p&
With sh 'avec la feuille "sh"
' On teste si le nom de la feuille est un mois valide.
' Pour cela on construit la chaine " 1 mois 2000"
' où mois est le nom de la feuille sh.
' Si l'expression représente une date, alors la feuille
' est une feuille de mois.
' Ex 1: "1 Février 2000" est une date valide
' Ex 2: "1 Personnel 2000" n'est pas une date valide
If IsDate("1 " & sh.Name & " 2000") Then
' On est bien sur une feuille de mois.
' On recherche le numéro de ligne de la dernière date
' dans la colonne A à partir de A4.
' Il est primordial que la cellule A35 reste VIDE
N = .Range("a4").End(xlDown).Row
' On transfère les valeurs de la zone A2 à caN
' dans un tableau en mémoire => Tablo
' Tablo est donc le tableau des valeurs du planning
' de la ligne 2 à N et de la colonne A à la colonne CA
Tablo = .Range("a2:ca" & N).Value
' On dimensionne le tableau des résultats à 26 lignes et deux colonnes
' La 1ière colonne comprendra le nom de la personne (26 personnes max)
' La 2ième colonne contiendra la liste des jours de congé de la personne
' en 1ière colonne.
ReDim RES(1 To 26, 1 To 2)
' On boucle sur chaque colonne de tablo avec un pas de 3.
' On commence par la colonne 2 de tablo (ie colonne B du planning)
' puis par colonne 5 de tablo (ie colonne E du planning)
' puis par colonne 8 de tablo (ie colonne H du planning)
' jusqu'à colonne 77 de tablo (ie colonne BY du planning).
' La colonne suivante serait 80 (=77+3) qui est au delà de la borne sup. de la boucle
For j = 2 To 79 Step 3
' On vérifie si le nom (en ligne 2 du planning qui est la ligne 1 de tablo)
' a plus d'un caractère (pour éliminer les noms égaux à "0")
If Len(Tablo(1, j)) > 1 Then
' C'est un nom valide.
' On augmente le compteur des noms valides.
p = p + 1
' On stocke le nom dans RES à la ligne p et colonne 1.
RES(p, 1) = Tablo(1, j)
' On va boucler sur les lignes de la colonne j de tablo.
' Cette colonne est la colonne sous le nom en cours.
' Du premier jour du mois => ligne 3 de tablo (ie ligne 4 du planning)
' Au dernier jour du mois => dernière ligne de tablo (ie ligne de fin de mois du planning)
For i = 3 To UBound(Tablo)
' On teste si la valeur est égale à "congé payé".
If Tablo(i, j) = "congé payé" Then
' La valeur est égale à "congé payé".
' On concatène le n° de jour de la date (colonne 1 de tablo)
' à la valeur de la colonne 2 de RES.
' Le séparateur est ", "
RES(p, 2) = RES(p, 2) & ", " & Day(Tablo(i, 1))
End If
Next i
' On teste si la chaine correspondnat aux congés de la personne
' est vide ou non. Si elle n'est pas vide, on ôte du début de la chaine
' le séparateur ", " devant le premier jour de congé.
If Len(RES(p, 2)) > 0 Then RES(p, 2) = Mid(RES(p, 2), 3)
End If
' On passe au nom suivant.
Next j
' Nous avons maintenant un tableau RES de deux colonnes
' et 26 lignes. Mais il n'y a que les p premières lignes qui
' nous intéressent (correspondant aux p noms trouvés)
' => Nous allons tronquer le tableau MAIS il y a un petit problème:
' VBA ne sait tronquer que les dernières colonnes d'un tableau
' On va donc transposer RES. RES va devenir un tableau de 2 lignes
' et 26 colonnes.
RES = Application.Transpose(RES)
' On tronque le nouveau RES en ne gardant que p colonnes,
' ça, VBA sait le faire...
' On obtient un tableau de 2 lignes et p colonnes
ReDim Preserve RES(1 To 2, 1 To p)
' On transpose à nouveau le tableau RES pour aboutir
' à un tableau de p ligne et deux colonnes.
' Nous sommes donc passés d'un tableau de 26 lignes et 2 colonnes
' à un tableau de p lignes et deux colonnes.
RES = Application.Transpose(RES)
' On considère la cellule a45.
' On la redimensionne à une plage aux dimensions du tableau RES
' et on y colle le tableau RES.
.Range("a45").Resize(p, 2) = RES
End If
End With
End Sub