Conseil pour migration Excel vers access ou autre SGBD en VBA

Conseil pour migration Excel vers access ou autre SGBD en VBA - SQL/NoSQL - Programmation

Marsh Posté le 07-12-2007 à 08:44:48    

Bonjour,

 

J'ai développé bénévolement(ah la galère !)  une  petite application "gestion clients/prise de commandes/facturation/ pour mon fils qui travaille dans une mini PME de Biologie.

 

L'appli devait être monoposte au départ et j'ai donc choisi Excel + VBA (seuls logiciels que je maitrise bien) notamment pour avoir des formulaires sympathiques.

 

Le classeur excel se compose donc de plusieurs feuilles "clients", "commandes", "projets" , etc et l'appli VBA automatise également la création des documents devis et factures (avec Word).

 

Et maintenant il faut passer tout ça en multi-poste.

 

Je me suis orienté vers Access et ADO pour voir ce que ça pouvait donner : j'ai migré mon classeur excel vers access sans trop de difficultés (encore que j'ai des questions sur la meilleure façon de migrer les champs date ou monétaires) et j'ai transposé 2 ou 3 procédures en remplaçant la gestion des feuilles excel par des requetes SQL

 

Avant de poursuivre je voudrais valider ce choix et donc je me pose les questions suivantes :

 

- access est payant (pour l'instant Access 2002 peut être installé sur tous les postes sans pb), quid des logiciels gratuits (comme sql serveur express ou autre)
- normalement une transaction peut provoquer plusieurs mises à jour, est-ce que ces logiciels gèrent facilement le rollback en cas de pb(je pense que oui)

 

- comment développer et tester sur un seul poste (chez moi) y compris le coding éventuellement nécessaire à la gestion des conflits d'accès.

 

- je trouve les requêtes SQL vraiment pénibles à coder, les quotes (simple ou double ) les valeurs numériques qui peuvent être aléatoirement négatives sans parler du séparateur des décimales (comment coder ... SET Montant_HT = Montant_HT  + " &  Delta & .. lorsque delta vaut -310,25 !) . N'y a-t-il pas mieux à faire.

 

Bref comment feriez-vous et merci de vos conseils

Message cité 1 fois
Message édité par edma le 07-12-2007 à 15:58:04
Reply

Marsh Posté le 07-12-2007 à 08:44:48   

Reply

Marsh Posté le 07-12-2007 à 20:31:41    

un petit refresh pour vos conseils ou avis notamment sur mySQL et sur le choix de garder toute les procédures sous VBA excel.

Reply

Marsh Posté le 08-12-2007 à 11:31:17    

personnellement je pense que la migration sera bcp plus simple si tu restes dans les produits de microsoft, cad SQL SERVER EXPRESS. Je pense d'ailleurs qu'ACcess permet de migrer vers SQL SERVER assez facilement.  
 
Maintenant pour la gestion des transactions. Ne t'attends pas à des miracles avec ACCESS, certes il les gère, mais de façon assez basique. SQL SERVER EXPRESS est donc une bien meilleure solution pour les raisons suivantes:
 
- SQL SERVER EXPRESS est un vrai SGBD
- SQL SERVER permet des query SQL bcp plus complexes que ACCESS
- Tu auras probablement un meilleur support avec SQL SERVER

Reply

Marsh Posté le 09-12-2007 à 08:07:17    

merci de ce premier conseil

 

sinon comment peut-on tester en monoposte les pb de conflits d'accès . J'imagine lancer par exemple concurremment des requetes depuis access, pendant que j'effectue d'autres requêtes à partir du logiciel.

 

que veux-tu dire par gestion basique des transactions, si le  rollback/commit ou leurs équivalents sont fournis ca me suffit .  


Message édité par edma le 09-12-2007 à 08:09:35
Reply

Marsh Posté le 09-12-2007 à 09:21:59    

Excel peut être accessible depuis plusieurs postes. Il suffit de mettre le classeur Excel sur un répertoire partagé dans un réseau. C'est une installation que j'ai vue dans plusieurs entreprises et qui est satisfaisante quand il y a moins de 20 utilisateurs.
 
Access est bien aussi, et peut aussi être installé sur un répertoire partagé, donc pas besoin d'ADO dans ce cas. Il est aussi possible de faire une application Access en deux parties, une partie sur chaque poste client contenant les traitements, et une partie sur un serveur contenant les données qui sont définies dans des "tables attachées". On peut "attacher" toutes sortes de tables via ODBC, pas seulement des tables Access. Les "tables attachées" sont faciles d'utilisation et très pratiques.
 
Cepndant ma solution préférée pour ce genre d'application est un serveur Apache avec du PHP et MySQL ou Oracle, et Internet Explorer ou Firefox sur les postes clients. L'avantage est multiple : 1. GUI plus pratique, par exemple, à cause de ces fenêtres qui peuvent scroller, les liens cliquables, etc. 2. Il est possible de faire n'importe quel traitement, par exemple, des éditions PDF, des interfaces avec d'autres logiciels. 3. Les bases de données MySQL ou Oracle sont plus performantes que la base Access, et ont un SQL beaucoup plus standard, plus rapide, et permettant de faire plus de choses. 4. Le PHP est plus rapide que le VBA.

Reply

Marsh Posté le 09-12-2007 à 12:01:52    

edma a écrit :

- access est payant (pour l'instant Access 2002 peut être installé sur tous les postes sans pb), quid des logiciels gratuits (comme sql serveur express ou autre)


Le logiciel Access est payant en effet.
Par contre, Windows peut gérer une base Access (*.mdb) sans nécessiter Access, tant que tu n'utilises que le moteur de base de données. Donc si tu laisses tes formulaires dans Excel/Word, tu n'as pas besoin de distribuer Access, tes macros VBA pourront parfaitement accéder à ta base avec une connexion ADO (MDAC contient le moteur MS JET, qui est le moteur de base de données d'Access).
 
En revanche, Access est très mauvais en ce qui concerne les accès concurrents, donc tu ne résoudras que partiellemet ton problème d'accès concurrents.
 
SQL Server Express est donc une solution infiniment meilleure. En revanche, il faudra l'installer sur un serveur "dédié", je te déconseille de le mettre sur un poste utilisateur, surtout si la machine n'est pas dotée de beaucoup de mémoire (au moins 2 Go sous XP, et 3 Go sous Vista, histoire de ne pas ralentir la machine)
 

edma a écrit :

- normalement une transaction peut provoquer plusieurs mises à jour, est-ce que ces logiciels gèrent facilement le rollback en cas de pb(je pense que oui)


 
Access et SQL Server gèrent parfaitement les transactions. Par contre, pour faire une transaction, tu dois la faire de façon explicite, et via ADO, non pas en SQL.
cnx.BeginTrans
cnx.CommitTrans
cnx.RollbackTrans
http://www.devguru.com/technologies/ado/8542.asp
http://www.devguru.com/technologies/ado/8545.asp
 
A noter que sous SQL Server, contrairement à Access, tu peux gérer le niveau de lock de tes tables, ce qui permet d'avoir des transactions de longue durée qui ne lockent pas les tables complètement.
http://msdn2.microsoft.com/en-us/library/ms187373.aspx
 

edma a écrit :

- comment développer et tester sur un seul poste (chez moi) y compris le coding éventuellement nécessaire à la gestion des conflits d'accès.


 
Logiquement tu lances deux instances de ton fichier Excel qui contient les macro, ça devrait passer. Chaque macro va tourner dans sa propre session, et donc être reconnue par la base de données comme deux connexions distinctes.
 

edma a écrit :

- je trouve les requêtes SQL vraiment pénibles à coder, les quotes (simple ou double ) les valeurs numériques qui peuvent être aléatoirement négatives sans parler du séparateur des décimales (comment coder ... SET Montant_HT = Montant_HT  + " &  Delta & .. lorsque delta vaut -310,25 !) . N'y a-t-il pas mieux à faire.


Que le SQL ? Non.
Par contre, utilise des requêtes préparées (ou commandes paramétrées). C'est beaucoup plus lisible, maintenable, et accessoirement, bien plus performant sans oublier que ça te protège contre nombre de bugs (une appostrophe dans un texte par exemple, ou l'exemple de la virgule que tu cites).
Pour les requêtes compliquées exécutées souvent, tu peux aussi créer des vues sous SQL Server (ou des "requêtes" dans Access) que tu peux appeler ensuite comme des tables, ça allège considérablement le code de ton application (cf. ma signature pour en savoir plus)
http://webman.developpez.com/artic [...] ter/vbnet/ (<= les prepared statements)
 

edma a écrit :

Bref comment feriez-vous et merci de vos conseils


Comme moi (pas moi, l'autre [:magicbuzz]) te le conseille : SQL Server rulez


Message édité par MagicBuzz le 09-12-2007 à 12:06:05
Reply

Marsh Posté le 09-12-2007 à 23:43:41    

Voila du grain à moudre...  
 
Je résume ce que j'ai compris en y ajoutant quelques précisions au passage en bleu
 
1 - La base de données sera naturellement sur le serveur  
(comme c'est déjà le cas pour le classeur contenant le VBA (formulaires et coding), ainsi que le classeur contenant les feuilles de données)

 
2 - Pour olivthill : Il me semble avoir lu qu'on peut partager sans difficultés un classeur excel en réseau tant qu'il n'y a pas de code VBA "inside" donc si c'était le cas il faudrait mettre le classeur VBA sur chaque poste ce qui est tout à fait envisageable. Par contre je vois surgir la difficulté suivante pour le classeur de données :  
- en monoposte on est sûr qu'entre la lecture d'un enregistrement et sa mise à jouer éventuelle à la fin d'une la transaction, il n'a pas changé de place dans la feuille de données. Donc pas besoin de le locker ni d'avoir un identifiant logique unique pour le retrouver ==> son rang (N° de ligne) suffit
- en multi-poste ce n'est plus garanti et il faut donc soit gérer des verrous (à proscrire je pense) soit contrôler qu'avant une mise à jour à la fin d'une transaction l'enregistrement n'a pas été modifié depuis la lecture du début de la transaction, donc gérer un système de timestamp et rajouter si nécessaire une clé unique et logique aux enregistrements ... Je dis là sans doute des évidences à moins qu'une autre possibilité plus élégante m'ait échappée, sinon,.....
 
3- sinon adieu Excel....  
 
4 - pour Access , le fait de pouvoir gérer une base *.mdb sur un serveur sans avoir avoir access sur ce serveur est un argument potentiellement intéressant (sauf que adieu les petits coups de bistouris pour récupérer le bugs résiduels)
 
5 - quand je parle d'accès concurrents il faut comprendre que plusieurs personnes peuvent émettre simultanément des devis ou des factures mais sur des projets complètement différents. Les seuls véritables conflits concernent les distributeurs de numéro ou les modifications des paramètres généraux et la gestion du fichier client. Leur probabilité reste très faible (5 ou 6 postes pour une vingtaine de devis et autant de factures ou de règlements par jour )  mais demande d'être bien gérée pour éviter tout soucis.
 
6 - la solution ADO Commit, etc me semble bien adaptée à une gestion modeste des transactions  
(j'ai choisi ADO plutôt que DAO car j'ai plus facilement trouvé des exemples ou des réponses à mes questions de débutant sur le net avec ADO, mais je n'ai pas encore pris le temps de comprendre les enjeux de ces deux approches)

 
7- SQL Server Express parait une solution très satisfaisante, mais dispose-t-on d'outils gratuits aussi ergonomiques("end user" ) que Access par exemple pour modifier directement une table (il m'a semblé voir des exemples en ligne de commande)
 
8- pour PHP, etc , çà me tenterait bien de m'y coltiner un jour mais pas pour migrer cette "énorme appli " de 1 Mo qui tourne bien coté formulaires et procédures, encore que j'ai fini de gagner ma croute en bossant (pré-retraite) et que mes tous petits enfants préfèrent me voir galérer sur leur LEGO que sur PHP.
 
9 - Au fait (et ça pourrait avoir son importance) je développe sous Vista et le logiciel devra tourner un bon moment sous XP
 

Merci de vos réponses et conseils que je vais continue à éplucher plus profondément, j'espère que la liste n'es pas close pour autant et je viendrai sans doute exposer mes problèmes concrets s'ils me résistent trop longtemps.
 


Message édité par edma le 10-12-2007 à 20:57:12
Reply

Marsh Posté le 12-01-2008 à 18:50:31    

Sinon question toute simple :
Y a t-il un moyen pour connaitre le nb d'enregistrements modifiés par une instruction  SQl  du type
 
 update ... Where Champ1 = 'XX'
 
sans faire un select préalable


Message édité par edma le 12-01-2008 à 19:40:23
Reply

Marsh Posté le 13-01-2008 à 01:13:44    

7/ Oui, avec SQL Server Express il y a un manager graphique qui permet de modifier la structure de la base de données comme avec Access (quand on se met en "mode création" ). En revanche, il n'y a aucune aide à l'écriture des requêtes SQL, on est censé savoir ce qu'on fait.
 
9/ Que ce soit Access ou SQL Server Express, aucune limitation particulière avec XP ou Vista. Pour SQL Server Express, il faut toutefois faire attention à installer la version "service pack 2" directement dès le départ, afin de corriger des bugs relatifs à la nouvelle gestion des droits sous Vista (sinon, tu n'as pas accès aux bases autrement qu'en utilisant le compte administrateur)

Reply

Marsh Posté le 13-01-2008 à 14:02:39    

Merci de ces précisions
l'aide à l'écriture des requêtes n'est effectivement pas un critère majeur  
 
Pour l'instant j'ai transposé avec access / ADO, ce qui semble tourner convenablement  
par contre le debbugging n'est pas fini, notamment avec les caractères spécifiques à access (le simple quote par exemple) et avec les zones null.
sans parler des possibilités d'insertion des lignes dans feuilles access que j'ai dû transposer avec des ordres ORDER BY etc
 
Il me reste un souci "métaphysique" : faut-il tester systématiquement les code retour après chaque requête ou se limiter aux possibles erreurs d'incohérences applicatives (d'où ma question précédente sur le nb d'enregistrements modifiés par un update)


Message édité par edma le 13-01-2008 à 14:03:22
Reply

Marsh Posté le 13-01-2008 à 14:02:39   

Reply

Marsh Posté le 14-01-2008 à 09:37:05    

pour les problèmes de caractères à la noix qui font planter les requêtes ainsi que les valeurs nulles, le mieux c'est de passer par des requêtes paramétrées.

Reply

Marsh Posté le 17-01-2008 à 14:13:41    

J'ai bien noté,  
 
sinon autre pb pour faire du begintrans, rollback et commit il me faut à priori une bibliothhèque DAO car j'utilise un objet workspace. du coup j'ai j'utilise ADO pour les accès à la base et DAO pour la gestion des transactions. n'y a t-il pas moyen de se passer de DAO.
 
Petit commentaire supplémentaire : mon objectif premier est que l'appli tourne rapidement en multiposte, ce qui est en passe d'être fait.  
Ensuite je procèderai à l'optimisation et à la clarification du code, ce qui ne m'empêche pas de prendre en compte les conseils directement applicables.

Reply

Marsh Posté le 17-01-2008 à 14:16:53    

Poste un exemple de ton code, parceque j'aimerais comprendre la différence entre ADO et DAO ?
 
DAO, c'est le truc pourrave avec l'objet "database", et "executequery" et tout le bordel afin d'interroger directement la base Access ?
 
Mais vire-moi cette merde bordel de dieu :o Utilise ADO pour te connecter à ta base Access, fait comme si ton VBA était un vrai programme VB, il ne doit pas y avoir une trace du moindre bout proprio Access, ou tu vas au devant de lourds problèmes... Genre le jour où tu veux transcrire ta macro en VB pur.
 
http://www.devguru.com

Reply

Marsh Posté le 18-01-2008 à 07:55:36    

Avec plaisir et agrémenté de quelques commentaires pour facilité la lecture ou justifier certains choix (enfin je l'espère !)
 
'==========================
Dim objAccess As Object
Dim Db As New ADODB.Connection   ' pour connexion à la base access
 
Dim StrPath As String ' nom de la DB access
Dim MaTable As New ADODB.Recordset, Ws_A As Workspace
Dim req As String ' pour requetes SQL
 
'................
'..........
'======================== Open
 
With ThisWorkbook.Db
        .Provider = "Microsoft.Jet.OLEDB.4.0"
        .Properties("Data Source" ).Value = ThisWorkbook.StrPath
        .Open
End With
'========
'..............
'...........
Set Ws_A = Workspaces(0)   ' début transaction de mise à jour  
Ws_A.BeginTrans
 
'incrémentation de N_Proj (Numéro de Projet)
' j'aurai aussi besoin de N_Proj tout au long de la procédure donc pas de simple UPDATE SET N_Dossier = N_Dossier + 1
req = "SELECT N_Dossier from Parametres " ' cette table ne comporte qu'un seul enregistrement avec autant de champs que de paramètres
MaTable.Open req, ThisWorkbook.Db, adOpenKeyset, adLockOptimistic, -1
N_Proj = MaTable.Fields("N_Dossier" ).Value + 1
MaTable.Fields("N_Dossier" ) = N_Proj  
MaTable.Update
MaTable.Close
Set MaTable = Nothing
'  
'........
'........... autres mises à jour
'............
'Fin des mises à jour
'..............
If Maj_OK then
'............
     Ws_A.CommitTrans
Else
'.................
    Ws_A.Rollback
End if
Set Ws_A = Nothing
'=========================================
 
si je ne coche pas la bibliothèque Microsoft DAO (3.6) Object Library dans les références VBA, l'instruction :
Dim Ws_A as Workspace provoque le message : erreur de compilation, type défini par l'utilisateur non défini
 
 
Pour info je suis sous Access 2002 et j'ai coché également la bibliothèque Microsoft ADO 2.8 Objects Library
 
Voilou .
 


Message édité par edma le 18-01-2008 à 08:31:25
Reply

Marsh Posté le 18-01-2008 à 10:14:46    

1/ Ton "ThisWorkbook.Db" doit disposer d'un "BeginTrans" aussi logiquement, puisque visiblement il s'agit d'un objet ADODB.Connection
 
2/ Ne fait jamais de DIM de plusieurs variables sur une seule ligne : outre le fait que c'est illisible (j'ai mis un temps de chien à trouver où était déclaré ton Ws_A), VB ne sais pas typer la variable lorsqu'elle est déclarée de la sorte. Donc malgré l'erreur quand tu ne lie pas la DLL DAO, ton Ws_A est de type Variant au moment de la déclaration.
PS : Ceci s'applique en tout cas à toutes les versions de VB compilées, jusqu'à la 6. Je doute que VBA fasse mieux.
 
3/ Va sur Devguru, afin de travailler avec du vrai code ADO. Même si ça va te faire redéclarer des objets identiques à ceux qui existent déjà, au moins tu les maîtrisera à 100%
 
http://www.devguru.com/technologies/ado/home.asp
 
A maîtriser :
- L'objet Connection
- L'objet Command
- L'objet Parameter
 
Et toujours utiliser des requêtes paramétrées (c'est à dire utilisant des Paramerters plutôt qu'une chaîne SQL crée à partir de concaténations d'instructions et de valeurs)

Reply

Marsh Posté le 18-01-2008 à 10:31:52    

Ok merci de ces précisions, je vais mettre tout ça en pratique, ça peut prendre quelque temps !
 
Je ne comprends pas très bien la nécessité du begintrans sur l'open de la Base ==> pour info la base est ouverte lors du lancement de l'application et reste ouverte tant qu'on ne quitte pas l'application.
 c'est peut-être critiquable, bien que cette base ne soit utilisée que par cette application et depuis une poignée de PC.

Reply

Marsh Posté le 18-01-2008 à 10:41:47    

Parceque Connection ouvre une session, à la base de données, et que par définition, une transaction a pour périmètre la session.
 
De plus, actuellement tu travailles avec des objets Access, mais si demain, pour une raison X ou Y tu dois passer à une base SQL Server, Oracle, MySQL ou autre, et que dans un premier temps tu ne veux pas refaire tout le frontend Access, alors t'as juste à modifier une petite ligne dans ton code écrit purement ADO : la chaîne de connexion à la base. Ceci n'est pas vrai si tu utilises les objets d'Access.
 
PS : Et j'ai pas dit de créer la transaction au moment de l'ouverture. Mais sur l'objet quoi gère cette ouverture. Après, tu crée et ferme des transactions (tu peux même imbriquer des transactions dans des transactions si Access le supporte) autant que tu veux, quand tu veux, et si tu veux. Ca ne changera rien à ton code.
 
Sauf qu'au lieu de faire Ws_A.<Instruction_Transaction> tu feras cnx.<Instruction_Transaction> avec "cnx" un objet ADODB.Connection qui va reprendre rigoureusement le même rôle que MyWorkbook.Bd (que tu ne maîtrises pas du tout -ni la version de l'objet, ni l'initialisation de ses propriétés, etc.-)

Reply

Marsh Posté le 18-01-2008 à 23:32:21    

Effectivement j'ai utilisé l'objet connexion au lieu de workspace et plus besoin de DAO !
 
Par contre j'ai une notion plus restrictive de la transaction qui date de ma longue pratique des gros systèmes préhistoriques sur lesquels on utilisait DL1/DB2 avec une notion de checkpoint correspondant au commit :
 
L'ensemble (begin,commit/rollback) assurait l'intégrité des données lors des mises à jour et donc :
- tant qu'on ne commence pas les mise à jour, tout problème est sans conséquences sur les données.
- une fois les mises à jour commencées il faut les terminer ou alors les détricoter  
 
 
et c'est pour ça que j'ai bâti mon appli comme ça (c'est un extrait):
-ouverture de l'application VBA depuis Excel, récupération des paramètres depuis un  fichier appli.ini
-ouverture de la connexion vers la DB appli.mdb
- affichage userform "menu général", selection fonction à effectuer
- affichage userform correspondant à la fonction à effectuer par exemples :
 
-transaction de consultation client (pas de mise à jour)
-retour userform "menu général"
 
- affichage userform "création de devis"
-transaction de création devis se décomposant en :
- sélection et affichage du client
- saisie des lignes du devis
- déclenchement de l'enregistrement du devis :
- begintransaction
- mises à jour table clients (date, code et montant du dernier devis par exemple)
-mise à jour table devis
- mise à jour table projets
-commit ou rollback si pb applicatif (ou plus rien si c'est  windows qui plante !)
-retour formulaire "menu général"
 
-exécution autres transactions
 
etc
et avant de fermer l'application au minimum chaque soir (obligation de quitter par un commandbutton)
- exportation de certaines données vers fichiers Excel ou séquentiels (pour d'autres applications de production ou statistiques)
- close connexion
- application.quit etc
 
 
et dans ce contexte je ne comprends pas bien la nécessité de mettre en place un begin/commit général correspondant à une "transaction globale" qui durerait de l'ouverture à la fermeture du logiciel, mais sans doute je n'ai pas tout pigé.  
 
Autre info (sans grand intérêt !) :
Si l'intégrité des données est bien prise en compte dans la base Access, elle n'est pas complètement assurée pour l'ensemble de l'application ;  
en effet l'application effectue d'autres mise à jour (comme par exemple la création ou la mise à jour de dossiers et de fichiers Word pour les factures) : il faudrait programmer un Rollback applicatif spécifique pour ces opérations (Rollback qui pourrait à son tour rencontrer des pb !).
Cela n'est pas inquiétant car actuellement l'application tourne sans soulever de pb d'intégrité et le retour arrière manuel sur les dossiers et fichiers "Windows" reste très simple.


Message édité par edma le 19-01-2008 à 08:06:43
Reply

Marsh Posté le 19-01-2008 à 07:39:58    

ben j'ai jamais dit le contraire, relis ce que j'ai écrit.
 
je dis juste qu'une transaction n'a rien à voir avec ton "programme", mais est 100% liée à ta connexion à la base de données. (session pour être exact)
 
si tu veux une transaction plus générale, alors tu ne dois plus passer par une transaction BDD, mais par le composant Microsoft Transaction Server, qui permet aussi de faire des transaction sur tout et n'improte quoi sur ton PC et le réseau, mais on s'éloigne beaucoup de la notion de transaction originale.
 
Donc quand t'a ton programme qui va faire une action qui doit nécessiter une intégrité absolue, il va indiquer au SGDB qu'il va faire une transaction, puis indique quand il a fini. le seul contact que t'as avec un SGBD depuis un programme, jusqu'à preuve du contraire, c'est la connexion, c'est donc à elle de gérer la chose.
 
je ne vois pas en quoi c'est incompatible avec ta vision des transactions.
 
PS : pour le coup du "checkpoint", c'est pas équivalent aux transactions, mais complémentaire : un checkpoint permet de faire un rollback/commit partiel au sein d'une même transaction.
les produits microsoft (SQL Server et Access) préfèrent les transactions imbriquées (ouverture d'une transaction au sein d'une première transaction), ce qui permet de faire la même chose, mais de façon plus évidente je trouve. ADO permet l'utilisation de l'un ou l'autre indifféremment.


Message édité par MagicBuzz le 19-01-2008 à 07:43:16
Reply

Marsh Posté le 19-01-2008 à 08:07:53    

J'ai édité mon précédent message et donc nos messages se sont légèrement croisés, tu es matinal aussi!
 
Effectivement ce que tu dis ne me choque pas, j'ai juste une question sur la nécessité de définir cette transaction globale qui correspond à la session d'utilisation de l'application.


Message édité par edma le 19-01-2008 à 08:14:41
Reply

Marsh Posté le 19-01-2008 à 10:52:37    

Y'a pas de transaction globale.
 
C'est toi qui défini à quelle moment elle commence et à quel moment elle s'arrête.
 
Mais à partir du moment où tu as démarré une transaction, tout ce que tu fais es dans la transaction, et c'est logique : si tu veux lire des données dans une table par exemple, il faut absolument que les données que tu lis reflètent les modifications effectuées dans ta transaction, sinon tu travailles avec un état incohérent des données.
 
Si réellement, pour une raison X ou Y, tu as absolument besoin d'avoir en même temps accès aux données de ta transaction, ainsi que les données en dehors de ta transaction, alors tu ouvres deux connections distinctes à ta base, mais non seulement je ne vois pas l'intérêt, mais surtout je vois ça comme une source d'erreurs.

Reply

Marsh Posté le 21-01-2008 à 02:43:05    

Y'a pas de transaction globale.  je suis bien d'accord et ça me paraissait  + que bizarre cette transaction globale.
 
Simplement je n'avais pas compris le sens de ta phrase :
 Ton "ThisWorkbook.Db" doit disposer d'un "BeginTrans" aussi logiquement, puisque visiblement il s'agit d'un objet ADODB.Connection ?
 
============
Sinon pour l'intégrité des SELECT....,
 
Effectivement si je n'inclus pas les requêtes SELECT dans le begin/commit rien ne garantit que les enregistrements concernés n'auront pas changés entretemps.
 
De fait il n'y a pas de mises à jour ni de suppression possible qui puissent en invalider le contenu (il faudrait par exemple que deux personnes émettent chacune une facture pour le même devis, ce qui est assez inconcevable dans l'organisation du travail.
 
 Néanmoins s'il n'y a aucun inconvénient à être rigoureux je vais m'y conformer pour éviter toute faille !
 
J'aurais peut-être besoin d'exemple pour traiter le plus simplement possible les messages d'erreurs liées à l'impossibilité d'accéder à un enregistrement loqué..
 
Une question: est-ce que les select incluent dans un recordset les enregistrements qui sont bloqués temporairement par un begintrans  ?


Message édité par edma le 21-01-2008 à 02:47:05
Reply

Marsh Posté le 21-01-2008 à 09:28:24    

tout dépend du mode d'ouverture de tes recordset et des informations modifiées sur la table.
 
avec les paramètres standard, normalement, non, les recordset ne déjà ouverts seront pas impactés par les transactions (et même sans transaction, si tu modifies des lignes d'une table qui est déjà ouverte dans un recordset, tu ne verra pas de changement dans le recordset).
 
avec un recordset avec un curseur serveur, et la méthode "pessimistic", alors le recordset lock toutes les lignes faisant partie du résultat, ce qui est le comportement normal (et donc pas l'inverse)

Reply

Marsh Posté le 05-03-2008 à 11:37:10    

Je reviens chercher conseil, critique ou confirmation sur la méthode générale que je me propose de mettre en place pour sérialiser les mises à jour ( et éviter tout conflit).
 
1° - les mises à jour sont regroupées à l'intérieur de transactions (begin/commit)  qui s'exécutent sans aucun échange avec l'utilisateur et donc en quelques secondes.
Par contre reste le problème que ces mises à jour génèrent la création ou la modification de dossiers windows, et que cet environnement ne peut donc pas être restauré "facilement" en cas de rollback.
 
2°- Si on s'en tient là, deux utilisateurs peuvent lancer deux transactions de mise à jour qui vont se télescoper et j'aurai donc à traiter les erreurs relatives à un verrouillage de la base access pour une des deux transactions, avec le pb des dossiers windows sur les bras!
 
3°- pour éviter cette situation chaque transaction de mise à jour fera appel à une fonction préliminaire qui posera un verrou applicatif, et se terminera par appel à une autre fonction de levée du verrou.
 
Cette fonction de pose de verrou s'appuiera sur le champ "verrou" d'une table paramètre :
verrou = "" <=> pas de mise à jour en cours  
==>  mise à jour ce verrou avec un timestamp passé en paramètre (date du jour & nb aléatoire < 100000 & info spécifique à la transaction)
verrou <> "" <=> mise à jour en cours initialisée pour une autre transaction
==> on temporise sur une boucle de wait en attendant qu'il repasse à "", avec alerte au bout de 10 ou 20 secondes.....
 
Cette fonction vérifie de plus le champ "verrou" a bien été mis à jour et qu'il n'y a pas eu interférence avec un autre début de transaction concomitante (on relie le verrou et on compare la valeur retournée avec la valeur passée en paramètre). En en cas d'erreur, notamment impossibilité de poser le verrou ou conflit avec une autre transaction, il y abandon de la mise à jour (laquelle n'a pas véritablement commencé) avec message demandant de relancer la mise à jour (cliquer sur le bouton enregistrer)
 
5) en fin de transaction levée du verrou par remise à "" du champ
 
6) en cas de bug inexpliqué..., l'applicatif fonctionnera à nouveau le lendemain car un verrou ne datant pas du jour même est ignoré
 
C'est peut-etre lourd, inutile ou inefficace ? Sachant qu'il s'agit d'une activité très modeste de prise de commande/facturation tournant sur 3 ou 4 postes et que la tranquillité prime sur la lourdeur.


Message édité par edma le 05-03-2008 à 12:09:48
Reply

Marsh Posté le 06-03-2008 à 01:50:38    

Euh...
 
Ben en fait, c'est ce que j'étais en train de te proposé avant d'avoir tout lu ton post :D
 

Citation :


Une solution simple pour gérer un verrou, c'est de créer une table avec une seule ligne.
Au début de la transaction à la base de données, tu mets à jour cette ligne avec n'importe quoi (un timestamp pouruoi pas).
Comme ça, si une personne tente de lancer une transaction concurrent, la ligne étant lockée, elle devra attendre que la précédente transaction soit commité ou rollbackée.


Message édité par MagicBuzz le 06-03-2008 à 01:51:33
Reply

Marsh Posté le 06-03-2008 à 12:29:58    

Alors c'est que c'est bien ! et puis ça a le mérite de ne pas trop pourrir le code applicatif.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed