Richard CHBEIR :
Transcription
Richard CHBEIR :
Visual Basic pour Applications DAO - ADO IQ2 – BDD © Richard CHBEIR : [email protected] 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 © [email protected] Introduction © [email protected] 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 © [email protected] Distinction VBA VB Complètement lié à un des produits Microsoft office Ne pourra en aucun cas s'exécuter de manière autonome. Access Basic 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. © [email protected] Version 1 et 2 d'Access Caracté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 © [email protected] Environnement de développement IDE Déclaration Exploration Fonction Fenêtre Code Procédure Propriétés © [email protected] Comment tester Exécution d’une procédure Fenêtre d’exécution Print ou ? © [email protected] Les composants Access © [email protected] 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. © [email protected] 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 © [email protected] Structure simplifiée du modèle Application Application Reports Screen DoCmd Control Debug Forms © [email protected] Properties Le langage VBA © [email protected] 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 © [email protected] 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 © [email protected] 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 © [email protected] 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 © [email protected] Porté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 © [email protected] Opérateurs Mathématiques +, -, *, /, ^ De comparaison <, <, =, <=, >=, <> Logiques AND, OR, NOT, EQV © [email protected] 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 © [email protected] 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) © [email protected] 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() © [email protected] Gestion d’erreurs 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 © [email protected] Fonctions inté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. © [email protected] 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 © [email protected] Méthodes d'accès aux données © [email protected] Méthodes d'accè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 ;) © [email protected] Le modèle DAO © [email protected] Le modèle DAO Access VBA DAO ODBCDirect ODBC Microsoft JET ISAM dbase *.mdb *.dbf ODBC SQL Server ODBC Oracle SQL Server 2000 Oracle © [email protected] Caracté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 ☺) © [email protected] Structure du modèle DAO DBEngine Parameters QueryDefs Connections Recordsets Workspaces Databases Errors Relations Fields TableDefs Indexes Containers Documents Groups Users © [email protected] 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 © [email protected] Tables Création (d'une table Etudiants avec deux champs Nom et Numéro) Sub Création_Table() '1Dim '1Dim '1Dim déclaration de la base db As database déclaration d'une variable de type Table definition_table As TableDef déclaration d'une variable de type champ 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 © [email protected] 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 © [email protected] 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 © [email protected] 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 © [email protected] Accéder aux enregistrement d'une table Plusieurs moyens, mais principalement : RecordSet © [email protected] 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 '2- Affectation dbOpensnapshot) DbOpentable) Set db = CurrentDb() Set tb_client = db.OpenRecordset("Clients", dbOpenDynaset) © [email protected] 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 © [email protected] 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 dans les enregistrements … donc le bookmark change ' Pour se repositionner à l'enregistrement ANTON tb_client.Bookmark = enregistrement © [email protected] 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 © [email protected] 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 'valeur 'valeur 'valeur 'valeur 'valeur du du du du du du champ nom_produit champ nom_produit champ nom_produit champ nom_produit premier champ premier champ © [email protected] 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 © [email protected] Ajout d'un enregistrement Elle se fait en respectant les étapes suivantes : 1. 2. Utiliser la méthode AddNew du Recordset pour créer un nouvel enregistrement vide et s’y positionner 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 © [email protected] 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 © [email protected] RecordSet Modification d ’enregistrements 1. 2. 3. 4. Se positionner sur l ’enregistrement à modifier Utiliser la méthode Edit Modifier la valeur des champs 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 © [email protected] RecordSet Suppression d ’enregistrements 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) 1. 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 © [email protected] RecordSet Tri de données 1. 2. 3. Ouvrir la table ou la requête avec RecordSet Utiliser la méthode Sort 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) © [email protected] Filtre de données Filtre de données 1. 2. 3. Ouvrir la table ou la requête avec RecordSet Utiliser la méthode Filtre 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) © [email protected] Le modèle ADO © [email protected] VC++ Access VBA/VB ASP Java Co n co OL mm E ate DB u rs Le modèle ADO Fo u O rnis LE se DB urs ADO Jet OLE MSIDXS Object ADSDSO SQLOLEDB MSDASQL ODBC Pilote ODBC SQL Server *.mdb Index Server Annuaire SQL Server 2000 © [email protected] 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 © [email protected] Caracté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 ☺ © [email protected] Structure simplifiée Source Exécuter Connection Exécuter Connexion Active Error Command RecordSet Field © [email protected] Parameter Instanciation des classes Syntaxe 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 © [email protected] 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. © [email protected] Les méthodes Connection Open Ouvre une connexion à une source de données Dim cn As New ADODB.Connection cn.open "Provider=Microsoft.Jet.OLEDB.4.0; Data source = c:\temp\Ma_Base.mdb" Execute 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’, …)") Close Ferme une connexion cn.close Set cn = nothing © [email protected] La classe Command Permet d'exécuter des commandes sur une source de données (des instructions SQL) Souvent avec des paramètres © [email protected] 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 © [email protected] 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 produits") © [email protected] * from La classe Command Exemple Dim cn As New ADODB.Connection cn.open "DSN=Base_Clients" ' Cela signifie qu'une source de données nommée Base_Client existe déjà 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 © [email protected] 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) © [email protected] La classe Recordset Trois possibilités d'instanciation via la méthode Execute de Connection Dim rs As New ADODB.recordset set rs = de cn.execute ("select [nom Client] from Clients") Execute Command Dim cmd As New ADODB.Command cmd.CommandText = "select * from Produits" set cmd.ActiveConnection = cn Dim rs As New ADODB.recordset = cmd.Execute Opensetders Recordset Dim rs As New ADODB.recordset rs.open "select * from Clients", "Base_Clients" © [email protected] Création d’un 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 table, … une chaîne contenant le DSN ou une réfé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 dès le début adLockOptimistic les enregistrements ne sont verrouillés qu’au moment de l’appel de la méthode update © [email protected] 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 © [email protected]