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
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
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