VBA DAO.OpenRecordSet存在不一致性错误

3

运行Access 2016

我试图从Excel导入MS Access .mdb表中的数据。(我的客户使用的专有软件只能识别*.mdb文件。)当表格关闭时,当我运行这段代码时,会出现以下错误:

Run-Time Error 3061
Too few parameters - Expected 2

如果我在Access中打开表格时运行代码,有一半的时间会出现错误,而另外一半的时间则不会出现:

Run-Time error '3008'
The table 'Daily_Logs_of_Flows' is already opened exclusively by 
another user, or it is already open through the user interface 
and cannot be manipulated programmatically.

这似乎表明VBA有时会通过第一个错误。

我已经检查了变量名,并且由于StackOverflow上的这篇文章,在monthToImport之前和之后使用了单引号和数字符号(#)。错误从中消失了。

Expected 3 

to

Expected 2

这里是代码

Sub importPLCDataFromAccess(monthToImport As Date)

Dim myDbLocation As String
myDbLocation = "K:\Users\WWTP Computer\Documents\POV_Projects\PLC Interface\PLC_Data.mdb"

DIM mySQLCall as String

Set myWorkbook = ActiveWorkbook
Set myDataSheet = myWorkbook.Worksheets("Page 1")

Set myEngine = New DAO.DBEngine
'Set myWorkspace = myEngine.Workspaces(0)
Set myDB = myEngine.OpenDatabase(myDbLocation)
' I deleted the workspace
' Set myDB = myWorkspace.OpenDatabase(myDbLocation)

mySQLCall = "SELECT Time_Stamp, GolfVolume, CreekVolume, InfluentVolume FROM Daily_Logs_of_Flows "
' Limit records to month requested...
mySQLCall = mySQLCall & "WHERE (DATEPART(m,Time_Stamp) = DATEPART(m,#" & monthToImport & "#)) "
'  ... during the year requested
mySQLCall = mySQLCall & "AND (DATEPART(yyyy,Time_Stamp) = DATEPART(yyyy,#" & monthToImport & "#)) "
mySQLCall = mySQLCall & "ORDER BY Time_Stamp"

Debug.Print "mySQLCall = " & mySQLCall
Debug.Print "monthToImport: " & monthToImport

'Error occurs on next line where execute query & populate the recordset

Set myRecordSet = myDB.OpenRecordset(mySQLCall, dbOpenSnapshot)

'Copy recordset to spreadsheet
Application.StatusBar = "Writing to spreadsheet..."
Debug.Print "RecordSet Count = " & myRecordSet.recordCount

If myRecordSet.recordCount = 0 Then
    MsgBox "No data retrieved from database", vbInformation + vbOKOnly, "No Data"
    GoTo SubExit
End If
'....
End Sub  

以下是当前SQL语句的Debug.Print:

mySQLCall = SELECT Time_Stamp, GolfVolume, CreekVolume, InfluentVolume FROM Daily_Logs_of_Flows WHERE (DATEPART(m,Time_Stamp) = DATEPART(m,#6/1/2016#)) AND (DATEPART(yyyy,Time_Stamp) = DATEPART(yyyy,#6/1/2016#)) ORDER BY Time_Stamp

有没有想法,我这里缺少了什么?提前感谢您的帮助。


我不知道答案,但是“独占”错误实际上是“第一个”错误,所以当您遇到运行时错误3061时,实际上已经越过了该错误,而不是反过来。 - OpiesDad
将 SQL 语句的 Debug.Print 直接在 Access 中运行会发生什么? - OpiesDad
1个回答

2
问题在于DATEPART函数需要将第一个参数放在引号中,否则它会查找字段“yyyy”或“m”。
例如:
DATEPART("yyyy", #6/1/2016#)

或者

DATEPART("m", #6/1/2016#)

总共:

SELECT Time_Stamp, GolfVolume, CreekVolume, InfluentVolume _
FROM Daily_Logs_of_Flows 
WHERE (DATEPART("m",Time_Stamp) = DATEPART("m",#6/1/2016#)) 
      AND (DATEPART("yyyy",Time_Stamp) = DATEPART("yyyy",#6/1/2016#)) 
ORDER BY Time_Stamp

为了在 VBA 中实现这一点(如果您不知道的话,但我猜您应该知道),只需每次调用 DATEPART 函数时将引号加倍即可...
例如:
mySQLCall = mySQLCall & "AND (DATEPART(""yyyy"",Time_Stamp)...."

为了完整起见,运行时错误'3008'实际上是第一个错误....只有在确认拥有适当权限后,Access才会尝试运行任何SQL语句。


1
在 SQL 的早期部分中,DATEPART("m")也是同样的事情(就像你在例子中看到的)。 - dbmitch
1
是的,我应该更清楚地说明需要为两者都做。已编辑以澄清。 - OpiesDad
我本来会因为找不到而卡住很长时间的!谢谢!解决了问题。 - PhillipOReilly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接