Parcourir des enregistrements II

Retour vers Access

Parcourir des enregistrements 2

Malgré mes efforts dans le premier opus je constate que certains ont encore des difficultés pour comprendre la manipulation des recordsets.

Pour rappel, Access , par défaut, ne gère que l'enregistrement sélectionné (on dit aussi pointé). Le pointeur se présente sous la forme d'un petit triangle sur la gauche (ici entouré en rouge). Donc, Access ne peut utiliser que les infos '04/10/1994' , '9' et 'Poussin' ...du moins directement...

Pour accéder aux autres infos, il faut soit utiliser des fonctions soit utiliser la technique du recordset. Voilà le grand mot lâché...

Personnellement, j'utilise presque exclusivement la méthode DAO (voir premier opus). Elle est compatible Access 97

Un recordset est un ensemble d'enregistrements que vous allez reproduire en mémoire vive. Cet ensemble est défini par une instruction SQL. Je dis "Ensemble" car on n'est pas obligé de copier une table ou une requête entière dans un recordset. On peut très bien définir une clause WHERE dans l'instruction SQL.

Petite astuce en passant, vous n'êtes pas chevronné en langage SQL. Faites donc une requête, passez en mode construction SQL et récupérer le code par un copier-coller dans votre module

Comme tout le monde comprend mieux à partir d'un exemple concret, plantons le décor.

Nous créons une nouvelle base de données, dans laquelle nous initions des tables

  1. Créer une table T_Annees avec un champ Annee - type Numérique , entier avec les données : 2004, 2005
  2. Créer une table T_Collaborateurs avec un champ NomCollaborateur - type texte avec les données : John, Bill, Oscar
  3. Créer une table T_Projets avec un champ NomProjet - typeTexte avec les données Projet1, Projet2, Projet3
  4. Créer une table T_Globale avec 4 champs NomCollaborateur - type texte; NomAnnee - type numérique;NomProjet - type texte et NomMois - type texte

Déjà vous réalisez que le but de l'exercice sera de remplir la T_Globale en récupérant tour à tour les infos dans les autres tables et ceci pour les 12 mois de chaque année. Ce qui devrait conduire Access à ajouter 216 (3 collaborateurs * 3 Projets * 24 mois) enregistrements dans T_Globale

Notre but est maintenant connu, nous allons alors progresser par étapes (inutile de tenter d'atteindre le but directement, on s'y perdrait)

1ère étape, je crée la boucle pour récupérer les années

Sub Commande1_Click()
  'Déclarations obligatoires et préalables
  Dim db As DAO.Database
  Dim rs1 As DAO.Recordset
  'Variable locale
  Dim MonAnnee As Integer
  'Variables qui placent le recordset en mémoire vive
  Set db = Application.CurrentDb
  Set rs1 = db.OpenRecordset("Select * from T_Annees")
  'Logiquement Access doit commencer par traiter le 1er enregistrement
  'Mais il est préférable de s'en assurer
  rs1.MoveFirst
  'Ici, débute la boucle
  Do
    'On injecte le contenu du champ dans une variable
    MonAnnee = rs1("Annee")
    'Pour vérifier le fonctionnement de notre procédure
    MsgBox MonAnnee
    'On passe à l'enregistrement suivant
    rs1.MoveNext
    'Et ceci jusqu'à la fin du recordset
  Loop Until rs1.EOF = True
End Sub



ça marche ! J'obtiens tour à tour les messages suivants

     


2ème étape, pour traiter les collaborateurs, j'imbrique une seconde boucle dans la première et cela devient ceci

Sub Commande1_Click() 
  'Déclarations obligatoires et préalables. En pourpre, les lignes ajoutées 
  Dim db As DAO.Database
  Dim rs1 As DAO.Recordset
  Dim rs2 As DAO.Recordset 
  'Variable locale
  Dim MonAnnee As Integer, MonCollaborateur As String
 'Variables qui placent leS recordsetS en mémoire vive
  Set db = Application.CurrentDb
 'J ai cette fois 2 recordsets en mémoire 
  Set rs1 = db.OpenRecordset("Select * from T_Annees")
  Set rs2 = db.OpenRecordset("Select * from T_Collaborateurs")
  rs1.MoveFirst
  Do 
    MonAnnee = rs1("Annee")
    MsgBox MonAnnee
   'Si on compare avec la procédure précédente, on constate que c'est le même mécanisme
    rs2.MoveFirst
    Do 
      MonCollaborateur = rs2("NomCollaborateur")
      MsgBox MonCollaborateur MsgBox MonAnnee & " " & MonCollaborateur
      rs2.MoveNext
    Loop Until rs2.EOF = True 
    'C'est avant l'instruction MoveNext que je dois insérer la nouvelle boucle
    'Il faudra agir de la sorte pour chaque recordset à parcourir
     rs1.MoveNext
 Loop Until rs1.EOF = True
End Sub

3ème étape, bin je recommence pour la T_Projets et ça donne..

Sub Commande1_Click()
Dim db As DAO.Database
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rs3 As DAO.Recordset

Dim MonAnnee As Integer, MonCollaborateur As String, MonProjet As String

Set db = Application.CurrentDb
Set rs1 = db.OpenRecordset("Select * from T_Annees")
Set rs2 = db.OpenRecordset("Select * from T_Collaborateurs")
Set rs3 = db.OpenRecordset("Select * from T_Projets")

rs1.MoveFirst
Do
MonAnnee = rs1("Annee")
MsgBox MonAnnee

rs2.MoveFirst
Do
MonCollaborateur = rs2("NomCollaborateur")
MsgBox MonCollaborateur
MsgBox MonAnnee & " " & MonCollaborateur

rs3.MoveFirst
Do
MonProjet = rs3("NomProjet")
MsgBox MonProjet
MsgBox MonAnnee & " " & MonCollaborateur & " " & MonProjet
rs3.MoveNext
Loop Until rs3.EOF = True
'C'est bien juste avant le MoveNext que j'ai inclus ma 3ème boucle
rs2.MoveNext
Loop Until rs2.EOF = True

rs1.MoveNext
Loop Until rs1.EOF = True

End Sub

4ème étape, on s'occupe maintenant des mois; mais ici, ces infos ne sont pas dans une table, nous allons les produire grâce à une instruction DateSerial

Sub Commande1_Click()
Dim db As DAO.Database
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rs3 As DAO.Recordset
Dim MonAnnee As Integer, MonCollaborateur As String, MonProjet As String
Dim i As Integer, MonMois As String

Set db = Application.CurrentDb
Set rs1 = db.OpenRecordset("Select * from T_Annees")
Set rs2 = db.OpenRecordset("Select * from T_Collaborateurs")
Set rs3 = db.OpenRecordset("Select * from T_Projets")

rs1.MoveFirst
Do
MonAnnee = rs1("Annee")
MsgBox MonAnnee

rs2.MoveFirst
Do
MonCollaborateur = rs2("NomCollaborateur")
MsgBox MonCollaborateur
MsgBox MonAnnee & " " & MonCollaborateur

rs3.MoveFirst
Do
MonProjet = rs3("NomProjet")
MsgBox MonProjet
MsgBox MonAnnee & " " & MonCollaborateur & " " & MonProjet
'Production des mois
For i = 1 To 12
MonMois = Format(DateSerial(1, i, 1), "mmmm")
MsgBox MonMois
MsgBox MonAnnee & " " & MonCollaborateur & " " & MonProjet & " " & MonMois
Next i

rs3.MoveNext
Loop Until rs3.EOF = True

rs2.MoveNext
Loop Until rs2.EOF = True

rs1.MoveNext
Loop Until rs1.EOF = True

End Sub

Ultime étape, ajouter le contenu des variables vers la T_Globale (dans les 4 champs NomAnnee - NomCollaborateur - NomProjet - NomMois) et j'imbrique alors la commande AddNew , le nettoyage de la mémoire et je neutralise les Msgbox qui m'ont permis de visualiser ma progression

Sub Commande1_Click()
Dim db As DAO.Database
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
Dim rs3 As DAO.Recordset
Dim rs4 As DAO.Recordset

Dim MonAnnee As Integer, MonCollaborateur As String, MonProjet As String
Dim i As Integer, MonMois As String
Set db = Application.CurrentDb
Set rs1 = db.OpenRecordset("Select * from T_Annees")
Set rs2 = db.OpenRecordset("Select * from T_Collaborateurs")
Set rs3 = db.OpenRecordset("Select * from T_Projets")
Set rs4 = db.OpenRecordset("Select * from T_Globale")

rs1.MoveFirst
Do
MonAnnee = rs1("Annee")
'MsgBox MonAnnee

rs2.MoveFirst
Do
MonCollaborateur = rs2("NomCollaborateur")
'MsgBox MonCollaborateur
'MsgBox MonAnnee & " " & MonCollaborateur

rs3.MoveFirst
Do
MonProjet = rs3("NomProjet")
'MsgBox MonProjet
'MsgBox MonAnnee & " " & MonCollaborateur & " " & MonProjet

For i = 1 To 12
MonMois = Format(DateSerial(1, i, 1), "mmmm")
'MsgBox MonMois
'MsgBox MonAnnee & " " & MonCollaborateur & " " & MonProjet & " " & MonMois
'On AJOUTE les données dans la T_Globale
With rs4
.AddNew
!NomAnnee = MonAnnee
!NomCollaborateur = MonCollaborateur
!NomProjet = MonProjet
!NomMois = MonMois
.Update
End With

Next i

rs3.MoveNext
Loop Until rs3.EOF = True

rs2.MoveNext
Loop Until rs2.EOF = True

rs1.MoveNext
Loop Until rs1.EOF = True
'Instruction pour nettoyer la mémoire des recordsets inutiles;
'il fallait normalement le réaliser dans les autres procédures aussi
'mais j'ai préféré les mettre uniquement dans la procédure finale pour ne pas embrouiller les esprits
rs1.Close
rs2.Close
rs3.Close
rs4.Close

Set rs1 = Nothing
Set rs2 = Nothing
Set rs3 = Nothing
Set rs4 = Nothing
Set db = Nothing
End Sub

Bien sûr, il faudrait aussi créer une boucle dans rs4 si T_Globale n'était pas vide pour vérifier si les données que l'on veut ajouter n'existent pas déjà, il suffit pour cela d'utiliser un IF..THEN avant la commande AddNew

Cliquez ici pour télécharger le fichier exemple AjoutEnregistrementsII

Fin