使用vba在Access查询中传递参数值

使用vba在Access查询中传递参数值,vba,ms-access,parameter-passing,ms-access-2010,query-parameters,Vba,Ms Access,Parameter Passing,Ms Access 2010,Query Parameters,我们的要求- 我们的供应商很少,我们希望每月生成每个供应商的采购报告,并导出到excel。我认为解决方案是创建一个参数查询,在这里我可以传递供应商ID、月份和年份的值。供应商列表不断变化,并存储在单独的表中。 因此,基本上,我应该能够从该表中顺序读取供应商ID,并将其作为参数传递给我的查询,以生成该供应商的报告 我为我的需求找到的最接近的解决方案是(性质相似)—— 为什么我认为有更好的解决方案- 在建议的解决方案中,我们将创建多个查询并删除这些查询。从概念上讲,我觉得应该有一种方法来创建一个

我们的要求-

我们的供应商很少,我们希望每月生成每个供应商的采购报告,并导出到excel。我认为解决方案是创建一个参数查询,在这里我可以传递供应商ID、月份和年份的值。供应商列表不断变化,并存储在单独的表中。 因此,基本上,我应该能够从该表中顺序读取供应商ID,并将其作为参数传递给我的查询,以生成该供应商的报告

我为我的需求找到的最接近的解决方案是(性质相似)——

为什么我认为有更好的解决方案-

在建议的解决方案中,我们将创建多个查询并删除这些查询。从概念上讲,我觉得应该有一种方法来创建一个参数查询,并使用do while循环将参数的值(在上面的示例中是DeptName)顺序传递给查询并将结果导出到excel

如果我可以使用vba将值传递给参数查询,我应该能够实现这一点。这就是我还没有弄明白的

更新日期:2月24日-

以下是我编写的代码-

Private Sub Monthly_Supplier_Sales_Report_Click()
Dim strDirectoryPath As String
Dim DateFolderName As String
DateFolderName = Format$((DateSerial(year(Date), month(Date), 1) - 1), "YYYY MM")
strDirectoryPath = "C:\dropbox\Accounting\Sales Reports\" & DateFolderName
If Dir(strDirectoryPath, vbDirectory) = "" Then MkDir strDirectoryPath

Dim Filename As String
Dim strSQL1 As String
Dim strSQL2 As String
Dim DesignerCode As String
Dim month1 As String
Dim year1 As Integer
Dim Query1 As DAO.QueryDef
Dim query2 As DAO.QueryDef
Dim rsDesigner As DAO.Recordset

Set rsDesigner = CurrentDb.OpenRecordset("Designer Details Master")

Do While Not rsDesigner.EOF
DesignerCode = rsDesigner![Designer Code]
month1 = "Jan" 'right now hardcoded, will call this programatically
year1 = 2014   'right now hardcoded, will call this programatically

strSQL1 = "SELECT * FROM [Sales Report Generation Data] WHERE [designer code] = '" & DesignerCode & "' AND [Shipping Month]= '" & month1 & "' AND [Shipping Year]=" & year1

strSQL2 = "SELECT * FROM [Sales Report Generation - Monthwise Inventory Snapshot] WHERE [designer code] = '" & DesignerCode & "' AND [Snapshot Month]= '" & month1 & "' AND [Snapshot Year]= " & year1

Set Query1 = CurrentDb.CreateQueryDef(Name:="TempSalesQuery", SQLText:=strSQL1)
Set query2 = CurrentDb.CreateQueryDef(Name:="TempInventoryQuery", SQLText:=strSQL2)

Filename = strDirectoryPath & "\" & DesignerCode & Format$(Now(), " yyyy mm") & ".xls"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "TempSalesQuery", Filename, False, "Sales Report"
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "TempInventoryQuery", Filename, False, "Inventory"

CurrentDb.QueryDefs.Delete "TempSalesQuery"
CurrentDb.QueryDefs.Delete "TempInventoryQuery"

rsDesigner.MoveNext
Loop

End Sub
相反,我想应用的逻辑是-

Do While Not 
assign Value to Parameter 1 = rsDesigner![Designer Code]
assign Value to Parameter 2 = Month1
assign Value to Parameter 3 = Year1
Run the two Parameter queries, for which about three parameters are the input value and export to excel in respective sheets.
Loop

只是我还没有弄明白如何实现这一点。

这里有一个解决方案。注意,我创建了两个查询将使用的函数。 只需创建两个查询并保存它们(请参见下面的示例SQL),添加代码来选择日期,一切都会很好

Option Compare Database
Option Explicit

Dim fvShipMonth     As String
Dim fvShipYear      As Integer
Dim fvDesignerCode  As String

Public Function fShipMonth() As String
    fShipMonth = fvShipMonth
End Function

Public Function fShipYear() As Integer
    fShipYear = fvShipYear
End Function

Public Function fDesignerCode() As String
    fDesignerCode = fvDesignerCode
End Function

Private Sub Monthly_Supplier_Sales_Report_Click()
Dim Filename    As String
Dim strSQL1     As String
Dim strSQL2     As String
Dim DesignerCode As String
Dim month1      As String
Dim year1       As Integer
Dim rsDesigner  As DAO.Recordset

'SAMPLE SQL
'SELECT * FROM [Sales Report Generation Data] " & _
'WHERE [designer code] = '" & fDesignerCode() & "' AND [Shipping Month]= '" & fShipMonth() & "' AND [Shipping Year]=" & fShipYear()

    fvShipMonth = "Jan"
    fvShipYear = 2014
    Set rsDesigner = CurrentDb.OpenRecordset("Designer Details Master")
    Do While Not rsDesigner.EOF
        fvDesignerCode = rsDesigner![Designer Code]
        Filename = strDirectoryPath & "\" & DesignerCode & Format$(Now(), " yyyy mm") & ".xls"
        DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "<your Query 1>", Filename, False, "Sales Report"
        DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "<your Query 2>", Filename, False, "Inventory"
        rsDesigner.MoveNext
    Loop
    rsDesigner.Close
    Set rsDesigner = Nothing
End Sub
选项比较数据库
选项显式
将月份设置为字符串
以整数形式显示年份
将fvDesignerCode设置为字符串
作为字符串的公共函数fshipmount()
fShipMonth=fvShipMonth
端函数
作为整数的公共函数fShipYear()
fShipYear=fvShipYear
端函数
公共函数fDesignerCode()作为字符串
fDesignerCode=fvDesignerCode
端函数
私人分月\供应商\销售\报告\点击()
将文件名设置为字符串
作为字符串的Dim strSQL1
作为字符串的Dim strSQL2
作为字符串的Dim DesignerCode
以字符串形式显示
1作为整数
将rsDesigner作为DAO.Recordset
'示例SQL
“从[销售报告生成数据]中选择*”&_
'其中[designer code]='“&fDesignerCode()&”'和[Shipping Month]='“&fshippMonth()&”'和[Shipping Year]=”&fshippyear()
fvShipMonth=“一月”
Fv年=2014年
Set rsDesigner=CurrentDb.OpenRecordset(“设计器详细信息主控”)
而不是rsDesigner.EOF
fvDesignerCode=rsDesigner![设计师代码]
Filename=strDirectoryPath&“\”&DesignerCode&Format$(Now(),“yyyy-mm”)和“.xls”
DoCmd.transfer电子表格acExport,acSpreadsheetTypeExcel9,”,文件名,False,“销售报告”
DoCmd.transfer电子表格acExport,acSpreadsheetTypeExcel9,”,文件名,False,“库存”
rsDesigner.MoveNext
环
rsDesigner,关闭
设置rsDesigner=Nothing
端接头
  • 打开数据库
  • 创建一个新模块
  • 粘贴以下代码
  • 将光标放在函数测试\我的\代码()中
  • 按F5
  • 将即时窗口中的结果粘贴到响应中

    Option Compare Database
    Option Explicit
    
    Dim fvShipMonth     As String
    Dim fvShipYear      As Integer
    Dim fvDesignerCode  As String
    
    Public Function fShipMonth() As String
        fShipMonth = fvShipMonth
    End Function
    
    Public Function fShipYear() As Integer
        fShipYear = fvShipYear
    End Function
    
    Public Function fDesignerCode() As String
        fDesignerCode = fvDesignerCode
    End Function
    
    Function TEST_MY_CODE()
        My_Click_EVENT      ' Test the code I provided
    End Function
    
    Private Sub My_Click_EVENT()
    Dim month1      As String
    Dim year1       As Integer
    
    fvShipMonth = "Jan"
    fvShipYear = 2014
    Debug.Print "**** START TEST ****"
    Debug.Print "fvShipMonth = " & fvShipMonth
    Debug.Print "fvShipYear = " & fvShipYear
    Debug.Print "fShipMonth() = " & fShipMonth()
    Debug.Print "fShipYear() = " & fShipYear()
    Debug.Print "**** END TEST ****"
    
    End Sub
    

  • 不知道你已经走了多远,也不知道你是否对你发布的链接中列出的步骤感到满意,但这里是我的建议。(1) 创建一个简单的表单(a)一个列表框12个月;(b) 列表框多年;(c) 供应商列表框/组合框**如果您总是希望为所有供应商运行报告,则省略;(d) 提交报告的命令按钮;(e) 在按钮单击事件中添加VBA代码,从列表框/组合框中选择值,为记录集创建过滤器,然后打开通过过滤器的报告。如果您对这种方法感兴趣,我可以添加更多关于如何实现的细节。我已经能够按照两个链接中给出的解决方案编写代码,并获得所需的结果。但我觉得应该有更好的解决办法。即使按照您的建议,我也在想,为什么我们必须创建表单来获取价值,因为我的计划是在每个月的第4/5天运行此表单,以获取所有供应商上个月的报告。因此,理想情况下,我们应该能够使用vba代码定义月份、年份和供应商的值。当然,您可以让它自动运行--我只是想您可能希望在需要时灵活地运行报告--如果您只需要某个供应商,则可以为选定的供应商运行报告。如您附加的链接所示,该查询不需要删除,您可以使用“TransferSpreadsheet”查询(至少在Office 2010及更高版本中)。你应该让你的查询接受日期和供应商的参数(或函数)(除非你想要所有供应商),然后在VBA中设置参数。编辑上面的问题-包括我根据给出的两个解决方案使用的代码。您好,谢谢您的解决方案。但它似乎对我不起作用。事实上,我花了很长时间才弄明白公共功能等概念,但这些功能似乎没有任何价值。我插入了一个msgbox并验证了函数是否返回空/零。原因可能是什么?我做错什么了吗?我不知道你是如何实现我的建议的-你复制了所有的代码吗?你的msgbox在哪里?在“分月供应商销售报告”中?请注意,我在22小时前编辑了代码,因为我忘记了SQL中函数名后面的()。还要小心,因为变量名与函数名相似!!下面是如何使用上述方法进行测试:(1)在设置fvShipMonth和fvShipYear之后放置以下msgbox:msgbox“Mo:”&fvShipMonth&vbTab&“Yr:”&fvShipYear&vbTab&“fMo:”&fvShipMonth()&vbTab&“fYr:&fShipYear()。复制了模块2中的公共函数。修改了要设置的参数查询