2010-11-10 3 views
0

Этот запрос в форм-Data-Record Source работает нормально, возвращая точные значения, которые я хочуSQL запросов в 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; 

Но если я пишу один и тот же запрос в VBA. Она не возвращает ничего

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);" 

Что-то не так с запросом ?? Кто-нибудь может мне помочь!

+3

Вы распечатали запрос sql, возвращенный вами, и ввели его в окно дизайна запроса? Вы можете сделать это с помощью 'Debug.Print strNewSql', это напечатает в ближайшее окно. – Fionnuala

+0

Этот запрос отображает записи сейчас, но он отображает все партитуры из базы данных. когда я использую тот же запрос в форме. Он отображает правые частичные числа, связанные с номером отслеживания. Но если я использую тот же запрос в VBA. Это отображает все Partnumbers из БД. – user397316

ответ

0

Я подозреваю, что ваша переменная tempTrackingNumber плохо

+0

Он ничего не возвращает, если я использую это условие и tblEventLog.TrackingNumber = tblRevRelLog_Detail.RevRelTrackingNumber – user397316

+0

Например, RevRelTrackingNumber действительно текстовое поле? – Fionnuala

+0

Это буквенно-цифровое – user397316

0

Если RevRelTrackingNumber числовой вам не нужно заключать в кавычки.

+0

Это буквенно-цифровой – user397316

0

Какой тип данных tempTrackingNumber? Ваш код (передний укороченный) показывает, что это:

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

Это означает, что это строка, и он будет рассматриваться как таковые.

Если это на самом деле цифровой, вы хотите вместо этого:

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

tempTrackingNumber является буквенно-цифровым – user397316

0

Во-первых, запросы не совпадают. Например, ваш открытый текст SQL содержит восемь столбцов в предложении SELECT, где версия VBA имеет только три.

Во-вторых, вы используете одно и то же имя таблицы, tblEventLog, дважды в том же объеме. Поэтому вам нужно будет использовать хотя бы одно имя корреляции таблицы. Я знаю, что префикс tbl является «точкой гордости» в мире доступа, но он делает ваши имена таблиц более длинными и трудными для чтения IMO (а префиксы специально запрещены ISO 11179 Standard для именования элементов данных:)) ... поэтому почему бы не использовать имена корреляции таблиц?

В-третьих, IIRC EXISTS работает лучше, чем IN для доступа (ACE/Jet/все) и ИМО легче понять (DISTINCT..INNER JOIN может работать еще лучше, но опять-таки труднее читать, ИМО).

Вот предложил переписать:

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

UPDATE: Кажется, я был неправ о EXIST подаче быть лучше, так что вот еще пару переписать на выбор:

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

На самом деле, я изо всех сил пытаюсь переписать эту запись с использованием собственных соединений Access. Я все время получаю ошибку «Катастрофический сбой». Вот код, где я ошибаюсь ?:

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 не более достоверен в отношении использования индекса с обеих сторон, чем NO IN. Действительно, по моему опыту, это меньше. –

+0

@ David-W-Fenton: Я переписал запись с помощью 'NOT IN', но моя перезапись JOIN получает ошибку« Катастрофическая ошибка »(см. VBA в ответе). Любая идея, что это значит? – onedaywhen

+0

Я никогда не видел этих тревожных слов в сообщении об ошибке Jet/ACE/Access. NOT IN является ненадежным с использованием индексов с обеих сторон. Тем не менее, как EXISTS, так и IN используют индексы с обеих сторон. Может быть, есть способ изменить логику на другом уровне? –

0

Похоже, что вам не хватает закрывающей скобки. Добавьте «)» в конце запроса в VBA и попробуйте.

Смежные вопросы