Как узнать из VBA, какую таблицу создает запрос в MS ACCESS? - PullRequest
2 голосов
/ 13 марта 2020

Я написал ниже Sub, чтобы выполнить несколько Make-table запросов, некоторые из которых используют параметр Some_date

Sub run_query(queryName As String, Optional Some_date As Date)
    Form_Select_input.logProgress queryName

    Dim qdf As DAO.QueryDef
    Set qdf = CurrentDb.QueryDefs(queryName)
    On Error Resume Next
    qdf!Date_after = Date_after
    On Error GoTo 0
    qdf.Execute
    Set qdf = Nothing
End Sub

Типичный запрос выглядит как

PARAMETERS Some_date DateTime;
SELECT  Some_field
    ,   Other_field
INTO Some_Target
FROM Some_Source
    LEFT JOIN Other_Source
    ON Some_Source.key = Other_Source.key
where Some_Source.Transaction_Date > [Some_date];

Теперь это работает в первый раз, когда я запускаю запросы, но во второй раз выдает ошибку, таблицы уже существуют, поэтому я хотел бы написать что-то вроде

Sub run_query(queryName As String, Optional Some_date As Date)
    Form_Select_input.logProgress queryName

    Dim qdf As DAO.QueryDef
    Set qdf = CurrentDb.QueryDefs(queryName)

    On Error Resume Next
    DoCmd.DeleteObject acTable, qdf.Destination ' At first execution, the destination does not exist, but we resume next 
    qdf!Date_after = Date_after                 ' For some queries, the parameter does not exist, but we resume next
    On Error GoTo 0
    qdf.Execute
    Set qdf = Nothing
End Sub

Пожалуйста, помогите мне заменить qdf.Destination на что-то, что существует.

Ответы [ 3 ]

1 голос
/ 13 марта 2020

Системные таблицы Access могут дать вам имя таблицы, созданной сохраненным запросом make-table.

Рассмотрим этот запрос:

queryName = "typical_query"
? CurrentDb.QueryDefs(queryName).SQL
SELECT Year(i.OrderDate) AS [Year], Count(i.OrderID) AS TotalOrders
INTO Some_Target
FROM Invoice AS i
GROUP BY Year(i.OrderDate);

Сначала найдите значение Id запроса в таблице MSysObjects:

queryId = DLookup("Id", "MSysObjects", "[Name]='" & queryName & "'")
? queryId
-2147483409 

Затем найдите строку MSysQueries для этого Id (ObjectId в MSysQueries), где значение поля Attribute равно 1. Имя созданная таблица хранится в поле Name1:

? DLookup("Name1", "MSysQueries", "ObjectId=" & queryId & " AND [Attribute]=1")
Some_Target

Будьте осторожны с системными таблицами. Вы должны быть в безопасности, чтобы только читать их данные. Но избегайте изменения данных, иначе вы можете сломать вашу базу данных.

Этот подход требует, чтобы ваш пользователь Access имел разрешение на чтение этих таблиц. Если ваша база данных не дает им разрешения на чтение, вы можете выполнить оператор GRANT SELECT, чтобы передать его им. ( GRANT SELECT пример )

1 голос
/ 15 марта 2020

Чтобы получить целевую таблицу, вы можете использовать это в своем коде:

Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.QueryDefs(queryName)
dim strTarget as string

strTarget = trim(Split(Split(qdf.SQL, "INTO")(1), " ")(1))
On Error Resume Next
DoCmd.DeleteObject acTable, strTarget
0 голосов
/ 13 марта 2020

Вы можете просто запросить системные таблицы, чтобы увидеть, существует ли объект.

If DCount("[Name]", "MSysObjects", "[Name] = '" & tblName & "'") = 0 Then
    'do stuff
End If
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...