Il s'agit d'une grid entièrement personnalisée, avec un VScrollBar qui apparaît lorsque le nombre de lignes dépassent la limite que vous avez fixé. Vous pouvez mettre des conditions pour colorer les cellules. Ce code possède 2 types de grid, l'une avec sélecteur et l'autre sans.
Source / Exemple :
Option Explicit
Private Tbl() As Variant 'Création d'un tableau à vide en vue d'un dimensionnement dynamique
'Dessine le tableau à partir de la requête sql
Public Sub DesignTable(ByVal cn As ADODB.Connection, ByVal rs As ADODB.Recordset, sql As String, sCpt As Integer, Frm As Form, ParamArray var() As Variant)
Dim i, j, k, cpt, PosX, PosY, Col, Lig, tmp As Integer
rs.Open sql, cn, 1, 2
'sCpt Définition du nombre de lignes à partir desquelles le scroll va commencer à opérer
Col = rs.Fields.Count 'Nb de colonnes
Lig = rs.RecordCount 'Nb de lignes
tmp = 0
'Définition du tableau récupérant les valeurs passées par la table
ReDim Tbl(Col - 1, Lig - 1) As Variant 'Chargement des dimensions réelles du tableau
PosX = Frm.Cell(0).Left 'Récupération de la position initiale
PosY = Frm.Cell(0).Top 'de la cellule en haut à gauche
If var(0) <> 0 Then
Frm.Cell(0).Width = var(0) 'défini la taille des cellule
Frm.Titre(0).Width = var(0)
End If
For i = 0 To UBound(var)
tmp = tmp + var(i) 'Longueur d'une ligne
Next i
'Définition de la taille du cadre qui entoure les cellules.
Frm.Cadre.Height = ((Lig + 1) * Frm.Cell(0).Height) + 30 '+1 à cause des titres
Frm.Cadre.Width = tmp + 30 'épaisseur
'Rend visible, place et initialise les paramètre du VScroll
If Lig > sCpt Then
Frm.VScroll.Min = 1
Frm.VScroll.Max = Lig - sCpt + 1 'Définition de la taille maximale du scroll
Frm.VScroll.Visible = True
Frm.Blanc.Visible = True
Frm.VScroll.Left = Frm.Cell(0).Left + tmp
Frm.VScroll.Height = sCpt * Frm.Cell(0).Height
Frm.VScroll.Top = Frm.Cell(0).Top
Frm.Blanc.Left = Frm.VScroll.Left
Frm.Blanc.Top = Frm.Titre(0).Top
'Définition de la taille du cadre qui entoure les cellules en fonction du scroll
Frm.Cadre.Height = ((sCpt + 1) * Frm.Cell(0).Height) + 30
Frm.Cadre.Width = tmp + Frm.VScroll.Width + 30 'Sélecteur + Vscrool + épaisseur
End If
cpt = Col * Lig 'Nb de cellules totales
k = 0
'Création des titres des cellules
For i = 0 To Col - 1
If i > 0 Then
Load Frm.Titre(i): Frm.Titre(i).Visible = True
Frm.Titre(i).Text = rs.Fields(i).Name 'Récupération du nom des colonnes
Frm.Titre(i).Width = var(i)
Frm.Titre(i).Left = Frm.Titre(i - 1).Left + Frm.Titre(i - 1).Width
Frm.Titre(i).Top = Frm.Titre(0).Top
Else
Frm.Titre(0).Text = rs.Fields(0).Name
End If
Next i
'Remplissage du tableau de Variant
j = 0
While rs.EOF = False
For i = 0 To (Col - 1)
'Si une valeur est null alors on insert une chaine vide dans le tableau
Tbl(i, j) = IIf(IsNull(rs.Fields(i)), vbNullChar, rs.Fields(i))
Next i
j = j + 1
rs.MoveNext
Wend
rs.Close
'Répartition des sélecteurs et des cellules
'Exemple de tableau, les chiffres représentant les index.
'---------------------
'|T0 |T1 |T2 |T3 |T4 |
'---------------------
'| 0 | 1 | 2 | 3 | 4 |
'---------------------
'| 5 | 6 | 7 | 8 | 9 |
'---------------------
k = 0
For j = 0 To (Lig - 1)
For i = 0 To (Col - 1)
'Calcul position des cellules leur affecte les valeurs
If ((i = 0) And (j = 0)) Then
Frm.Cell(k).Text = Tbl(i, j)
Condcoul Frm, k, Col, Lig 'condition couleur
Else
If ((k) Mod (Col) = 0) Then 'Créé et place toutes les cellules qui sont du coté gauche
Frm.Cell(0).Width = var(0)
Load Frm.Cell(k)
If (j < (sCpt)) Then Frm.Cell(k).Visible = True
Frm.Cell(k).Top = Frm.Cell(k - 1).Top + Frm.Cell(k).Height 'le .top de la cellule précédente + la hauteur de la cellule
Frm.Cell(k).Left = Frm.Cell(0).Left
Frm.Cell(k).Text = Tbl(i, j)
Condcoul Frm, k, Col, Lig 'condition couleur
Else
'Crée et place toutes les autres cellules
Frm.Cell(0).Width = var(i)
Load Frm.Cell(k)
If (j < (sCpt)) Then Frm.Cell(k).Visible = True
Frm.Cell(k).Top = Frm.Cell(k - 1).Top
If k = 1 Then
Frm.Cell(1).Left = Frm.Cell(0).Left + var(0)
Else
Frm.Cell(k).Left = Frm.Cell(k - 1).Left + Frm.Cell(k - 1).Width
End If
Frm.Cell(k).Text = Tbl(i, j)
Condcoul Frm, k, Col, Lig 'condition couleur
End If
End If
k = k + 1
Next i
Next j
Frm.Cell(0).Width = var(0)
End Sub
'Place et rend visible les cellules que l'on souhaite voir
Public Sub ReGetCell(Départ As Integer, Frm As Form, ByVal Col As Integer, ByVal Lig As Integer, sCpt As Integer)
Dim k, i, j, PosX, PosY As Integer
PosY = Frm.Titre(0).Top + Frm.Titre(0).Height
PosX = Frm.Titre(0).Left
k = Départ 'N° de la 1ere cellule en haut à gauche
j = 0
'Efface toutes les cellules
For i = 0 To ((Col * Lig) - 1)
Frm.Cell(i).Visible = False
Next i
'Ne fait apparaitre que les cellules nécessaires
For i = Départ To ((Col * sCpt) + Départ - 1)
Frm.Cell(i).Visible = True
Next i
While k < (Départ + (Col * sCpt)) 'Ne place que les cellules concernées
If k = Départ Then 'Place en haut à gauche la cellule
Frm.Cell(k).Top = PosY
Frm.Cell(k).Left = PosX
k = k + 1
Else
For i = 0 To Col - 1
If k <> 1 Then
If k < ((Col * sCpt) + Départ) Then
If ((k) Mod (Col) = 0) Then 'Créé et place toutes les cellules qui sont du coté gauche
Frm.Cell(k).Top = Frm.Cell(k - 1).Top + Frm.Cell(k).Height 'le .top de la cellule précédente + la hauteur de la cellule
Frm.Cell(k).Left = Frm.Cell(Départ).Left
Else
'Crée et place toutes les autres cellules
Frm.Cell(k).Top = Frm.Cell(k - 1).Top
Frm.Cell(k).Left = Frm.Cell(k - 1).Left + Frm.Cell(k - 1).Width
End If
End If
Else 'si k =1
If i > 0 Then
If ((k) Mod (Col) = 0) Then
Frm.Cell(k).Top = Frm.Cell(k - 1).Top + Frm.Cell(k).Height 'le .top de la cellule précédente + la hauteur de la cellule
Frm.Cell(k).Left = Frm.Cell(Départ).Left
Else
Frm.Cell(k).Top = Frm.Cell(k - 1).Top
Frm.Cell(k).Left = Frm.Cell(k - 1).Left + Frm.Cell(k - 1).Width
End If
End If
End If
If k <> 1 Then k = k + 1
If ((k = 1) And (i <> 0)) Then k = k + 1
Next i
j = j + 1
End If
Wend
End Sub
'#####################################################################################################
'# Dessine le tableau avec un sélecteur, attention, il ne faut passer une rq contenant un n°auto #
'#####################################################################################################
'Dessine le tableau à partir de la requête sql - NA = NuméroAuto
Public Sub DesignTableNA(ByVal cn As ADODB.Connection, ByVal rs As ADODB.Recordset, sql As String, sCpt As Integer, Frm As Form, ParamArray var() As Variant)
Dim i, j, l, cpt, PosY, Col, Lig, tmp As Integer
rs.Open sql, cn, 1, 2
'sCpt Définition du nombre de lignes à partir desquelles le scroll va opérer
Col = rs.Fields.Count
Lig = rs.RecordCount
tmp = 0
'Définition du tableau récupérant les valeurs passées par la table
ReDim Tbl(Col - 1, Lig - 1) As Variant 'Chargement des dimensions réelles du tableau
PosY = Frm.Cell(0).Top 'de la cellule en haut à gauche
If var(0) <> 0 Then
Frm.Cell(0).Width = var(0) 'défini la taille des cellule
Frm.Titre(1).Width = var(0)
End If
For l = 0 To UBound(var)
tmp = tmp + var(l) 'Longueur d'une ligne
Next l
'Définition de la taille du cadre qui entoure les cellules.
Frm.Cadre.Height = ((Lig + 1) * Frm.Cell(0).Height) + 30 '+1 à cause des titres
Frm.Cadre.Width = tmp + Frm.Sélecteur(0).Width + 30 'Sélecteur + épaisseur => 375 + 30
'Rend visible, place et initialise les paramètre du VScroll
If Lig > sCpt Then
Frm.VScroll.Min = 1
Frm.VScroll.Max = Lig - sCpt + 1
Frm.VScroll.Visible = True
Frm.Blanc.Visible = True
Frm.VScroll.Left = Frm.Cell(0).Left + tmp
Frm.VScroll.Height = (sCpt) * Frm.Cell(0).Height
Frm.VScroll.Top = Frm.Cell(0).Top
Frm.Blanc.Left = Frm.VScroll.Left
Frm.Blanc.Top = Frm.Titre(1).Top
'Définition de la taille du cadre qui entoure les cellules en fonction du scroll
Frm.Cadre.Height = ((sCpt + 1) * Frm.Cell(0).Height) + 30
Frm.Cadre.Width = tmp + Frm.Sélecteur(0).Width + Frm.VScroll.Width + 30 'Sélecteur + Vscrool + épaisseur
End If
cpt = Col * Lig 'Nb de cellules totales
'Création des titres des cellules
For i = 1 To Col - 1
If i > 1 Then
Load Frm.Titre(i): Frm.Titre(i).Visible = True
Frm.Titre(i).Text = rs.Fields(i).Name
Frm.Titre(i).Width = var(i - 1)
Frm.Titre(i).Left = Frm.Titre(i - 1).Left + Frm.Titre(i - 1).Width
Frm.Titre(i).Top = Frm.Titre(1).Top
Else
'1er Vide
'On ne prend pas le titre du NuméroAuto c'est inutile
Frm.Titre(1).Text = rs.Fields(1).Name
End If
Next i
'Remplissage du tableau de Variant
j = 0
While rs.EOF = False
For i = 0 To (Col - 1)
'Si valeur null alors on insert une chaine vide dans le tableau
Tbl(i, j) = IIf(IsNull(rs.Fields(i)), vbNullChar, rs.Fields(i))
Next i
j = j + 1
rs.MoveNext
Wend
rs.Close
'Répartition des sélecteurs et des cellules
'Exemple de tableau, les chiffres représentant les index.
'------------------------
'|x |T1 |T2 |T3 |T4 |T5 |
'------------------------
'|0>| 1 | 2 | 3 | 4 | 5 |
'------------------------
'|1>| 6 | 7 | 8 | 9 |10 |
'------------------------
For j = 0 To (Lig - 1) 'j = 0 To (sCpt - 1)
For i = 0 To (Col - 1)
'Calcul position des cellules et des sélecteurs
Select Case i
Case 0 'Colonne du sélecteur
If (j = 0) Then '1er sélecteur
Frm.Sélecteur(0).Tag = Tbl(i, j) 'récupération de la clé primaire pr d'éventuelle manipulation
Else 'ligne suivante, on crée les autres sélecteur
Load Frm.Sélecteur(j)
If (j < (sCpt)) Then Frm.Sélecteur(j).Visible = True
Frm.Sélecteur(j).Tag = Tbl(0, j)
Frm.Sélecteur(j).Top = Frm.Sélecteur(0).Top + (Frm.Sélecteur(0).Height * j)
End If
Case Else 'On rentre dans les colonnes des cellules i > 0
tmp = 0 'Change la taille de Cell(0) afin que les cellules créée à partir de cell(0)
Frm.Cell(0).Width = var(i - 1) 'prennent la taille de cette dernière
Load Frm.Cell(i + ((Col - 1) * j))
If (j < (sCpt)) Then Frm.Cell(i + ((Col - 1) * j)).Visible = True
Frm.Cell(i + ((Col - 1) * j)).Text = Tbl(i, j)
Frm.Cell(i + ((Col - 1) * j)).Top = Frm.Sélecteur(j).Top
Frm.Cell(1).Left = Frm.Cell(0).Left
If (((i + ((Col - 1) * j)) - ((Col - 1) * (j - 1))) Mod (Col)) = 0 Then
Frm.Cell(i + ((Col - 1) * j)).Left = Frm.Cell(0).Left 'Si ce sont les cellules du coté gauche
Else 'pour les autres cellules, la position se fait par rapport à la précédente
Frm.Cell(i + ((Col - 1) * j)).Left = Frm.Cell(i + ((Col - 1) * j) - 1).Left + Frm.Cell(i + ((Col - 1) * j) - 1).Width
End If
Condcoul Frm, (i + ((Col - 1) * j)), Col, Lig 'condition couleur
End Select
Next i
Next j
End Sub
'########################################################################################################
'# Place et rend visible les cellules que l'on souhaite voir en fonction du scroll #
'########################################################################################################
Public Sub ReGetCellNA(Départ As Integer, Frm As Form, ByVal Col As Integer, ByVal Lig As Integer, sCpt As Integer)
Dim k, i, j As Integer
k = 0 'Compteur de ligne
j = 0
'Rend toutes les cellules et les sélecteurs invisibles
For i = 0 To ((Col - 1) * Lig)
Frm.Cell(i).Visible = False 'ion
Next i
For i = 0 To Lig - 1
Frm.Sélecteur(i).Visible = False
Next i
'Ne fait apparaître que les cellules nécessaires
For i = 1 + ((Départ - 1) * (Col - 1)) To (((Départ - 1) + sCpt) * (Col - 1))
Frm.Cell(i).Visible = True
Next i
For i = (Départ - 1) To ((sCpt - 1) + (Départ - 1))
Frm.Sélecteur(i).Visible = True
Next i
'Positionnement des cellules et des sélecteurs
For j = (Départ - 1) To ((sCpt - 1) + (Départ - 1))
For i = 0 To (Col - 1)
'Calcul position des cellules et des sélecteurs
Select Case i
Case 0 'Colonne des sélecteurs
If (j = (Départ - 1)) Then '1er sélecteur en haut à gauche
Frm.Sélecteur(Départ - 1).Top = Frm.Cell(0).Top 'récupère la position de départ de cell(0) qui ne bouge pas et qui est invisible
Else 'ligne suivante, on crée les autres sélecteur
Frm.Sélecteur(j).Top = Frm.Sélecteur(Départ - 1).Top + (Frm.Sélecteur(Départ - 1).Height * k)
End If
Case Else 'On rentre dans les colonnes des cellules i > 0
Frm.Cell(i + ((Col - 1) * j)).Top = Frm.Sélecteur(j).Top
'Frm.Cell(i + ((Col - 1) * j)).Left = Frm.Cell(0).Left + (Frm.Cell(0).Width * (i - 1))
If (((i + ((Col - 1) * j)) - ((Col - 1) * (j - 1))) Mod (Col)) = 0 Then
Frm.Cell(i + ((Col - 1) * j)).Left = Frm.Cell(0).Left 'Si ce sont les cellules du coté gauche
Else 'pour les autres cellules, la position se fait par rapport à la précédente
Frm.Cell(i + ((Col - 1) * j)).Left = Frm.Cell(i + ((Col - 1) * j) - 1).Left + Frm.Cell(i + ((Col - 1) * j) - 1).Width
End If
End Select
Next i
k = k + 1 'Incrémentation du compteur de ligne
Next j
End Sub
Conclusion :
La finalité de ce projet, serait en fait d'en faire un OCX, mais je n'ai pas encore les connaissances suffisantes dans ce domaine, il faudrait que je me penche sur la question etc. Bref, si quelqu'un taquine les OCX et veut bien en faire un à partir de mon code, j'en serait ravi ^^
Dernière petite chose, les form sont limités en nombre de controles, donc évitez de passer de trop gros tableaux dépassant les 3000 lignes...
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.