Probleme objet ADODB fermé : incompréhensible !!

mekhanik Messages postés 33 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 20 mai 2007 - 15 févr. 2006 à 19:04
mekhanik Messages postés 33 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 20 mai 2007 - 16 févr. 2006 à 14:18
Salut,
Voici mon problème. J'ai un programme qui comptabilise le temps passé sur un projet automatiquement. Lorsqu'un logiciel est détecté dans la liste de processus, le projet est détecté grâce au nom de fichier et je demande alors quel est l'employé qui travaille sur le projet puis le compteur se met en route. Le programme surveillé est alors rajouté dans une listbox qui est rafraichie toutes les secondes. Cela marche très bien. Le problème c'est lorsque je double-clique sur un des éléments de la listbox pour changer l'employé. Le double clique déclenche l'ouverture d'une form ayant un combobox avec la liste des employés. Les employés sont issus de la table employe sur une base access. Le combobox est complété dans la méthode load de la form via la méthode ListEmp décrite plus bas. J'obtiens alors le message d'erreur suivant :
Erreur '3704':
Cette opération n'est pas autorisée si l'objet est fermé
Après avoir fait une éxécution pas à pas, j'ai constaté que l'objet req est ouvert sur la ligne CListEmp.Text = req!Nom_Emp + " " + req! et fermé sur req.MoveNext juste après. C'est d'ailleur sur req.MoveNext que l'erreur se déclenche (Lorsque la gestion d'erreur n'est pas activé).

Je précise que j'utilise des timers que j'arrete lorsque le double click sur la listbox est détecté et que je redémarre juste après. La connexion à la base de donnée est effectué dès le lancement du programme et est effective toute sa durée.
Merci de votre aide en espérant avoir été assez clair.

P.S. : Je reconnais que mes transactions n'ont aucune utilité ici mais je voulais essayé. Le problème est identique sans.

Code d'échange avec la base de donnée :

Dim tabEmp() As Long


Dim MaConn As ADODB.Connection, req As ADODB.Recordset



Public Sub Connexion(PathBDD As String)
Set MaConn = New ADODB.Connection
MaConn.Provider = "Microsoft.Jet.OLEDB.4.0;"
MaConn.Open PathBDD
End Sub


Public Sub ExecuterRequete(requete As String)
'On Error GoTo ErrHandler
Set req = New ADODB.Recordset
'Execution d'une requete sur la bd
Set req = MaConn.Execute(requete)
'ErrHandler:
'If Err.Number <> 0 Then
'MsgBox "Impossible d'effectuer la requete", , "Erreur"
' End If
End Sub


Public Function recupIndex() As Long
Call ExecuterRequete("Select Id_A_Travaille from Identifiant where Id_Table = 1;")
recupIndex = req!Id_A_Travaille
End Function


Public Sub MAJIndex(i As Integer) Call ExecuterRequete("Update Identifiant set Id_A_Travaille " + CStr(i) + " where Id_Table 1;")
End Sub



Public Sub ListEmp(ByRef CListEmp As ComboBox)
Dim i As Integer
On Error GoTo ErrHandler
Call ExecuterRequete("BEGIN transaction")
Call ExecuterRequete("Select * from Employe order by Nom_emp;")
ReDim tabEmp(0)
i = 0
Do While Not req.EOF
i = i + 1
ReDim Preserve tabEmp(i)
tabEmp(i - 1) = req!Id_emp
CListEmp.AddItem (req!Nom_Emp + " " + req!Prenom_Emp)
If idEmp = req!Id_emp Then
CListEmp.Text = req!Nom_Emp + " " + req!Prenom_Emp
CListEmp.ListIndex = i - 1
End If
CListEmp.ListIndex = 0
req.MoveNext
Loop
Call ExecuterRequete("COMMIT TRANSACTION")
If CListEmp.ListIndex = -1 Then
If i = 0 Then
CListEmp.Text = "Aucun Employé"
Else
CListEmp.ListIndex = 0
CListEmp.Text = CListEmp.List(0)
End If
End If
ErrHandler:
If Err.Number <> 0 Then
Call ExecuterRequete("ROLLBACK TRANSACTION")
End If
End Sub

3 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
15 févr. 2006 à 20:53
Salut
Il faudrait savoir si tes déclarations (Dim) sont faites dans un module ou dans une Forme.
Dans une Forme, les objets n'existent que dans la forme
Dans un module (si déclaré en Public au lieu de Dim), ils existent dans tout le code de ton application.


Ajoute un "req.MoveFirst" avant ton Do-Loop
Ce n'est pas obligatoire, mais c'est plus sûr.


Bizarreries constatées :
- La concaténation de chaine se fait avec un signe &, pas avec +
Ca marche, oui, mais pas tout le temps.
CListEmp.Text = req!Nom_Emp & " " & req!Prenom_Emp


- Dans ListEmp, tu as cette ligne :
CListEmp.AddItem (req!Nom_Emp + " " + req!Prenom_Emp)
Ca doit déclencher une erreur : Les parenthèses sont en trop


- Lenteurs :
Lorsque tu fais des Redim Preserve en n'augmentant que de 1 le nombre de données, ca peut devenir très lent.
Avant de faire ton "Do While Not req.EOF", tu connais le nombre de lignes grace à req.RecordCount
--> Ne fais qu'un seul Redim :
Redim tabEmp(req.RecordCount - 1) ' le -1 pour palier au décalage


- Lenteurs :
Tu fais un "CListEmp.ListIndex = 0" à chaque item --> Ca rafraichit tout --> lenteur


Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage. (Socrate)
0
mekhanik Messages postés 33 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 20 mai 2007
16 févr. 2006 à 09:49
Merci pour tes conseils, je vais corriger tout ça et te tenir au courant.
Pour les variables déclarées grâces à dim elles sont dans un module mais ne sont utilisées que dans celui-ci. D'ailleur tout le code ci-dessus est contenu dans un module.
Merci encore
0
mekhanik Messages postés 33 Date d'inscription vendredi 15 août 2003 Statut Membre Dernière intervention 20 mai 2007
16 févr. 2006 à 14:18
J'ai enfin trouver l'origine de mon problème. En fait dans ma form, lorsque le combobox contenant la liste des employés est cliquer (évènement combo_click), j'appelais une méthode qui déclenchais une requete. Or ce que je ne savais pas c'est que lorsqu'on l'on fait "CListEmp.ListIndex = 0" cela déclenche l'évenement click sur le combo et donc j'effectuais une autre requete dans ma requete d'où mon objet fermé ...
J'ai par contre pas réussi à utiliser la méthode RecordCount il a toujours la valeur -1. Si tu peux m'aider ...
0
Rejoignez-nous