Visual Basic pour Applications DAO - ADO IQ2 BDD Richard CHBEIR : richard.chbeir@iut-dijon.u-bourgogne.fr Bibliographie : "VBA pour Access 2000", Edition Eyrolles, ISBN : 2-212-09100-1 "ASP 3.0 Professionnel", Edition Eyrolles, ISBN: 2-212-09151-6 "Programmation Access pour Windows 95", Edition Micro Application ISBN : 2-7429-0635-5 "Aide de Microsoft Access", F1
Plan du chapitre Introduction Les composants Access Les méthodes d'accès aux données Le modèle DAO Le modèle ADO Quelques conseils
Introduction
Définition VBA est un langage de programmation commun à tous les produits Microsoft Moyen rapide de développer Permet d'interagir avec l'environnement Windows Programmation événementielle Souris: Déplacement, clique du bouton droit, glisser, déplacer, etc. Clavier: saisie, touche relâchée, etc. Gestion des fenêtres Exécution des commandes systèmes Capable de gérer les erreurs
Distinction VBA Complètement lié à un des produits Microsoft office Ne pourra en aucun cas s'exécuter de manière autonome. VB Permet de créer des applications indépendantes Il existe cependant une version "Run time" d'access, nommée "Kit Office Développement Environnement (Kit ODE)", qui permet de distribuer une application développée sous Access sans avoir à installer Access sur les postes destinés à faire fonctionner cette application. Access Basic Version 1 et 2 d'access
Caractéristiques ristiques de VBA Syntaxe avec le code en couleur Explorateur d objets Aide contextuelle syntaxique depuis les lignes de code Possibilité de définir des segments de code se compilant conditionnellement Espions Points d arrêt
Environnement de développement IDE Exploration Déclaration Fonction Fenêtre Code Procédure Propriétés
Comment tester Fenêtre d exd exécution Exécution d une d procédure Print ou?
Les composants Access
Composants majeurs Access comporte deux composants : Microsoft Jet Contrôle le stockage des données Définit les objets de la BD Le moteur de l application Contrôle la programmation Contrôle l interface Comment ça fonctionne? Quand vous ouvrez une BD, le moteur de l application utilise Microsoft Jet pour déterminer les noms des tables, des requêtes, etc.
Microsoft Jet 4.0 C'est le Gestionnaire de fichiers Il possède les caractéristiques suivantes : Moteur à 32 bits Support Unicode Jeux de caractères à deux octets par caractère Types de données compatibles avec SQL Server SQL 92 Verrouillage amélioré des données
Structure simplifiée e du modèle Application Application Reports Screen DoCmd Control Properties Debug Forms
Le langage VBA
Types de données Byte entiers positifs compris entre 0 et 255, Boolean True et False, Integer ou % entiers entre -32 768 et 32 767, Currency ou @ valeurs entre -922 337 203 685 477,5808 et 922 337 203 685 477,5807 String ou $ Entre 0 et environ 63 Ko de caractères Long ou & entier -2 147 483 648 et 2 147 483 647
Types de données Decimal Single ou! Double ou # Date pour stocker les dates (1/01/100 31/12/9999) et les heures Object Tous types d'objets, Variant (Par défaut) Type de données particulier pouvant contenir des données numériques, des chaînes ou des dates, des types définis par l'utilisateur ainsi que les valeurs spéciales Empty et Null
Déclarations Des variables (DIM) DIM entier as INTEGER DIM type as Variant DIM x(10, 25) as Single REDIM x(10, 40) as INTEGER Des constantes (CONST) Const PI As Single = 3.14 Des structures de données définies par l utilisateur Type Adresse Numero as Integer NomRue as String * 30 Ville as String * 50 CodePostal as INTEGER End TYPE.. DIM Adresse_client as Adresse
Déclarations Des procédures (SUB) Sub Attribution_Note_Aleatoire() Dim Notes As Recordset... End Sub Des fonctions (function) Function NoteAleatoire() As Single Dim ValeurAlea As Single ValeurAlea = Rnd() * 20 NoteAleatoire = Format(ValeurAlea, "0.0") End Function
Portée e d'une variable Private Permet de définir des variables privées Une procédure privée englobe des variables privées Public (ou Global) Permet de définir des variables publiques Static Permet de (re)définir des variables dont le contenu est non modifiable
Opérateurs Mathématiques +, -, *, /, ^ De comparaison <, <, =, <=, >=, <> Logiques AND, OR, NOT, EQV
Branchement et boucles Instruction IF IF (a=5) Then Else ENDIF Instruction IIf(condition, truepart, falsepart) Instruction GOTO GoTO Fin.. :FIN Instruction FOR NEXT For i=1 to 10 --- Next i Instruction While While i<=10 --- Wend
Branchement et boucles Instruction DO..LOOP Do [{While Until} condition] [statements] Loop Vous pouvez également utiliser la syntaxe suivante : Do [statements] Loop [{While Until} condition] Instruction Select Case Select CASE valeur Case 0 to 2. Case 3 to 5 Case 6 Case ELSE END SELECT L instruction CALL Transfère le contrôle à une procédure ou à une Fonction (interne ou externe) Call MyProc(0)
Référencer des objets Plusieurs méthodes : NomCollection![Nom de l Objet] Ex: Forms![Clients] NomCollection("Nom de l Objet") Ex: Forms("Clients") NomCollection(Numéro de l Objet) Ex: Forms(0) et Forms(Forms.Count-1) Pour accéder à un sous-object ou à une méthode, on utilise aussi le. Ex: DBEngine.Workspaces(0).CurrentDB()
Gestion d erreursd On error Génération d'une constante Err Resume NEXT Le programme continue sans abandonner ERL Renvoie le numéro de la ligne où l erreur s est produite Err.Number Contient le code de l erreur Error$(Err) ou Err.Description Donne les détails de ERR On Error GoTo Err_Click. Err_Click: MsgBox Err.Number & " : " & Err.Description
Fonctions intégr grées Sur les chaînes Left (chaîne, taille), Right, Replace, etc. Arithmétiques ABS, LOG, EXP, etc. Commandes CHDIR, CHDRIVE, DIR, MKDIR, RMDIR, etc. Heure/date Date$, Now, etc. Affichage MSGBOX, INPUTBOX$, etc.
Librairies Les librairies proposées dans très variées Pour les intégrer dans un module: Dans l'ide de Visual Basic Outils/références Intégrer seulement les librairies concernées, sinon
Méthodes d'accès s aux données
Méthodes d'accès s aux données Plusieurs librairies sont proposées. Mais Principalement : DAO (Data Access Objects) Interface permettant l'accès aux données qui communique avec Microsoft Jet et des sources de données compatibles ODBC pour se connecter à, récupérer, manipuler et mettre à jour des données et la structure de base de données. ADO (ActiveX Data Objects) Interface d'accès aux données qui communique avec des sources de données compatibles OLE DB pour la connexion, la récupération, la manipulation et la mise à jour de données (Via le Web par exemple ;)
Le modèle DAO
Le modèle DAO Access VBA DAO ODBCDirect Microsoft JET ODBC ISAM dbase ODBC SQL Server ODBC Oracle *.mdb *.dbf SQL Server 2000 Oracle
Caractéristiques ristiques de DAO Adapté à la gestion des BD hétérogènes Oracle, SQL server, Access, Sybase, Paradox, etc. Conçu pour des applications client/serveur Dépend d'un groupe international (et pas de Microsoft )
Structure du modèle DAO DBEngine Parameters QueryDefs Connections Recordsets Workspaces Databases Relations Fields Errors Groups TableDefs Indexes Users Containers Documents
Accès à une BD Ouverture OpenDataBase(Name, Exclusif, ReadOnly) Fermeture Close Exemple (Déclaration de trois bases) Sub Accès_femeture_base() ' 1- Déclaration des bases DIM MaBD1 As DataBase DIM MaBD2, MaBD3 As DataBase.... ' 2- Affectation des bases Set MaBD1 = OpenDataBase("c:\temp\fichierDB1.mdb") ' base locale Set MaBD2 = OpenDataBase("\\serveur_IUT\Partage\fichierDB2.mdb", TRUE) ' base partagée en mode exclusif Set MaBD3 = OpenDataBase("fichierDB3.mdb", FALSE, TRUE) ' base locale ouverte en lecture seule.... ' 3- Fermer les bases MaBD1.Close MaBD2.Close MaBD3.Close End Sub
Tables Création (d'une table Etudiants avec deux champs Nom et Numéro) Sub Création_Table() '1- déclaration de la base Dim db As database '1- déclaration d'une variable de type Table Dim definition_table As TableDef '1- déclaration d'une variable de type champ Dim champ_nom, Champ_Num As Field.... '2- Affectation Set db = currentdb() Set definition_table = db.createtabledef("etudiant") Set champ_nom = definition_table.createfield("nom", dbtext, 50) Set champ_num = definition_table.createfield("numéro", dbinteger) definition_table.fields.append champ_nom definition_table.fields.append champ_num.... '3- Sauvegarder Db.TableDefs.Append definition_table End Sub
Tables Suppression (de la table Etudiants) Sub Suppresion_table() '1- déclaration de la base Dim db As database '2- Affectation Set db = currentdb() ' Suppresion de la table Db.TableDefs.Delete "Etudiants" End Sub Déclaration (d'une variable qui représente la table Etudiants) Sub Attribution_table() '1- déclaration de la base Dim db As Database Dim definition_table As Recordset '2- Affectation Set db = CurrentDb() Set definition_table = db.openrecordset("etudiants", dbopendynaset) End Sub
Requêtes Création (d'une requête des Clients lyonnais) Sub création_requete() '1- déclaration Dim db As Database Dim definition_requete As QueryDef '2- Affectation Set db = CurrentDb() Set definition_requete = db.createquerydef("clients Lyonnais", "Select * from Clients where Ville='Lyon'") End Sub Suppression (de la requête Client lyonnais) Sub Suppresion_requête() '1- déclaration de la base Dim db As database '2- Affectation Set db = currentdb() ' Suppresion de la requete Db.QueryDefs.Delete "Clients Lyonnais" End Sub
Requêtes Déclaration (de la requête Clients lyonnais) Sub Attribution_requete() '1- déclaration de la base Dim db As Database Dim requete As Recordset '2- Affectation Set db = CurrentDb() Set requete = db.openrecordset("clients lyonnais", dbopendynaset) End Sub Sub Attribution_requete_methode2 () '1- déclaration de la base Dim db As Database Dim requete As Recordset Dim definition_requete As QueryDef '2- Affectation Set db = CurrentDb() Set definition_requete = db.querydefs("clients lyonnais") Set requete = definition_requete.openrecordset(dbopendynaset) End Sub
Accéder aux enregistrement d'une table Plusieurs moyens, mais principalement : RecordSet
RecordSet Applicable sur les tables et les requêtes Trois éléments sont essentiels La base de données concernée Les enregistrements dans la base Le type de RecordSet Déclaration d'une variable Pour représenter la table "Clients" '1- déclaration des variables Dim db As Database Dim tb_clients As Recordset dbopensnapshot) '2- Affectation DbOpentable) Set db = CurrentDb() Set tb_client = db.openrecordset("clients", dbopendynaset)
RecordSet Propose plusieurs méthodes : De positionnement MoveFirst MoveNext MoveLast MovePrevious Move n BOF, EOF De recherche FindFirst FindLast FindNext FindPrevious De manipulation Delete Update Edit Addnew Field Requery (mise-à-jour) Diverses Bookmark RecordCount
RecordSet Positionnement sur un enregistrement Propriété Bookmark Indique l enregistrement courant Cette propriété mise à jour à chaque déplacement dans le recordset Exemple Dim db As Database Dim tb_clients As Recordset Dim enregistrement As Variant '2- Affectation Set db = CurrentDb() Set tb_client = db.openrecordset("clients", dbopendynaset) tb_client.findfirst "[Code Client] = 'ANTON'" enregistrement = tb_client.bookmark ' on se déplace d dans les enregistrements donc le bookmark change ' Pour se repositionner à l'enregistrement ANTON tb_client.bookmark = enregistrement
RecordSet Méthodes FindFirst FindLast FindNext FindPrevious Permet de trouver un enregistrement selon un critère donné utilisation des opérateurs de comparaison, logique, et/ou de l opérateur LIKE Exemple On veut savoir si on a des clients dont le code commence par A '1- déclaration des variables Dim db As Database Dim tb_clients As Recordset '2- Affectation Set db = CurrentDb() Set tb_client = db.openrecordset("clients", dbopendynaset) '3- Rerchercher les clients dont le code commence par A tb_client.findfirst "[Code Client] LIKE 'A*'" '4- Affichage d'un message quand l'enregistrement est trouvé If Not tb_client.nomatch Then MsgBox "trouvé" End If
Comment accéder à un champ? En utilisant Fields : stocke les différents champs d un enregistrement. Chaque champ est représenté par un objet instance de la classe Field Le nombre de Fields est déterminé par la méthode Count Remarque : la classe field permet de représenter un champ. On y trouve principalement les propriétés name et value qui renvoie respectivement le nom et la valeur du champ. Exemple Dim rs As Recordset rs.fields("nom_produit") rs ("nom_produit") rs.[nom_produit] rs![nom_produit] rs.fields(1) rs(1) 'valeur du champ nom_produit 'valeur du champ nom_produit 'valeur du champ nom_produit 'valeur du champ nom_produit 'valeur du premier champ 'valeur du premier champ
Question 1 Comment afficher la liste des champs de la table "Etudiants" ainsi que le contenu de chaque champ? Sub afficher_contenu_table_clients() Dim db As Database Dim tb_clients As Recordset Set db = CurrentDb() Set tb_client = db.openrecordset("clients", dbopendynaset) For i = 0 To tb_client.fields.count - 1 Debug.Print tb_client.fields(i).name Next i While Not tb_client.eof For i = 0 To tb_client.fields.count - 1 Debug.Print tb_client.fields(i).value Next i tb_client.movenext Wend End Sub
Ajout d'un enregistrement Elle se fait en respectant les étapes suivantes : 1. Utiliser la méthode AddNew du Recordset pour créer un nouvel enregistrement vide et s y positionner 2. Donner une valeur aux champs (Fields) du Recordset On peut également passer ces valeurs comme paramètres de la méthode AddNew 3. Utiliser la méthode Update du Recordset pour enregistrer le nouvel enregistrement dans la base On peut utiliser la méthode CancelUpdate pour annuler la création
RecordSet Exemple d'ajout On veut ajouter le client IQ2 ayant le code 'IUTIQ' Dim db As Database Dim tb_clients As Recordset Set db = CurrentDb() Set tb_client = db.openrecordset("clients", dbopendynaset) '1- Demander la création Tb_client.AddNew '2- Fournir les valeurs des champs Tb_client.[Code Client] = "IUTIQ" Tb_client![Nom] = "IQ2" '3- Enregistrer les données Tb_client.Update
RecordSet Modification d enregistrements 1. Se positionner sur l enregistrement à modifier 2. Utiliser la méthode Edit 3. Modifier la valeur des champs 4. Utiliser la méthode update Exemple On veut changer le nom du client dont le code est 'ANTON' Dim db As Database Dim tb_clients As Recordset Set db = CurrentDb() Set tb_client = db.openrecordset("clients", dbopendynaset) tb_client.findfirst "[Code Client] = 'ANTON'" ' On aurait pu faire directement 'Set tb_client = db.openrecordset("select * from Clients where [Code client] = 'ANTON'") If Not tb_client.nomatch Then 'If (tb_client.recordcount!= 0) Then MsgBox "trouvé" tb_client.edit tb_client.[nom] = "Richard CHBEIR" tb_client.update End If
RecordSet Suppression d enregistrements 1. Se positionner sur l enregistrement à supprimer 2. Utiliser la méthode delete Remarque : l enregistrement courant n est plus valide pensez donc à le déplacer (avec MoveNext ou autres) Exemple Supprimer le client dont le Code est ANTON Dim db As Database Dim tb_clients As Recordset Set db = CurrentDb() Set tb_client = db.openrecordset("clients", dbopendynaset) tb_client.findfirst "[Code Client] = 'ANTON'" ' On aurait pu faire directement 'Set tb_client = db.openrecordset("select * from Clients where [Code client] = 'ANTON'") tb_client.delete tb_client.movenext
Tri de données RecordSet 1. Ouvrir la table ou la requête avec RecordSet 2. Utiliser la méthode Sort 3. Copier le résultat dans une autre RecordSet Exemple Trier les clients par ordre décroissant Dim db As Database Dim enregistrement, enregistrement_trie As Recordset Set db = CurrentDb() Set enregistrement = db.openrecordset("select * FROM Clients") ' ou Set enregistrement = db.openrecordset("clients", dbopendynaset) ' Attention ' Set enregistrement = db.openrecordset("clients") ne marche pas enregistrement.sort = "Nom DESC" Set enregistrement_trie = enregistrement.openrecordset(dbopendynaset dbopendynaset)
Filtre de données Filtre de données 1. Ouvrir la table ou la requête avec RecordSet 2. Utiliser la méthode Filtre 3. Copier le résultat dans une autre RecordSet Exemple Trouver les clients dont le nom est IQ2 ou le code postal commence par 21 Dim db As Database Dim enregistrement, enregistrement_filtre As Recordset Set db = CurrentDb() Set enregistrement = db.openrecordset("clients"), dbopendynaset) enregistrement.filter = "[Nom] = 'IQ2' Or [Code Postal] like '21*'" Set enregistrement_filtre = enregistrement.openrecordset(dbopendynaset dbopendynaset)
Le modèle ADO
Le modèle ADO Concommateurs OLE DB VC++ Access VBA/VB ASP Java ADO Fournisseurs OLE DB Jet OLE Object MSIDXS SQLOLEDB MSDASQL ADSDSO ODBC Pilote ODBC SQL Server *.mdb Index Server Annuaire SQL Server 2000
Fournisseurs OLE DB Jet OLE DB 4.0 Pour les BD Access SQL Server Oracle ODBC Drivers Pour les sources de données ODBC OLAP Services Pour le serveur OLAP Microsoft (Exchange Server) Simple Provider Pour les fichiers de texte simples Microsoft Directory Services Pour Active Directory sous Windows 2000 Internet Publishing Pour l'accès aux serveurs Web DTS packages Pour les services de conversion de données SQL server
Caractéristiques ristiques de OLE DB et ADO Adaptés à la gestion de toute source de données BD, systèmes de messagerie, service d'annuaires, serveurs Web, etc. Conçus pour des applications orientées Internet Jeux d'enregistrements déconnectés, meilleure gestion des utilisateurs, etc. Dépend complètement de Microsoft
Structure simplifiée Connection Exécuter Connexion Active RecordSet Source Exécuter Command Error Field Parameter
Syntaxe Instanciation des classes Dim nom_variable As [New] ADODB.nom_classe Exemple Dim cn As New ADODB.Connection Dim cmd As New ADODB.Command Dim rst As New ADODB.Recordset
La classe Connection Permet la connexion à une source de données. Un objet de cette classe identifie une et une seule connexion à une source de données Permet l'exécution de commandes Requête de mise à jour, d'insertion, de suppression, etc.
Les méthodes m Connection Open Ouvre une connexion à une source de données Dim cn As New ADODB.Connection cn.open cn.open "Provider=Microsoft.Jet.OLEDB.4.0; Data source = c:\temp temp\ma_base.mdb" Execute Close Exécute une requête et récupère le résultat dans un RecordSet Dim rs1, rs2 As New ADODB.Recordset Set rs1 = cn.execute("select [nom Client] from Clients") cn.execute("insert into ma_table values (5, abc, )") Ferme une connexion cn.close Set cn = nothing
La classe Command Permet d'exécuter des commandes sur une source de données (des instructions SQL) Souvent avec des paramètres
La classe Command Propriétés.CommandText : stocke le texte de la commande Ex : objet_cmd.commandtext = "select * from Clients".ActiveConnection : permet de choisir la connexion (donc la base) sur laquelle s exécutera la commande Ex : set objet_cmd.activeconnection = cn
La classe Command Méthode Execute : permet d exécuter la commande Sans paramètre (stockée dans la propriété CommandText) Ex: objet_command.execute Avec paramètre Ex: objet_command.execute("select * from produits")
La classe Command Exemple Dim cn As New ADODB.Connection cn.open "DSN=Base_Clients Base_Clients" ' Cela signifie qu'une source de données nommée Base_Client existe déjàd dans ODBC Dim cmd As New ADODB.Command cmd.commandtext = "select * from Clients" Set cmd.activeconnection = cn Dim rs As New ADODB.recordset Set rs = cmd.execute
La classe Recordset Permet de contenir l'ensemble des données extraites des sources Stocke le résultat de l exécution d une commande sous forme d un ensemble de lignes Seule la ligne courante est visible (Notion de curseur)
La classe Recordset Trois possibilités d'instanciation via la méthode Execute de Connection Dim rs As New ADODB.recordset set rs cn.execute("select [nom Client] from Clients") Execute rs = de cn.execute Command Dim cmd As New ADODB.Command cmd.commandtext = "select * from Produits" set cmd.activeconnection = cn Dim rs As New ADODB.recordset rs = cmd.execute Open set de rs Recordset Dim rs As New ADODB.recordset rs.open "select * from Clients", "Base_Clients" Base_Clients"
Création d un d Recordset Syntaxe générale de la méthode open objet_recordset.open une_instruction connection_active lock_type requête sql,, nom d une d table, une chaîne contenant le DSN ou une référence r rence à un objet de la classe connection Une constante qui prend une des valeurs suivantes : adlockreadonly les données ne peuvent pas être modifiées adlockpessimisticles enregistrements sont verrouillés s dès d s le débutd adlockoptimistic les enregistrements ne sont verrouillés s qu au moment de l appel l de la méthode m update
Conseils Optimiser votre application Réduire la consommation de mémoire Utilisez le bon type de données Regroupez les procédures dans les modules Ne chargez pas les bibliothèques inutiles Augmenter la vitesse d'exécution Réduire les portions code Utilisez les constantes Accroître la vitesse perçue Pré-charger et masquer des formulaires Stocker localement les données dans un cache Compacter la base Commentez votre code