Impossible de trouver l'objet dans la collection correspondant au nom ou à la ré

Résolu
ajor Messages postés 90 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2020 - 18 juin 2010 à 10:29
ajor Messages postés 90 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2020 - 18 juin 2010 à 17:37
Bonjour,

En ouvrant mon fichier Excel, j'obtiens une erreur :
3265
Impossible de trouver l'objet dans la collection correspondant au nom ou à la référence ordinale demandé


Le code contient une requête SQL qui fonctionne très bien

alors que la même requête fonctionne très bien quand je la fais directement dans Oracle (par SQL+)

Voici la requête :

 strSQL = "select cote.indice, cote.cote_actuelle " & _
                "from t_detail_vin pr, type_vin vin, (select ind.id_tvin,ind.milesime millesime,c.cote cote_actuelle, ind.id_indice indice from t_indices ind,cote_annuelle c where ind.id_indice = c.id_indice and   ind.format in('Bouteille') and  c.annee='2010' and ind.id_indice not in ('1','2','3') and ind.id_indice < '100') cote" & _
                "where vin.id_tvin pr.id_tvin and pr.milesime cote.millesime and vin.id_tvin=cote.id_tvin and vin.proprietaire not in ('Indifferent') and vin.proprietaire is not null order by cote.indice"



A votre avis, d'où vient l'erreur ?

Précision : je travaille sur Excel 2003, j'appelle une base Oracle 10g avec cette fonction (qui fonctionne très bien avec des requêtes simples):
Set cN = New ADODB.Connection
    cN.ConnectionString = "Provider=msdaora;Data Source=OIU;User Id=XXXXX;Password=XXXX;"

7 réponses

ajor Messages postés 90 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2020
18 juin 2010 à 16:53
Si ça intéresse d'autres personne, j'ai trouvé d'où venait le problème :
Excel n'aime pas les points dans les variables (comme "cote.indice"...)
Du coup, j'ai mis un alias, et maintenant ça fonctionne !

strSQL = ""
strSQL = strSQL & "select cote.indice indiceZ, "
strSQL = strSQL & "       cote.cote_actuelle coteZ"
strSQL = strSQL & "  from t_detail_vin pr, "
strSQL = strSQL & "       type_vin vin, "
strSQL = strSQL & "      (select ind.id_tvin, "
strSQL = strSQL & "              ind.milesime millesime, "
strSQL = strSQL & "              c.cote cote_actuelle, "
strSQL = strSQL & "              ind.id_indice indice "
strSQL = strSQL & "         from t_indices ind, "
strSQL = strSQL & "              cote_annuelle c "
strSQL strSQL & "        where ind.id_indice c.id_indice"
strSQL = strSQL & "          and ind.format in('Bouteille') "
strSQL = strSQL & "          and c.annee='2010' "
strSQL = strSQL & "          and ind.id_indice not in ('1','2','3') "
strSQL = strSQL & "          and ind.id_indice < '100') cote "
strSQL strSQL & "  where vin.id_tvin pr.id_tvin "
strSQL strSQL & "    and pr.milesime cote.millesime "
strSQL = strSQL & "    and vin.id_tvin=cote.id_tvin "
strSQL = strSQL & "    and vin.proprietaire not in ('Indifferent') "
strSQL = strSQL & "    and vin.proprietaire is not null "
strSQL = strSQL & "  order by cote.indice"
 
      rs.Open strSQL, cN, adOpenForwardOnly, adLockOptimistic
        
        If rs.RecordCount > 0 Then
        
            j = 1
            i = 0
            
          Do While Not rs.EOF And Not rs.BOF
                
    i = i + 1
    Feuil1.Cells(i, j) = rs("coteZ")
    Feuil1.Cells(i, j + 1) = rs("coteZ")
    rs.MoveNext
3
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
18 juin 2010 à 12:21
Salut
Ce n'est pas l'ouverture du fichier Excel qui génère cette erreur, mais le code que tu y as mis.
Il faudrait lancer ton programme en pas à pas et surveiller ce qui se passe lors du cN.Connect et lors de la requète.

Déjà, problème ici :
... < '100') cote" & _
"where vin.id_tvin ...
La chaine dinale va donner
... < '100') cotewhere vin.id_tvin ...
--> cotewhere : problème --> ajouter un espace pour séparer les mots clés

Première chose : remettre en forme la requète pour être lisible ET détecter facilement les erreurs :
strSQL =  ""
strSQL = strSQL & "select cote.indice, "
strSQL = strSQL & "       cote.cote_actuelle "
strSQL = strSQL & "  from t_detail_vin pr, "
strSQL = strSQL & "       type_vin vin, "
strSQL = strSQL & "      (select ind.id_tvin, "
strSQL = strSQL & "              ind.milesime millesime, "
strSQL = strSQL & "              c.cote cote_actuelle, "
strSQL = strSQL & "              ind.id_indice indice "
strSQL = strSQL & "         from t_indices ind, "
strSQL = strSQL & "              cote_annuelle c "
strSQL strSQL & "        where ind.id_indice c.id_indice"
strSQL = strSQL & "          and ind.format in('Bouteille') "
strSQL = strSQL & "          and c.annee='2010' "
strSQL = strSQL & "          and ind.id_indice not in ('1','2','3') "
strSQL = strSQL & "          and ind.id_indice < '100') cote"
strSQL strSQL & "  where vin.id_tvin pr.id_tvin "
strSQL strSQL & "    and pr.milesime cote.millesime "
strSQL = strSQL & "    and vin.id_tvin=cote.id_tvin "
strSQL = strSQL & "    and vin.proprietaire not in ('Indifferent') "
strSQL = strSQL & "    and vin.proprietaire is not null "
strSQL = strSQL & "  order by cote.indice"

Bien que tu dises que ta requète fonctionne correctement sur un autre support, quelques détails m'intriguent et qui te font mentir :
- Un Select à l'intérieur d'un From : quelle drôle d'idée !
Pas sûr que cela puisse fonctionner ET, de toute façon, c'est forcément incorrect puisque ton deuxième Select fournit 4 champs !
Ça n'a aucun sens.

- Dans ta database, de quel type sont les champs id_indice et annee ?
A mon avis, ce doivent être des chiffres.
Dans ce cas, la valeur à laquelle tu compares ces champ ne doit pas être encadrée par des '
c.annee = 2010
nd.id_indice not in (1, 2, 3)
ind.id_indice < 100

- Le In dans une clause Where ralentit les requètes.
Si tu n'as qu'un seul élément après le In, c'est que la syntaxe n'est pas optimale :
ind.format in('Bouteille')
Préfère
ind.format = 'Bouteille'
Idem pour 'Indifférent'

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
ajor Messages postés 90 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2020
18 juin 2010 à 13:06
Bonjour,
Merci beaucoup pour ces conseils.

J'ai fait comme tu as dit, réécrit la requête (c'est déjà plus lisible comme ça !) et fait le débogage pas à pas, et en effet, le message d'erreur apparait à la ligne
MsgBox Err.Number & vbCr & Err.Description


Voici le code en entier :

Option Explicit

Public cN As ADODB.Connection
Public rs As ADODB.Recordset

Public Function conNect() As Boolean
    
    On Error GoTo conNect_Err
    Set cN = New ADODB.Connection
    cN.ConnectionString = "Provider=msdaora;Data Source=OIIUI;User Id=xxxxxxx;Password=xxxxxxxxxx;"
    cN.Open
    conNect = True
    Exit Function
    
conNect_Err:

    MsgBox Err.Number & vbCr & Err.Description
    conNect = True
    
End Function

Public Function DeconNect() As Boolean

    On Error Resume Next
    cN.Close
    Set cN = Nothing
    
End Function

Private Sub Workbook_Open()
Dim strSQL As String
Dim i As Integer
Dim j As Integer

    On Error GoTo Workbook_Open_Err
    
    If conNect() = True Then
    
        Set rs = New ADODB.Recordset
        rs.CursorLocation = adUseClient
        
strSQL = ""
strSQL = strSQL & "select cote.indice, "
strSQL = strSQL & "       cote.cote_actuelle "
strSQL = strSQL & "  from t_detail_vin pr, "
strSQL = strSQL & "       type_vin vin, "
strSQL = strSQL & "      (select ind.id_tvin, "
strSQL = strSQL & "              ind.milesime millesime, "
strSQL = strSQL & "              c.cote cote_actuelle, "
strSQL = strSQL & "              ind.id_indice indice "
strSQL = strSQL & "         from t_indices ind, "
strSQL = strSQL & "              cote_annuelle c "
strSQL strSQL & "        where ind.id_indice c.id_indice"
strSQL = strSQL & "          and ind.format in('Bouteille') "
strSQL = strSQL & "          and c.annee='2010' "
strSQL = strSQL & "          and ind.id_indice not in ('1','2','3') "
strSQL = strSQL & "          and ind.id_indice < '100') cote "
strSQL strSQL & "  where vin.id_tvin pr.id_tvin "
strSQL strSQL & "    and pr.milesime cote.millesime "
strSQL = strSQL & "    and vin.id_tvin=cote.id_tvin "
strSQL = strSQL & "    and vin.proprietaire not in ('Indifferent') "
strSQL = strSQL & "    and vin.proprietaire is not null "
strSQL = strSQL & "  order by cote.indice"
 
      rs.Open strSQL, cN, adOpenForwardOnly, adLockOptimistic
        
        If rs.RecordCount > 0 Then
        
            j = 1
            i = 0
            
          Do While Not rs.EOF And Not rs.BOF
                
    i = i + 1
    Feuil1.Cells(i, j) = rs("cote.indice")
    Feuil1.Cells(i, j + 1) = rs("cote.cote_actuelle")
    rs.MoveNext
                
Loop
            
        End If
        
        DeconNect
        
    Else
    
        'blablabla
        
    End If
    
    Exit Sub

Workbook_Open_Err:
MsgBox Err.Number & vbCr & Err.Description

End Sub


J'ai ajouté l'espace manquant (qui n'était qu'une erreur de copier coller).
Je précise que je n'y connais pas grand chose en VBA, mais assez en SQL, et je suis sûr que cette requête fonctionne bien dans le client Oracle (je viens de la revérifier)
0
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
18 juin 2010 à 17:06
lol, le code avec la MsgBox est la ligne sur laquelle tu arrives après la détection d'une erreur, ce n'est pas la ligne de l'erreur.

Non, ce code SQL ne peut pas fonctionner.
strSQL =  strSQL & "  from t_detail_vin pr, "
strSQL = strSQL & "       type_vin vin, "
strSQL = strSQL & "      (select ind.id_tvin, "
strSQL = strSQL & "              ind.milesime millesime, "
strSQL = strSQL & "              c.cote cote_actuelle, "
strSQL = strSQL & "              ind.id_indice indice "
strSQL = strSQL & "         from t_indices ind, "
strSQL = strSQL & "              cote_annuelle c "
strSQL strSQL & "        where ind.id_indice c.id_indice"
strSQL = strSQL & "          and ind.format in('Bouteille') "
strSQL = strSQL & "          and c.annee='2010' "
strSQL = strSQL & "          and ind.id_indice not in ('1','2','3') "
strSQL = strSQL & "          and ind.id_indice < '100') cote

Ce serait un Select sensé renvoyer le nom d'une table puisqu'il est à l'intérieur du From (car tu as mis une virgule après le nom de la deuxième table type_vin)

Je ne pense pas que ce Select, à l'intérieur du From, soit possible.
Admettons qu'il le soit, ce Select renvoie 4 champs, id_tvin, milesime, cote et id_indice, et tu ne peux pas les associer à un seul alias 'cote'

Alors, encore une hypothèse :
Si SQL est intelligent, il ne prendra en compte que le premier de ces champ, id_tvin : dans ce cas, les autres champs sont appelés mais sans raison.

De toute façon, tu as lu ma première réponse en diagonale : Je t'expliquais aussi comment modifier ta syntaxe pour résoudre le problème des apostrophes ', ainsi que de l'utilisation abusive du In

Vala
Jack, =fr 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

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
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
18 juin 2010 à 17:10
Non, ce n'est pas que Excel n'aime pas les points, mais que tu t'adresses maintenant à un RecordSet, pas à une table.
Dans le RecordSet, seuls subsistent les noms des colonnes, peu importe d'où elles viennent :
    Feuil1.Cells(i, j) = rs("indice")
    Feuil1.Cells(i, j + 1) = rs("cote_actuelle")
0
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
18 juin 2010 à 17:13
En VB (*), cette syntaxe ne fonctionnera pas :
ind.id_indice < '100'
'100' est inférieur à '90' parce que le 1 est avant le 9 dans la table ASCII.
Il faut impérativement que (ou) :
- tu corriges le type du champ pour accepter une valeur numérique et pas un texte représentant un chiffre + supprimer les ' qui encadrent ce 100
- tu demandes à SQL de convertir le texte en chiffre (Convert) afin qu'il puisse faire une comparaison numérique avec le champ.

(*) donc en SQL surement aussi
0
ajor Messages postés 90 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 19 août 2020
18 juin 2010 à 17:37
Je répète que ma requête (qui n'est surement pas parfaite) fonctionne très bien.

Le seul changement que j'ai fait, c'est de rajouter l'alias, et maintenant ça marche correctement.

Donc le problème est résolu !
0
Rejoignez-nous