【问题标题】:Exporting a parameterized query to excel using vba使用 vba 将参数化查询导出到 excel
【发布时间】:2013-11-08 10:40:13
【问题描述】:

我想通过单击表单中的按钮将查询结果导出到 Excel 文件。

为此,我使用了这段代码并且效果很好:

Private Sub Command9_Click()

On Error GoTo ProcError

DoCmd.OutputTo _
ObjectType:=acOutputQuery, _
ObjectName:="Contract Type Billing", _
OutputFormat:=acFormatXLSX, _
Autostart:=True

ExitProc:
Exit Sub
ProcError:
Select Case Err.Number
Case 2501 'User clicked on Cancel
Case Else
MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical, _
"Error in cmdExportQuery_Click event procedure..."
End Select
Resume ExitProc

End Sub

但我的查询使用了 2 个参数 sdateedate,我不想访问询问我这些值,但我希望用户在表单中输入它们使用适当的文本框。

所以我在 DoCMD.OutputTo 之前的代码中添加了这一点

Dim qdf As DAO.QueryDef

Set qdf = CurrentDb.QueryDefs("Contract Type Billing")

qdf.Parameters("sdate") = sdate.Value
qdf.Parameters("edate") = edate.Value

但不幸的是,它不起作用。在导出之前如何将参数放入我的查询中?

【问题讨论】:

    标签: sql excel vba ms-access


    【解决方案1】:

    如果您想保持原始参数查询不变,您可以创建一个临时 QueryDef 将数据转储到临时表中,然后将临时表输出到 Excel:

    Dim cdb As DAO.Database, qdf As DAO.QueryDef
    Const tempTableName = "_tempTbl"
    Set cdb = CurrentDb
    On Error Resume Next
    DoCmd.DeleteObject acTable, tempTableName
    On Error GoTo 0
    Set qdf = cdb.CreateQueryDef("")
    qdf.SQL = "SELECT * INTO [" & tempTableName & "] FROM [Contract Type Billing]"
    qdf.Parameters("sdate").Value = DateSerial(2013, 1, 3)  ' test data
    qdf.Parameters("edate").Value = DateSerial(2013, 1, 5)
    qdf.Execute
    Set qdf = Nothing
    Set cdb = Nothing
    DoCmd.OutputTo acOutputTable, tempTableName, acFormatXLSX, "C:\__tmp\foo.xlsx", True
    

    【讨论】:

    • 效果很好。但我认为 .Execute 命令只适用于更新、添加和删除查询。
    • @Tom SELECT ... INTO 也是一个动作查询。在 Access 应用程序 UI 中,它被称为“生成表查询”。
    【解决方案2】:

    我遇到了同样的问题,我宁愿在 sql 脚本中插入 WHERE 条件并将查询结果直接导出到 excel 中(当然你必须定义一个目标文件),而不是使用参数。假设 Contract Type Billing 中的日期字段名为 dDate。

    Set qdf = CurrentDb.CreateQueryDef("qTempQuery")
    qdf.SQL = "SELECT * FROM [Contract Type Billing] WHERE ((([Contract Type Billing].dDate)>#" _
        & cdate(sdate.value) & "# And ([Contract Type Billing].dDate)<#" & cdate(edate.value) & "#));"
    DoCmd.OutputTo acOutputQuery, "qTempQuery", "ExcelWorkbook(*.xlsx)", OutputFileName, False
    DoCmd.DeleteObject acQuery, "qTempQuery"
    Set qdf = Nothing
    

    【讨论】:

      【解决方案3】:

      一种方法是: 假设表单名称是 [MyForm],文本框仍然是 [sdate] 和 [edate], 然后删除 PARAMETERS 部分(如果您的查询中存在)。将查询中的 [sdate] 和 [edate] 替换为 eval("Forms![MyForm]![sdate]") 和 eval("Forms![MyForm]![edate]")

      另一种方法是在模块中创建公共函数:

      Global m_sdate as date
      Global m_edate as date
      
      Public Function sdate() as date
           sdate = m_sdate
      end function
      
      Public Function edate() as date
           edate = m_edate
      end function
      

      将查询中的 [sdate] 和 [edate] 替换为调用 sdate() 和 edate()。 并在导出前添加分配:

      m_sdate = Me.sdate.Value
      m_edate = Me.edate.Value
      
      DoCmd.OutputTo ............
      

      【讨论】:

      • 如果我删除我的参数部分,我将无法以其他形式运行我的查询不是吗?我尝试了第二个选项,但它在运行我的查询时出现编译错误。它似乎无法识别 sdate() 和 edate()
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      相关资源
      最近更新 更多