SQL-строка выбрасывает ошибку “Внешнее имя не определено” при запуске в модуле VBA – имя определено.

Вопрос или проблема

В окне запроса Access SQL-код выполняется корректно и дает точные результаты, однако, когда я переношу код в модуль VBA, я получаю ошибку “Внешнее имя не определено” на [tblAssociate].[AssocID] в функции DMax.

Имя определено, так что не уверен, в чем проблема?

SELECT 
    tblAssociate.AssocID, 
    tblAssociate.PersNo, 
    tblAssociate.Inactive, 
    
    " & DLookup("[Position]", "tblAssocHistory", "[AssocHistoryID] = " & DMax("[AssocHistoryID]", "tblAssocHistory", "[AssocID] = " & [tblAssociate].[AssocID])) & " AS CurrPos, 
    
    tblAssignments.Inactive, 
    tblAssignments.AssignmentID 
    
    FROM tblAssociate 
    INNER JOIN tblAssignments ON tblAssociate.AssocID = tblAssignments.AssocID WHERE 
    (
     ((tblAssociate.Inactive)=True) AND (tblAssignments.Inactive = False)
    ) 
    OR 
    (
      (tblAssociate.Inactive = False) 
      AND 
      (
       " & DLookup("[Position]", "tblAssocHistory", "[AssocHistoryID] = " & DMax("[AssocHistoryID]", "tblAssocHistory", "[AssocID] = " 
       & [tblAssociate].[AssocID])
      ) & " Not In 
       (SELECT ref_Config.ConfigLongDesc FROM ref_Config WHERE ref_Config.ConfigShortDesc In ('Agent Positions')
       )
      ) 
      AND tblAssignments.Inactive = False
     )"

Ошибка возникает в обоих случаях в условии DMax.

Эта строка кода должна предоставить список заданий, которые подлежат отмене, поскольку агент больше не является активным сотрудником.

[tblAssociate].[AssocID] не определяется до тех пор, пока не будет выполнен DLookup и объединен в SQL-запрос. Вы не можете использовать значения из запроса внутри DLookup, которые объединяются в SQL. Я предлагаю вам рассмотреть использование соединений SQL.

Ответ или решение

Ошибку "External Name Not Defined" в вашем SQL-запросе в VBA можно объяснить тем, что вы пытаетесь сослаться на tblAssociate.AssocID в функции DMax, находясь в контексте строки SQL, где эта таблица еще не определена. В промежуточных вычислениях, таких как DLookups или DMax, вы не можете использовать значения из других таблиц, если они не были явно предоставлены в рамках запроса.

Вот несколько шагов, которые помогут вам решить проблему:

Решение 1: Используйте SQL-запросы с объединениями

Вместо использования DMax и DLookup в строке SQL, вы можете написать SQL-запрос с использованием объединений (JOIN), который позволит вам извлекать необходимые данные без необходимости использования подзапросов или функции DLookup.

Пример вашего запроса может выглядеть так:

SELECT 
    tblAssociate.AssocID, 
    tblAssociate.PersNo, 
    tblAssociate.Inactive,
    (SELECT TOP 1 Position FROM tblAssocHistory 
     WHERE AssocID = tblAssociate.AssocID 
     ORDER BY AssocHistoryID DESC) AS CurrPos,
    tblAssignments.Inactive, 
    tblAssignments.AssignmentID 
FROM 
    tblAssociate 
INNER JOIN 
    tblAssignments ON tblAssociate.AssocID = tblAssignments.AssocID 
WHERE 
    (
     (tblAssociate.Inactive = True AND tblAssignments.Inactive = False) 
     OR 
     (tblAssociate.Inactive = False AND 
      (SELECT Position FROM tblAssocHistory 
       WHERE AssocHistoryID = 
         (SELECT MAX(AssocHistoryID) FROM tblAssocHistory 
          WHERE AssocID = tblAssociate.AssocID) 
      NOT IN 
      (SELECT ref_Config.ConfigLongDesc 
       FROM ref_Config 
       WHERE ref_Config.ConfigShortDesc IN ('Agent Positions')))
      AND tblAssignments.Inactive = False)
    )

Этот запрос будет возвращать необходимые данные без необходимости в DMax и DLookup, что устранит ошибки, связанные с неопределенностью внешнего имени.

Решение 2: Использование переменных и циклов в VBA

Если вам нужны такие вычисления в VBA, возможно, стоит рассмотреть вариант выполнения отдельного запроса для извлечения идентификаторов перед основным запросом. Вы можете делать это с помощью Recordset, извлекая данные, которые потом сможете использовать в дальнейших расчетах.

Пример:

Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
Dim sql As String

sql = "SELECT AssocID, PersNo, Inactive FROM tblAssociate"
Set rs = db.OpenRecordset(sql)

Do While Not rs.EOF
    Dim currentAssocID As Long
    currentAssocID = rs!AssocID

    ' Здесь вы можете использовать currentAssocID для выполнения DMax и DLookup
    ' и последующей логики.

    rs.MoveNext
Loop

rs.Close
Set rs = Nothing
Set db = Nothing

Заключение

Использование SQL-запросов с объединениями вместо DLookup и DMax, а также применение подхода с использование Recordset может помочь вам избежать проблемы с ошибкой "External Name Not Defined". Если у вас есть дополнительные вопросы или требуется помощь по другим аспектам вашей задачи, не стесняйтесь обращаться.

Оцените материал
Добавить комментарий

Капча загружается...