MS Access OpenRedcordset 读取错误的字符串
MS Access OpenRedcordset reading wrong string
一般解释:
我的查询2_Totalreturns单个值:
运行 将查询导出到 excel 文件的 VBA 函数:
问题: OpenRecordset
没有读取正确的查询。我的查询应该导出到我的 excel 文件。然而我的 VBA 指向错误的东西。
我猜 qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
行没有提供足够的信息?
SQL
SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold
FROM dbo_SO_SalesHistory
WHERE (((dbo_SO_SalesHistory.InvoiceDate)
BETWEEN [Forms]![RUN]![textBeginOrderDate] AND [Forms]![RUN]![textendorderdate]));
VBA
Option Compare Database
Option Explicit
Public Function TRANS2()
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim xlWS As Excel.Worksheet
Dim acRng As Variant
Dim xlRow As Integer
Dim db As DAO.Database
Dim qry As QueryDef
Dim rst As Recordset
Dim prm As DAO.Parameter
Dim strSQL As String
Set db = CurrentDb
Set xlApp = New Excel.Application
Set xlWB = xlApp.Workbooks.Open("C:\Users\J\Desktop\August 2017.xlsx")
Set xlWS = xlWB.Worksheets("Totals")
xlRow = (xlWS.Columns("K").End(xlDown).Row)
Set qry = db.QueryDefs("2_Total")
strSQL = strSQL & " [dbo_SO_SalesHistory].[InvoiceDate] Between #" _
& [Forms]![Run]![textBeginOrderDate] & "# And #" _
& [Forms]![Run]![textendorderdate] & "#"
qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
Set rst = db.OpenRecordset("2_Total", dbOpenDynaset)
Dim c As Integer
c = 11 'C is the one that stores column number, in which c=1 means column A, 11 is for column K, 12 for Column L
xlRow = xlRow + 11
Do Until rst.EOF
For Each acRng In rst.Fields
xlWS.Cells(xlRow, c).Formula = acRng
c = c + 1
Next acRng
xlRow = xlRow + 1
c = 1
rst.MoveNext
If xlRow > 25 Then GoTo rq_Exit
Loop
rq_Exit:
rst.Close
Set rst = Nothing
Set xlWS = Nothing
xlWB.Close acSaveYes
Set xlWB = Nothing
xlApp.Quit
Set xlApp = Nothing
Exit Function
End Function
我可能删得太多了,但是如果“2_Totals”SQL代码就是:
SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold
FROM dbo_SO_SalesHistory
WHERE (((dbo_SO_SalesHistory.InvoiceDate)
BETWEEN [Forms]![RUN]![textBeginOrderDate] AND [Forms]![RUN]![textendorderdate]));
然后以下代码将查找该值并将其放置在 Excel 中引用的单元格中。有一个循环,这似乎没有意义,因为查询 returns 是一个单一的值,所以我删除了它。我不明白为什么你找到最后一行然后向它添加 11 行,但如果它更改了错误的单元格,请注释掉 xlRow = xlRow + 11
行。
Option Explicit
Public Function TRANS2()
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim xlWS As Excel.Worksheet
Dim xlRow As Integer
Dim dblOutput As Double
Dim db As DAO.Database
Set db = CurrentDb
Set xlApp = New Excel.Application
Set xlWB = xlApp.Workbooks.Open("C:\Users\J\Desktop\August 2017.xlsx")
Set xlWS = xlWB.Worksheets("Totals")
xlRow = (xlWS.Columns("K").End(xlDown).Row)
dblOutput = DLookup("[SumOfDollarsSold]", "2_Totals")
xlRow = xlRow + 11
xlWS.Cells(xlRow, 11).Value = dblOutput
rq_Exit:
Set xlWS = Nothing
xlWB.Close acSaveYes
Set xlWB = Nothing
xlApp.Quit
Set xlApp = Nothing
Set db = Nothing
End Function
考虑在 OpenRecordset
之前释放 querydef,因为记录集调用使用最后保存的查询实例而不是对 SQL 的更改,因为您从未官方保存:
qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
Set qry = Nothing
Set rst = db.OpenRecordset("2_Total", dbOpenDynaset)
或者更好的是,直接从 querydef 打开记录集,使用 QueryDef.OpenRecordset:
qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
Set rst = qry.OpenRecordset(dbOpenDynaset)
但正如@ThomasG 评论的那样,请仔细检查您的代码并相应地整合上述建议。这个 SELECT
语句似乎没有输出单行单列的结果集。但是,您发布的 SQL 确实 return 一个 row/one-column 合计。我怀疑你打算:
strSQL = "SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold" _
& " FROM dbo_SO_SalesHistory" _
& " WHERE [dbo_SO_SalesHistory].[InvoiceDate] BETWEEN #" _
& [Forms]![Run]![textBeginOrderDate] & "# AND #" _
& [Forms]![Run]![textendorderdate] & "#"
qry.SQL = strSQL
但是,我建议使用参数化来获得更干净、更安全、可维护的代码。
strSQL = "PARAMETERS [BeginDate] Datetime, [EndDate] Datetime;" _
& " SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold" _
& " FROM dbo_SO_SalesHistory" _
& " WHERE [dbo_SO_SalesHistory].[InvoiceDate]" _
& " BETWEEN [BeginDate] AND [EndDate];"
qry.SQL = strSQL
qry![BeginDate] = [Forms]![Run]![textBeginOrderDate]
qry![EndDate] = [Forms]![Run]![textendorderdate]
Set rst = qry.OpenRecordset(dbOpenDynaset)
是的,上面的 VBA 字符串可以而且应该作为 Access 查询对象单独保存。所以不需要每次都重新写 SQL 。每次绑定不同的动态参数即可!
Set qry = db.QueryDefs("2_Total") ' ABOVE STRING SQL STATEMENT WITH PARAMETERS
qry![BeginDate] = [Forms]![Run]![textBeginOrderDate]
qry![EndDate] = [Forms]![Run]![textendorderdate]
Set rst = qry.OpenRecordset(dbOpenDynaset)
一般解释:
我的查询2_Totalreturns单个值:
运行 将查询导出到 excel 文件的 VBA 函数:
问题: OpenRecordset
没有读取正确的查询。我的查询应该导出到我的 excel 文件。然而我的 VBA 指向错误的东西。
我猜 qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
行没有提供足够的信息?
SQL
SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold
FROM dbo_SO_SalesHistory
WHERE (((dbo_SO_SalesHistory.InvoiceDate)
BETWEEN [Forms]![RUN]![textBeginOrderDate] AND [Forms]![RUN]![textendorderdate]));
VBA
Option Compare Database
Option Explicit
Public Function TRANS2()
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim xlWS As Excel.Worksheet
Dim acRng As Variant
Dim xlRow As Integer
Dim db As DAO.Database
Dim qry As QueryDef
Dim rst As Recordset
Dim prm As DAO.Parameter
Dim strSQL As String
Set db = CurrentDb
Set xlApp = New Excel.Application
Set xlWB = xlApp.Workbooks.Open("C:\Users\J\Desktop\August 2017.xlsx")
Set xlWS = xlWB.Worksheets("Totals")
xlRow = (xlWS.Columns("K").End(xlDown).Row)
Set qry = db.QueryDefs("2_Total")
strSQL = strSQL & " [dbo_SO_SalesHistory].[InvoiceDate] Between #" _
& [Forms]![Run]![textBeginOrderDate] & "# And #" _
& [Forms]![Run]![textendorderdate] & "#"
qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
Set rst = db.OpenRecordset("2_Total", dbOpenDynaset)
Dim c As Integer
c = 11 'C is the one that stores column number, in which c=1 means column A, 11 is for column K, 12 for Column L
xlRow = xlRow + 11
Do Until rst.EOF
For Each acRng In rst.Fields
xlWS.Cells(xlRow, c).Formula = acRng
c = c + 1
Next acRng
xlRow = xlRow + 1
c = 1
rst.MoveNext
If xlRow > 25 Then GoTo rq_Exit
Loop
rq_Exit:
rst.Close
Set rst = Nothing
Set xlWS = Nothing
xlWB.Close acSaveYes
Set xlWB = Nothing
xlApp.Quit
Set xlApp = Nothing
Exit Function
End Function
我可能删得太多了,但是如果“2_Totals”SQL代码就是:
SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold
FROM dbo_SO_SalesHistory
WHERE (((dbo_SO_SalesHistory.InvoiceDate)
BETWEEN [Forms]![RUN]![textBeginOrderDate] AND [Forms]![RUN]![textendorderdate]));
然后以下代码将查找该值并将其放置在 Excel 中引用的单元格中。有一个循环,这似乎没有意义,因为查询 returns 是一个单一的值,所以我删除了它。我不明白为什么你找到最后一行然后向它添加 11 行,但如果它更改了错误的单元格,请注释掉 xlRow = xlRow + 11
行。
Option Explicit
Public Function TRANS2()
Dim xlApp As Excel.Application
Dim xlWB As Excel.Workbook
Dim xlWS As Excel.Worksheet
Dim xlRow As Integer
Dim dblOutput As Double
Dim db As DAO.Database
Set db = CurrentDb
Set xlApp = New Excel.Application
Set xlWB = xlApp.Workbooks.Open("C:\Users\J\Desktop\August 2017.xlsx")
Set xlWS = xlWB.Worksheets("Totals")
xlRow = (xlWS.Columns("K").End(xlDown).Row)
dblOutput = DLookup("[SumOfDollarsSold]", "2_Totals")
xlRow = xlRow + 11
xlWS.Cells(xlRow, 11).Value = dblOutput
rq_Exit:
Set xlWS = Nothing
xlWB.Close acSaveYes
Set xlWB = Nothing
xlApp.Quit
Set xlApp = Nothing
Set db = Nothing
End Function
考虑在 OpenRecordset
之前释放 querydef,因为记录集调用使用最后保存的查询实例而不是对 SQL 的更改,因为您从未官方保存:
qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
Set qry = Nothing
Set rst = db.OpenRecordset("2_Total", dbOpenDynaset)
或者更好的是,直接从 querydef 打开记录集,使用 QueryDef.OpenRecordset:
qry.SQL = "SELECT * FROM [dbo_SO_SalesHistory]"
Set rst = qry.OpenRecordset(dbOpenDynaset)
但正如@ThomasG 评论的那样,请仔细检查您的代码并相应地整合上述建议。这个 SELECT
语句似乎没有输出单行单列的结果集。但是,您发布的 SQL 确实 return 一个 row/one-column 合计。我怀疑你打算:
strSQL = "SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold" _
& " FROM dbo_SO_SalesHistory" _
& " WHERE [dbo_SO_SalesHistory].[InvoiceDate] BETWEEN #" _
& [Forms]![Run]![textBeginOrderDate] & "# AND #" _
& [Forms]![Run]![textendorderdate] & "#"
qry.SQL = strSQL
但是,我建议使用参数化来获得更干净、更安全、可维护的代码。
strSQL = "PARAMETERS [BeginDate] Datetime, [EndDate] Datetime;" _
& " SELECT Sum(dbo_SO_SalesHistory.DollarsSold) AS SumOfDollarsSold" _
& " FROM dbo_SO_SalesHistory" _
& " WHERE [dbo_SO_SalesHistory].[InvoiceDate]" _
& " BETWEEN [BeginDate] AND [EndDate];"
qry.SQL = strSQL
qry![BeginDate] = [Forms]![Run]![textBeginOrderDate]
qry![EndDate] = [Forms]![Run]![textendorderdate]
Set rst = qry.OpenRecordset(dbOpenDynaset)
是的,上面的 VBA 字符串可以而且应该作为 Access 查询对象单独保存。所以不需要每次都重新写 SQL 。每次绑定不同的动态参数即可!
Set qry = db.QueryDefs("2_Total") ' ABOVE STRING SQL STATEMENT WITH PARAMETERS
qry![BeginDate] = [Forms]![Run]![textBeginOrderDate]
qry![EndDate] = [Forms]![Run]![textendorderdate]
Set rst = qry.OpenRecordset(dbOpenDynaset)