Recordset = "objet fermé"

Kobal

XLDnaute Junior
Bonjour à tous,
Je ne suis pas venu ici depuis un bout de temps, mais je me remets au VB à cause du boulot, et j'ai un petit souci actuellement:
j'essaie d'exécuter des requêtes SQL dans une base postgre, depuis un fichier excel.
La requête s'exécute bien, mais lorsque j'essaie de récupérer son résultat, j'obtiens une erreur "cette opération n'est pas autorisée si l'objet est fermé";
Voici les bouts de code incriminés:

Code:
ResultReq.Open ReqModif, connexion
MsgBox (ResultReq.GetString)

(ici, ReqModif est ma requête SQL, un update, et connexion est ma connexion à la base postgre).
La requête est bien exécutée, mais c'est le "MsgBox(ResultReq.GetString)" qui crée l'erreur. J'ai la même chose quand ma requête est un select, ou un insert.
Il y a quelque chose que j'oublie de faire avec mon recordset?
Si je m'y prend mal pour voir le résultat, il y a un autre moyen pour voir le contenu de ce recordset?

Merci d'avance
 
G

Guest

Guest
Re : Recordset = "objet fermé"

Bonjour,

Plusieurs causes peuvent être en jeu. Mais comment sais-tu que ta requête s'éxecute bien?

Je suppose que tu as une connexion ADODB
Ajoute ceci à ta connexion:
Code:
connexion.CursorLocation = adUseClient

Code:
If ResultReq.State = adStateOpen then
   msgbox (ResultReq.GetString)
End IF

Sans la macro, difficile de t'en dire plus.

A+
 

Kobal

XLDnaute Junior
Re : Recordset = "objet fermé"

Bonjour,
Merci pour cette réponse,
J'ai ajouté tes suggestions, sans succès. Mon recordset reste "fermé".
Je peux voir que mes requêtes s'exécutent, car mes update/insert sont visibles en base.

Pour le code de la macro entière, le voici (je raccourci un peu, il y a de nombreux paramètres car beaucoup de colonnes en table):

Code:
Function NSTGCreerStation(nom As String, _
    code_ig As String, _
    nom_ig As String, _
   [[liste des attributs à insérer/mettre à jour]])
    
Dim ResultDoublon As Object
Dim ResultModif As Object
Dim ResultReq As Object
Dim connexion As Object
Set ResultDoublon = CreateObject("ADODB.Recordset")
Set ResultModif = CreateObject("ADODB.Recordset")
Set ResultReq = CreateObject("ADODB.Recordset")
Set connexion = CreateObject("ADODB.Connection")
'On cree une connexion
Set connexion = BDDCreerConnexion[B]
connexion.CursorLocation = adUseClient[/B]

'On verifie que la station n'existe pas deja
ReqVerif = "Select * from station_nstg where nom = '" & nom & "'"

Set ResultDoublon = BDDExecuterRequete(connexion, ReqVerif)

If (Not (ResultDoublon.EOF And ResultDoublon.BOF)) Then
    'en cas de doublon, on met a jour la ligne concernee
    ReqModif = "Update station_nstg set ig_nom = '" & nom_ig & "', ig_code = '" & code_ig _
    & "', ig_latitude = '" & latitude & "', ig_longitude = '" & longitude _
    & "', ig_altitude= '" & altitude & "', ig_latitude_deg_dec = '" & latitude_deg_dec _
[[liste des différents attributs à mettre à jour dans l'update]]
    & "' where ig_nom = '" & nom_ig & "'"
[B]    Set ResultReq = BDDExecuterRequete(connexion, ReqModif)
    If ResultReq.State = adStateOpen Then
        MsgBox (ResultReq.GetString)
    End If[/B]

    
Else
[[on fait pareil avec un insert]]

    
    
End If

Call BDDFermerConnexion(connexion)
Set NSTGCreerStation = ResultReq


End Function
Et j'ajoute les quelques fonctions appelées dans cette macro:

Code:
'Ouvre une connexion et retourne l'objet
Function BDDCreerConnexion() As ADODB.Connection

    'On crée une nouvelle connexion
    Dim cn As New ADODB.Connection
    cn.Provider = "MSDASQL"
    'cn.ConnectionString = "DSN=PostgreSQL30;"
    Dim DSN As String
    
    'On recupere les parametre dans la feuille excel
    cn.ConnectionString = "DSN=" & Worksheets(BDDFeuilleParams).Range(BDDCellDSN).Value & ";"
    
    'On se connecte reellement
    cn.Open
    
    'On retourne la connexion ouverte
    Set BDDCreerConnexion = cn
        
End Function'Ferme une connexion passee en parametre
Sub BDDFermerConnexion(ByRef cn)
    
    a = 1
    'On ferme la connexion donnee
    cn.Close
        
End Sub

'Permet de lancer une requete et de retourner le resultset demande
Function BDDExecuterRequete(ByRef cn, ByVal rqt) As ADODB.Recordset
    
    Dim rst As New ADODB.Recordset
    rst.Open rqt, cn
    
    
    Set BDDExecuterRequete = rst
    
End Function

Désolé pour les gros pavés :/
 
G

Guest

Guest
Re : Recordset = "objet fermé"

Re,
Déjà un premier point:

Dans NSTGCreerStation tu crées tes objets Recordset par CreateObject alors que dans BDDExecuterRequete tu en crées un par New ADODB.Recordset laissant supposer que tu a une référence à Microsoft ActiveX Data Object dans ton projet.

Si c'est le cas choisis cette méthode (plus rapide) plutôt que CreateObject.

Si ce n'est pas le cas, c'est que tu n'as pas 'Option Explicit' en tête de module ni de référence à MSADO dans ton projet et que ton problème vient probablement de là.

Fais un débogage Pas à Pas (F8) et teste l'évolution de tes objets et variables.

A+

A+
 

Kobal

XLDnaute Junior
Re : Recordset = "objet fermé"

Oui en effet, j'avais créé le recordset et la connexion avec CreateObject dans un souci de portabilité, mais je ne suis pas à l'origine des autres bouts de code (BDDExecuteRequete, etc.) donc la création diffère.
J'ai enlevé les "CreateObject" pour faire des "New ADODB.Recordset" dans NSTGCreerStation, mais le problème persiste.
D'ailleurs, au cas où ça influerai, les fonctions "BDDExecuteRequete", "BDDCreerConnexion" et "BDDFermerConnexion" sont dans un module séparé de celui de NSTGCreerStation. Mais le tout est dans le même classeur excel.
 
G

Guest

Guest
Re : Recordset = "objet fermé"

Re,

Difficile de deboguer quelque chose un programme qu'on ne peut pas lancer.

Mais,

As tu tester tous tes variables et objets en Pas à Pas.

Dans la fonction
Code:
Function BDDExecuterRequete(ByRef cn, ByVal rqt) As ADODB.Recordset
 
    Dim rst As New ADODB.Recordset
    rst.Open rqt, cn
 
 
    Set BDDExecuterRequete = rst
 
End Function

rst Contient-il un resultat à ce niveau là?

Sinon dans ta sub principale tu peux essayer:

Code:
Dim ResultReq as New AODB.Recordset
'......
ResultReq.Open ReqModif, connexion
    If ResultReq.State = adStateOpen Then
        MsgBox (ResultReq.GetString)
    End If

Ou
Code:
Set ResultReq = connexion.Execute(ReqModif)
'....
Sinon je ne vois pas et ne peux pas t'aider sans faire de véritable test.

A+
 
Dernière modification par un modérateur:

Kobal

XLDnaute Junior
Re : Recordset = "objet fermé"

J'ai testé en pas à pas, dans BDDExecuterRequete, rst reste vide. J'ignore pour quoi, mais je pense que je vais investiguer par là.

J'ai aussi essayé les autres méthodes pour exécuter une requête, et j'obtiens la même erreur.

Merci de ton aide en tout cas.

edit: bizarrement, l'espion n'indique aucune valeur pour le recordset, même quand ce dernier n'est pas vide. J'en ai pour preuve que lors de ma première requête,celle qui permet d'éviter les doublons, le recordset contient quelque chose si la ligne existe déjà en base, et ma branche "if" a un comportement normal (on va faire un update de la ligne, dans ce cas). Je me demande si l'espion Excel ne pourrait pas afficher la valeur d'un recordset...

edit2: au temps pour moi, j'utilisais l'espion express, qui ne décrit pas tout l'objet, je recommence avec le vrai espion.
 
Dernière édition:

Kobal

XLDnaute Junior
Re : Recordset = "objet fermé"

Bonjour,
Je pense avoir trouvé l'origine du problème, et c'était tout bête en fait: une requête update ou insert ne retourne rien dans le recordset, donc on ne peut pas "lire" cet objet.
Si je fais un select au lieu de l'update, j'obtiens bien le résultat du select dans mon recordset.
Encore merci Hasco, et désolé pour la perte de temps occasionnée.
 

Discussions similaires

Statistiques des forums

Discussions
312 488
Messages
2 088 867
Membres
103 979
dernier inscrit
imed