FAQ MS-Access

FAQ MS-AccessConsultez toutes les FAQ
Nombre d'auteurs : 140, nombre de questions : 926, dernière mise à jour : 15 juin 2021
Sommaire→Administrer une base de données- Comment déconnecter les utilisateurs d'une base de données ?
- Comment documenter une base Access ?
- Comment ouvrir une base en mode exclusif ?
- Comment programmer une date d'expiration pour une application ?
- Comment inhiber la touche MAJ au démarrage ?
- Comment afficher la liste des utilisateurs connectés à une BDD ?
- Comment concevoir un formulaire login/mot de passe ?
- Comment lister les tables liées ?
- Comment dans du code vérifier qu'un utilisateur appartient à un groupe ?
- Comment tester la version d'Access utilisée ?
- Comment nettoyer le journal des connexions afin d'enlever les utilisateurs qui ne sont en fait plus connectés ?
- Comment réparer une base Access par décompilation ?
- Pourquoi l'erreur : "Signet non valide" à l'ouverture de ma base de données ?
- Comment faire si je dois reprendre une application Access et que tout est sur le serveur (formulaires, états...) ?
- Comment gérer le fait que plusieurs utilisateurs aient accès à mon application ?
- Pourquoi les formulaires de mon application partagée sont-ils très longs à ouvrir ?
- Comment modifier le mot de passe de la base de données en VBA ?
- Comment ajouter/modifier une propriété sur une base de données ?
L'idée est que le formulaire principal de l'application sache quand il faut lancer la routine de déconnexion des utilisateurs.
Pour cela, on crée une table avec un seul champ de type oui/non et un seul enregistrement : Administration(LogOff(oui/non)).
L'administrateur de la base peut ensuite cacher cette table (propriétés de la table, cocher Masqué) et lui seul peut cocher la case LogOff.
Il faut maintenant utiliser l'événement minuterie du formulaire principal qui lance la vérification de la routine qui déconnectera
les utilisateurs (on utilise un intervalle de 5 minutes).
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Private Sub Form_Timer()
On Error GoTo Err_LogOffChk
Dim Lancer As Boolean
Dim rcd As DAO.Recordset
Set rcd = CurrentDb.OpenRecordset("Administration")
rcd.MoveFirst
Lancer = rcd.Fields(0)
rstLO.Close
CurrentDb.Close
' --Si la case est cochée
If Lancer Then Application.Quit acQuitSaveAll
Exit_LogOff:
Exit Sub
Err_LogOffChk:
MsgBox Err.Number & vbCrLf & Err.Description, vbInformation, "Erreur"
Resume Exit_LogOff
End SubLien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Lien : Comment utiliser une application en mode multi-utilisateur par Dolphy35
Menu Outils/Analyse/Documentation.
Lien : Comment sortir un descriptif détaillé de toutes ses tables et de leurs attributs ?
Function Ouvrir_Base_Exclusif()
Dim Bd As Database
On Error Resume Next
Set Bd = DbEngine (0).OpenDatabase("C:\Ma_base.mdb", True)
If Err.Number<> 0 Then
Msgbox Err.Number & " Impossible d\'ouvrir la base en mode Exclusif " & vbcrlf & Err.Description, VbInformation
Else
MsgBox "La base de données est ouverte en mode exclusif.", VbInformation
End If
End FunctionSi on obtient le numéro d'erreur 3262, c'est que la base est ouverte en mode partagé par un autre utilisateur.
Pour mettre une date d'expiration à la base et désactiver le run-time de votre application Access, appelez cette fonction à l'ouverture du formulaire de démarrage
Public Function DateExpirationApplication()
If Date >= DateSerial(2003, 12, 31) Then
MsgBox "La date d\'expiration de l\'application est dépassée", vbExclamation
DoCmd.Quit
End If
End FunctionIl est parfois intéressant d'inhiber l'effet de la touche MAJ (ne pas exécuter les événements de chargement de la base) pour ne pas afficher le conteneur de la base à l'utilisateur. Pour cela on dispose de deux procédures, l'une qui l'inhibe SetBypassProperty, l'autre qui l'active UnSetBypassProperty.
Sub SetBypassProperty()
Const DB_Boolean As Long = 1
ChangeProperty "AllowBypassKey", DB_Boolean, False
End Sub
Sub UnSetBypassProperty()
Const DB_Boolean As Long = 1
ChangeProperty "AllowBypassKey", DB_Boolean, True
End Sub
Function ChangeProperty(strPropName As String, varPropType As Long, varPropValue As Variant) As Integer
Dim dbs As Database, prp As Variant
Const conPropNotFoundError = 3270
Set dbs = CurrentDb
On Error GoTo Change_Err
dbs.Properties(strPropName) = varPropValue
Change_Bye:
Exit Function
Change_Err:
If Err = conPropNotFoundError Then ' Propriété non trouvée.
Set prp = dbs.CreateProperty(strPropName, _
varPropType, varPropValue)
dbs.Properties.Append prp
Resume Next
Else
' --Erreur inconnue.
Resume Change_Bye
End If
End FunctionLien : Comment empêcher le lancement du formulaire de démarrage ou de la macro AUTOEXEC ?
Pour connaître la liste des connectés à une base de données, il suffit d'explorer le fichier .ldb. Pour ce faire, on aura besoin de définir un type :
Private Type Un_Connecté
' --Nom PC
PC(1 To 32) As Byte
' --Nom utilisateur
User(1 To 32) As Byte
End TypeCette fonction renvoie alors la chaîne des connectés :
Public Function WHO_IS() As String
' -- Retourne une liste séparée par des points-virgules indiquant le nom de l'ordinateur ainsi que
' -- L'utilisateur connecté à la base.
On Error GoTo Err_WHO_IS
Dim Mon_LDB As Integer, i As Integer
Dim Mon_Chemin As String
Dim Mon_Log As String, Ma_Connexion As String
Dim Nom_PC As String, Nom_Utilisateur As String
Dim utilisateur As Un_Connecté
Mon_Chemin = CurrentDb.Name
CurrentDb.Close
' --Aller chercher le LDB
Mon_Chemin = Left(Mon_Chemin, InStr(1, Mon_Chemin, ".")) + "LDB"
Mon_LDB = FreeFile
' --Ouvrir le LDB
Open Mon_Chemin For Binary Access Read Shared As Mon_LDB
' -- Lire le LDB
Do While Not EOF(Mon_LDB)
' -- Chaque enregistrement lu est placé dans la variable utilisateur pour y être traité.
Get Mon_LDB, , utilisateur
With utilisateur
i = 1
Nom_PC = ""
' -- Nom du PC
While .PC(i) <> 0
Nom_PC = Nom_PC & Chr(.PC(i))
i = i + 1
Wend
i = 1
Nom_Utilisateur = ""
' -- Nom de l'utilisateur
While .User(i) <> 0
Nom_Utilisateur = Nom_Utilisateur & Chr(.User(i))
i = i + 1
Wend
End With
Mon_Log = Nom_PC & " | " & Nom_Utilisateur
If InStr(Ma_Connexion, Mon_Log) = 0 Then
Ma_Connexion = Ma_Connexion & Mon_Log & ";"
End If
Loop
Close Mon_LDB
' --WHO_IS contient la liste des utilisateurs
WHO_IS = Ma_Connexion
Exit_WHO_IS:
Exit Function
Err_WHO_IS:
MsgBox Err.Number & vbCrLf & Err.Description, vbInformation, "Erreur"
Close Mon_LDB
Resume Exit_WHO_IS
End FunctionPour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Le formulaire login/mot de passe permettra à un utilisateur de s'identifier et à la base de le reconnaître et de décider de lui donner
ou non la permission d'accéder à la base. Pour ce faire, on aura besoin d'une table T_User et d'un formulaire " F_Connexion ".
Table T_User (TRIGRAMME, NOM, PRENOM, GROUPE, PASWD) tous les champs sont de type texte. Un enregistrement exemple
de cette table : T_User(SED, SEBASTIEN, DULOT, Administrateur, root).
L'événement on_click du bouton Connexion :
Private Sub connexion_Click()
Me.Requery
Dim sql, User_id, User_groupe As String
Dim rs As DAO.Recordset
Static i As Byte
sql = "SELECT * FROM T_USERS WHERE TRIGRAMME = \'" & Me.txt_user & "\' AND PASWD =\'"& Me.txt_pass & "\';"
Set rs = CurrentDb.OpenRecordset(sql)
If Not rs.EOF Then
DoCmd.OpenForm "F_Autre_Formulaire", acNormal, , , , acWindowNormal
DoCmd.close acForm, "F_CONNEXION"
User_id = rs("TRIGRAMME").value
User_groupe = rs("GROUPE").value
Else
MsgBox "(Identifiant, Mot de Passe) incorrect ", vbInformation, "Connexion"
i = i + 1
End If
If i = 3 Then
Msgbox "Vous avez dépassé le nombre de tentatives autorisées", vbCritical
DoCmd.Quit
End If
End SubLien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Pour connaître l'origine des tables liées, il suffit d'explorer la table MSysObjects. Vous pouvez alors créer un formulaire avec trois zones de texte dans la section détail : Nom de la table, Nom étranger de la table, Chemin de la table. Dans la source de données du formulaire, il faut mettre cette requête :
SELECT Name, ForeignName, Database
FROM MSysObjects
WHERE MSysObjects.Type=6;N'oubliez pas de renseigner la source de données des zones de texte.
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Exemple en DAO :
Dim Utilisateur As DAO.User, MonGroup As DAO.Group
Set Utilisateur = DBEngine.Workspaces(0).Users(DBEngine.Workspaces(0).UserName)
For Each MonGroup In Utilisateur.Groups
If MonGroup.Name = "Admins" Then
MsgBox Utilisateur.Name & " est dans le groupe " & MonGroup.Name
Exit For
End If
NextLien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Dim Valeur As Variant
Valeur = SysCmd(acSysCmdAccessVer)Si Valeur vaut 8.0, la version est Access97. 9.0 correspond à Access 2000, etc.
Pour exécuter ce code, il faut activer les références : Microsoft DAO 3.x Object Library, Microsot ADO Ext 2.X for dll and security et Microsof ActiveX Data Object 2.X Library.
Const JET_SCHEMA_USERROSTER = "{947bb102-5d43-11d1-bdbf-00c04fb92675}"
Sub WriteUserConnected()
'To determine who is logged onto a database
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim i, j As Long
Dim rsUC As DAO.Recordset
Set rsUC = db.OpenRecordset("T_USER_CONNECTED", dbOpenDynaset)
Set cn = CurrentProject.Connection
' The user roster is exposed as a provider-specific schema rowset
' in the Jet 4.0 OLE DB provider. You have to use a GUID to
' reference the schema, as provider-specific schemas are not
' listed in ADO's type library for schema rowsets
Set rs = cn.OpenSchema(adSchemaProviderSpecific, , JET_SCHEMA_USERROSTER)
' Output the list of all users in the current database.
db.Execute "DELETE * FROM T_USER_CONNECTED"
While Not rs.EOF
With rsUC
.AddNew
!COMPUTER_NAME = rs.Fields(0)
!LOGIN_NAME = rs.Fields(1)
!CONNECTED = rs.Fields(2)
!SUSPECTED_STATE = rs.Fields(3)
.Update
End With
rs.MoveNext
Wend
End SubPensez à créer une table T_USER_CONNECTED.
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Il y a beaucoup de messages qui évoquent des applications corrompues qu'il faut reprendre en exportant tout ce qui peut l'être dans un nouveau fichier .mdb, les problèmes de mémoire "written" "read", etc.
Bien souvent, ces problèmes pourraient être résolus par une décompilation.
Je m'explique:
L'application Access permet d'utiliser différentes options dans la ligne de commande de démarrage.
Dans l'aide, chercher :
>> Options de la ligne de commande de démarrage
Il existe une option non documentée /decompile ; elle permet de remettre en ordre de marche une application MDB qui donne des signes de dysfonctionnement incompréhensibles.
Voici un exemple d'utilisation:
"C:\Program Files\Microsoft Office\Office\MSACCESS.EXE" "d:\bd1.mdb" /decompile
Il existe beaucoup de pages sur le web qui traitent la question.
Entre autres, le lien:
http://www.granite.ab.ca/access/decompile.htm
CONSEILS :
1. Faire une sauvegarde du fichier avant de le décompiler.
2. Après avoir décompilé le fichier, le compacter pour récupérer tout l'espace libéré par la décompilation.
CERISE SUR LE GÂTEAU DE LA BASE DE REGISTRE :
Astuce pour ne plus avoir à retaper toujours et encore cette sacrée ligne de commande, ni créer des raccourcis ad hoc.
Sur mon PC, j'ai modifié la base de registre de Windows pour que le menu contextuel géré par le bureau (Windows explorer inclus) donne enfin un accès rapide aux fonctions de décompactage et de décompilation.
Le code qui suit doit être copié dans un fichier nommé [AccessDecomp.reg] (c'est l'extension .reg qui importe).
Il ne reste plus qu'à l'exécuter pour enrichir le menu contextuel.
ATTENTION : ceci ne convient que pour Access 2000 (version 9).
Pour d'autres versions merci d'adapter à votre cas et de nous communiquer les modifications utiles.
REGEDIT4
[HKEY_CLASSES_ROOT\Access.Application.9\shell]
[HKEY_CLASSES_ROOT\Access.Application.9\shell\Compacter]
"EditFlags"=hex:01,00,00,00
@="&Compacter"
[HKEY_CLASSES_ROOT\Access.Application.9\shell\Compacter\command]
@="\"C:\\Program Files\\Microsoft Office\\Office\\MSACCESS.EXE\" \"%1\" /COMPACT "
[HKEY_CLASSES_ROOT\Access.Application.9\shell\Décompiler]
"EditFlags"=hex:01,00,00,00
@="&Décompiler"
[HKEY_CLASSES_ROOT\Access.Application.9\shell\Décompiler\command]
@="\"C:\\Program Files\\Microsoft Office\\Office\\MSACCESS.EXE\" \"%1\" /DECOMPILE "Hélas, même si décompiler apporte souvent une solution, il n'empêche que de temps à autre il faut quand même "reprendre" un fichier .mdb récalcitrant. Et, à mon avis, c'est le pire défaut d'Access et c'est un énorme défaut !!!
Cela signifie que le fichier de la base de données est corrompu. Dans la plupart des cas, un simple compactage de la base de données ou une réparation avec l'utilitaire JetComp sera suffisant.
Si cela ne résout pas le problème, il vous faudra importer un à un chacun des objets dans une nouvelle base de données.
Si jamais vous devez travailler sur une base de données ne respectant pas le schéma classique de Client/Serveur il faut que vous sépariez :
- les tables (qui restent sur le serveur), -> n'oubliez pas la sauvegarde quotidienne ;
- de l'application : tout le reste ainsi que les mêmes tables, mais attachées. -> pas besoin de sauvegardes tous les jours, juste une seule copie de sauvegarde pour tout le monde.
Une fois ces modifications apportées vous allez constater des performances hors du commun (il n'est pas rare de voir des formulaires mettre jusqu'à 20 minutes pour s'ouvrir, lorsque l'application est sur le serveur, puis 15 à 30 secondes, après avoir recopié l'application localement...).
Lien : Comment gérer le fait que plusieurs utilisateurs aient accès à mon application ?
Tout d'abord, une chose à ne jamais faire est de mettre l'application sur le serveur puis de créer un raccourci pour chaque utilisateur devant l'utiliser. Car dans ce cas deux utilisateurs sur deux postes différents peuvent ouvrir le même formulaire partagé sur un serveur.
Voici la logique à suivre :
- on partage les tables contenant les données, dans une base de données située sur un serveur .
- on ne partage jamais l'application (tables attachées, formulaires, requêtes, états, etc.). Chaque poste possède une application.
Sinon, dès qu'un utilisateur modifie un formulaire, il faut s'attendre à voir les mêmes modifications sur tous les postes, avec de longs délais (passage d'info par le réseau), d'où un cafouillage total pour Access.
Votre projet est sans doute divisé en deux fichiers Access : la base de données et l'application (formulaires, états...).
Il faut impérativement que vous recopiiez l'application sur chaque poste et que la base de données soit sur le Serveur.
En effet, seule la base de données est destinée à être partagée.
L'application ne doit jamais l'être, sous peine :
- de mettre très longtemps (jusqu'à plusieurs minutes si le réseau est encombré) pour ouvrir certains formulaires ;
- d'obtenir des erreurs quasi incompréhensibles lorsque plusieurs utilisateurs ouvrent les mêmes formulaires en même temps : affichage incomplet de certains contrôles, etc. ;
- s'il y a des tables locales, dans l'application elle-même, ces tables doivent être propres à chaque utilisateur et non pas partagées, sous peine de voir les données changer toutes seules lorsqu'un autre utilisateur les modifie...
De plus, ceci est cohérent avec une bonne politique de sauvegarde :
- une copie de secours de l'application (pourquoi pas sur le serveur) suffit pour réinstaller l'application en cas de panne sur un poste. Inutile de la sauvegarder tous les jours, si elle n'est pas modifiée par un programmeur ;
- des copies quotidiennes de la base de données sont indispensables dans les sauvegardes (backups).
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Il faut appliquer la méthode NewPassword de l'objet DataBase en utilisant DAO.
Sub ChangeMotPass()
On Error GoTo err
Dim odb As DAO.Database
Set odb = CurrentDb
odb.NewPassword "ancien", "nouveau"
MsgBox "Mot de passe changé"
fin:
Set odb = Nothing
Exit Sub
err:
Select Case err.Number
Case 3031
MsgBox "Mot de passe non valide", vbCritical, "Sécurité"
Case Else
MsgBox "Une erreur est survenue pendant le changement du mot de passe", _
vbCritical, "Erreur"
End Select
Resume fin
End SubLien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Sub SetProperty(strName As String, intType As Variant, vValue As Variant)
Dim prpNew As DAO.Property
Dim db As DAO.Database
Set db = CurrentDb()
' Tente de définir la propriété spécifiée.
On Error GoTo Err_SetProperty
db.Properties(strName) = vValue
Exit_SetProperty:
db.Close
Set db = Nothing
Exit Sub
Err_SetProperty:
' L'erreur 3270 signifie que la propriété est
' introuvable.
Select Case Err.Number
Case 3270
' Crée une propriété, définit sa valeur et
' l'ajoute à la collection Properties.
Set prpNew = db.CreateProperty(strName, intType, vValue)
db.Properties.Append prpNew
Case Else
MsgBox "erreur n°" & Err.Number & vbCrLf & Err.Description
End Select
GoTo Exit_SetProperty
End Sub
exemples d'utilisation :
setproperty "NouvellePropriete", dbboolean, false
ou
setproperty "RepTravail", dbtext, "C:\Program Files\Office\"
Il sera ensuite facile de récupérer dans le code cette propriété :
Dim strPath as String strPath = CurrentDB.Properties("RepTravail")Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Lien : Comment modifier le titre de l'application ?



