【问题标题】:How to find out from VBA which table a query in MS ACCESS creates?如何从 VBA 中找出 MS ACCESS 中的查询创建了哪个表?
【发布时间】:2020-03-13 14:11:46
【问题描述】:

我写了下面的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

【问题讨论】:

  • 一个想法是将查询命名为类似于表:MyTable_CreateMyTable。因此,如果您想执行查询MyTable_Create,您需要先搜索一个名为MyTable 的表,方法是从查询名称中删除_Create
  • 好吧,如果我能从头开始设计的话

标签: vba ms-access


【解决方案1】:

Access 系统表可以为您提供保存的生成表查询创建的表的名称。

考虑这个查询:

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

首先在MSysObjects表中找到查询的Id值:

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

然后为IdMSysQueries 中的ObjectId)找到MSysQueries 行,其中Attribute 字段值为1。创建的表的名称存储在Name1 字段中:

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

谨慎使用系统表。您应该安全地只读取他们的数据。但避免修改数据,否则您可能会破坏您的数据库。

此方法要求您的 Access 用户对这些表具有读取权限。如果您的数据库不允许他们读取权限,您可以执行GRANT SELECT 语句将其授予他们。 (GRANT SELECT example)

【讨论】:

    【解决方案2】:

    要获取目标表,您可以在代码中使用它:

    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
    

    【讨论】:

      【解决方案3】:

      您可以只查询系统表来查看对象是否存在。

      If DCount("[Name]", "MSysObjects", "[Name] = '" & tblName & "'") = 0 Then
          'do stuff
      End If
      

      【讨论】:

      • 问题是,tblName 应该是什么
      • 好吧,如果你是自动生成表查询,你应该有这个大声笑
      • 如果我自动创建make table 查询,我确实会。那不是我正在做的事情。
      • 所以你有给你名称的日期部分的参数......我很困惑你怎么没有这些信息?我只是错过了这里的重点吗?
      猜你喜欢
      • 2011-12-12
      • 2012-02-08
      • 2010-10-26
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多