2010-11-10 21 views
0

Cette requête sous la forme-données-source d'enregistrement fonctionne bien, le retour des valeurs exactes que je veuxrequête SQL dans MS Access VBA

SELECT tblRevRelLog_Detail.RevRelTrackingNumber, tblRevRelLog_Detail.PartNumber, tblRevRelLog_Detail.ChangeLevel, tblRevRelLog_Detail.Version, tblRevRelLog_Detail.JobPnType, tblRevRelLog_Detail.EdsName, tblRevRelLog_Detail.DetailerNamePerPartNumber, tblRevRelLog_Detail.DetailerCompanyPerPartNumber 
FROM tblRevRelLog_Detail 
LEFT JOIN tblEventLog ON tblRevRelLog_Detail.PartNumber = tblEventLog.PartNumber 
WHERE (((tblEventLog.PartNumber) Not In 
    (SELECT tblEventLog.PartNumber 
    FROM tblEventLog 
    WHERE tblEventLog.EventTypeSelected = 'pn REMOVED From Wrapper' 
     AND tblEventLog.TrackingNumber = tblRevRelLog_Detail.RevRelTrackingNumber))) 
ORDER BY tblRevRelLog_Detail.PartNumber; 

Mais si j'écris la même requête dans la VBA. Il ne retourne rien

strNewSql = "SELECT tblRevRelLog_Detail.PartNumber, tblRevRelLog_Detail.ChangeLevel, tblRevRelLog_Detail.ID FROM tblRevRelLog_Detail LEFT JOIN tblEventLog ON tblRevRelLog_Detail.PartNumber = tblEventLog.PartNumber" 
strNewSql = strNewSql & " WHERE ((tblEventLog.PartNumber) Not In (SELECT tblEventLog.PartNumber FROM tblEventLog WHERE tblEventLog.EventTypeSelected = 'pn REMOVED From Wrapper' AND tblEventLog.TrackingNumber = tblRevRelLog_Detail.RevRelTrackingNumber);" 

Quelque chose ne va pas avec la requête ?? Est-ce que quelqu'un peut m'aider!

+3

Avez-vous imprimé la requête SQL retournée par vous et collée dans la fenêtre de conception de la requête? Vous pouvez le faire avec 'Debug.Print strNewSql', cela affichera la fenêtre immédiate. – Fionnuala

+0

Cette requête affiche les enregistrements maintenant, mais elle affiche tous les numéros de pièce de la base de données. lorsque j'utilise la même requête dans le formulaire. Il affiche les numéros de pièces qui sont liés au numéro de suivi. Mais si j'utilise la même requête dans VBA. C'est afficher tous les numéros de pièces de la base de données. – user397316

Répondre

0

Je suppose que votre tempTrackingNumber variable est mauvaise

+0

Il ne retourne rien si j'utilise cette condition également tblEventLog.TrackingNumber = tblRevRelLog_Detail.RevRelTrackingNumber – user397316

+0

Par exemple, RevRelTrackingNumber est-il vraiment un champ de texte? – Fionnuala

+0

Il est alphanumérique – user397316

0

Si RevRelTrackingNumber est numérique, vous ne devez placer entre guillemets.

+0

Il est alphanumérique – user397316

0

Quel est le type de données de tempTrackingNumber? Votre code (avant tronqué) montre ceci:

...tblRevRelLog_Detail.RevRelTrackingNumber = """ & tempTrackingNumber & """);" 

Cela implique qu'il est une chaîne, et il sera traité comme tel.

Si c'est en fait numérique, vous voulez ceci:

...tblRevRelLog_Detail.RevRelTrackingNumber = " & tempTrackingNumber & ");" 
+0

tempTrackingNumber est alphanumérique – user397316

0

D'abord, les requêtes ne sont pas les mêmes. Par exemple, votre texte en texte clair comporte huit colonnes dans la clause SELECT, où la version VBA n'en a que trois. Deuxièmement, vous utilisez le même nom de table, tblEventLog, deux fois dans la même étendue. Vous devrez donc utiliser au moins un nom de corrélation de table. Je sais que le préfixe tbl est un «point de fierté» dans le monde Access, mais il rend les noms de tables plus longs et plus difficiles à lire (les préfixes sont spécifiquement interdits par le ISO 11179 Standard pour le nommage des éléments de données:)) ... Pourquoi ne pas utiliser les noms de corrélation de table tout au long?

Troisièmement, IIRC EXISTS fonctionne mieux que IN pour l'accès (ACE/Jet/whatever) et l'OMI est plus facile à comprendre (DISTINCT..INNER JOIN peut faire encore mieux, mais est encore plus difficile à lire, l'OMI).

est ici une ré-écriture suggéré:

SELECT D1.PartNumber, D1.ChangeLevel, 
     D1.ID 
    FROM tblRevRelLog_Detail AS D1 
     LEFT OUTER JOIN tblEventLog AS E1 
      ON D1.PartNumber = E1.PartNumber 
WHERE NOT EXISTS (
        SELECT * 
        FROM tblEventLog AS E2 
        WHERE E2.EventTypeSelected = 'pn REMOVED From Wrapper' 
          AND E2.TrackingNumber = D1.RevRelTrackingNumber 
          AND E2.PartNumber = E1.PartNumber 
       ); 

MISE À JOUR: Il semble que je me suis trompé sur l'EXIST donnant l'être mieux, donc voici quelques plus récrire à choisir:

SELECT D1.PartNumber, D1.ChangeLevel, 
     D1.ID 
    FROM tblRevRelLog_Detail AS D1 
     LEFT OUTER JOIN tblEventLog AS E1 
      ON D1.PartNumber = E1.PartNumber 
WHERE E1.PartNumber NOT IN 
     (
     SELECT E2.PartNumber 
      FROM tblEventLog AS E2 
     WHERE E2.EventTypeSelected = 'pn REMOVED From Wrapper' 
       AND E2.TrackingNumber = D1.RevRelTrackingNumber 
     ); 

En fait, j'ai du mal à obtenir ce réécrit en utilisant les jointures propriétaires d'Access. Je reçois toujours une erreur "Catastrophic failure". Voici le code repro, où je vais mal ?:

Sub grjieopgj() 

    On Error Resume Next 
    Kill Environ$("temp") & "\DropMe.mdb" 
    On Error GoTo 0 

    Dim cat 
    Set cat = CreateObject("ADOX.Catalog") 
    With cat 
    .Create _ 
     "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
     "Data Source=" & _ 
     Environ$("temp") & "\DropMe.mdb" 
    With .ActiveConnection 

     Dim Sql As String 
     Sql = _ 
     "CREATE TABLE tblRevRelLog_Detail " & vbCr & "(" & vbCr & _ 
     " PartNumber VARCHAR(20), " & vbCr & " EventTypeSelected VARCHAR(20), " & vbCr & _ 
     " TrackingNumber VARCHAR(20), " & vbCr & " RevRelTrackingNumber VARCHAR(20), " & vbCr & _ 
     " ChangeLevel VARCHAR(20), ID VARCHAR(20)" & vbCr & ");" 
     .Execute Sql 

     Sql = _ 
     "CREATE TABLE tblEventLog " & vbCr & "(" & vbCr & _ 
     " PartNumber VARCHAR(20), " & vbCr & " EventTypeSelected VARCHAR(20), " & vbCr & _ 
     " TrackingNumber VARCHAR(20), " & vbCr & " RevRelTrackingNumber VARCHAR(20), " & vbCr & _ 
     " ChangeLevel VARCHAR(20), ID VARCHAR(20)" & vbCr & ");" 

     Sql = _ 
     "SELECT DISTINCT D1.PartNumber, D1.ChangeLevel," & _ 
     " " & vbCr & "  D1.ID " & vbCr & " FROM (" & vbCr & "  tblRevRelLog_Detail" & _ 
     " AS D1" & vbCr & "  LEFT OUTER JOIN tblEventLog" & _ 
     " AS E1" & vbCr & "   ON D1.PartNumber = E1.PartNumber" & vbCr & "" & _ 
     "  )" & vbCr & "  LEFT OUTER JOIN tblEventLog" & _ 
     " AS E2" & vbCr & "   ON AND E2.TrackingNumber" & _ 
     " <> D1.RevRelTrackingNumber" & vbCr & "   " & _ 
     " AND E2.PartNumber <> E1.PartNumber" & vbCr & " WHERE" & _ 
     " E2.EventTypeSelected = 'pn REMOVED From" & _ 
     " Wrapper';" 

     Dim rs 
     Set rs = .Execute(Sql) 
     MsgBox rs.GetString 
    End With 
    Set .ActiveConnection = Nothing 
    End With 
End Sub 
+0

NOT EXISTS n'est pas plus fiable en ce qui concerne l'utilisation d'index des deux côtés que NO IN. En effet, selon mon expérience, c'est moins vrai. –

+0

@ David-W-Fenton: J'ai maintenant réécrit en utilisant 'NOT IN' mais ma réécriture' JOIN' est en train de recevoir une erreur "Catastrophic failure" (voir VBA en réponse). Une idée de ce que cela signifie? – onedaywhen

+0

Je n'ai jamais vu ces mots alarmants dans un message d'erreur Jet/ACE/Access. NOT IN n'est pas fiable avec l'utilisation des index des deux côtés, aussi. Les deux EXISTS et IN utilisent les index des deux côtés, cependant. Peut-être qu'il y a un moyen d'inverser la logique à un autre niveau? –

0

On dirait que vous manque un support de fermeture. Ajouter ")" à la fin de la requête dans VBA et essayez.