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]