所以我有一个相对简单的查询,它只有两个参数,其中一个从表单中拉出一个长整数,只从一个表中选择记录,其中一个字段具有该值。 (这是一个设计项目表,用户正在选择应列出项目的设计师。)
如果我打开表单然后手动打开查询,则完美。如果我有第二个表单(用查询结果填充列表框)尝试设置一个等于查询结果的记录集,它会失败并显示“运行时错误'3061'。参数太少。预计为1.”
如果我将参数设置为静态整数,例如3,它工作正常(但显然没用)。为什么我的VBA代码无法从表单上的文本字段中读取文本,而Access本身显然可以?
这是我的问题:
SELECT [Project Request Log TABLE].Designer1, [Project Request Log TABLE].Priority, [Project Request Log TABLE].ProjectName, [Project Request Log TABLE].Manager, [Project Request Log TABLE].SME1, [Project Request Log TABLE].Priority, [Project Request Log TABLE].ProjectID
FROM Designers INNER JOIN [Project Request Log TABLE] ON Designers.ID = [Project Request Log TABLE].Designer1
WHERE ((([Project Request Log TABLE].Designer1)=[Forms]![frm_selectDesigner]![txtDesignerId]) AND (([Project Request Log TABLE].PercentComplete)<>1))
ORDER BY [Project Request Log TABLE].Designer1, [Project Request Log TABLE].Priority;
以下是给出错误的VBA行:
Set rst_projects = dbs.OpenRecordset("qryDesignerProjectPrioritySet", dbOpenDynaset)
感谢。
编辑:选择设计器的表单打开第二个表单,上面的代码尝试打开记录集。原始frm_selectDesigner未关闭,当单击“确定”时隐藏,但仍保持打开状态。
编辑2:如果我包含该行
DoCmd.OpenQuery "qryDesignerProjectPrioritySet"
查询打开并具有正确的结果。如果下一行尝试将该查询的结果分配为上述记录集,则会出现3601错误?我编写OpenRecordset命令的方式肯定存在某种错误,对吗?
答案 0 :(得分:1)
OpenRecordset()
应该是一个简单的基本操作;我无法理解为什么DoCmd.OpenQuery "qryDesignerProjectPrioritySet"
工作时失败了。查看最小程序会发生什么,该程序仅足以尝试OpenRecordset()
。
将以下代码作为新的标准模块插入,并从VB Editor的主菜单中运行Debug-&gt; Compile。假设它编译时没有错误,请在表单视图中打开frm_selectDesigner
表单来测试sub。如果它不编译,您可能需要为DAO或ACEDAO添加引用。
Option Compare Database
Option Explicit
Public Sub test_OpenRecordset()
Dim dbs As DAO.Database
Dim rst_projects As DAO.Recordset
Set dbs = CurrentDb
Set rst_projects = dbs.OpenRecordset("qryDesignerProjectPrioritySet", dbOpenDynaset)
rst_projects.Close
Set rst_projects = Nothing
Set dbs = Nothing
End Sub
如果它编译并运行没有错误,请将该代码与失败的代码进行比较,看看是否可以发现差异,例如声明和分配对象变量的方式。
如果这种努力没有导致解决方案,或者test_OpenRecordset
也会引发相同的错误,我认为建议的是HOW TO decompile and recompile。
答案 1 :(得分:0)
您可以在这样的代码中设置参数(您还必须对查询进行Dim / Set):
...
Dim prm As DAO.Parameter
Set qdef = db.QueryDefs("qryName")
'Evaluate and set the query's parameters.
For Each prm In qdef.Parameters
prm.Value = Eval(prm.Name)
Next prm
Set rs = qdef.OpenRecordset
...
答案 2 :(得分:0)
恐怕不是一个非常令人满意的答案。我使用了我的查询中的SQL代码而不是未来,而是在变量(基于表单行设置)中替换,而不是让VBA尝试读取文本字段。我的最终代码如下所示:
designerToPrioritize = Me.designerList.Column(2, Me.designerList.ListIndex + 1)
queryText = "SELECT [Project Request Log TABLE].Designer1, [Project Request Log TABLE].Priority, [Project Request Log TABLE].ProjectName, [Project Request Log TABLE].Manager, [Project Request Log TABLE].SME1, [Project Request Log TABLE].Priority, [Project Request Log TABLE].ProjectID"
queryText = queryText & vbCrLf & "FROM Designers INNER JOIN [Project Request Log TABLE] ON Designers.ID = [Project Request Log TABLE].Designer1"
queryText = queryText & vbCrLf & "WHERE ((([Project Request Log TABLE].Designer1)=" & **designerToPrioritize** & " AND (([Project Request Log TABLE].PercentComplete)<1)))"
queryText = queryText & vbCrLf & "ORDER BY [Project Request Log TABLE].Designer1, [Project Request Log TABLE].Priority;"
'That should recreate my original query. Let's see how it works.
Set rst_projects = dbs.OpenRecordset(queryText, dbOpenDynaset)
这很好用,所以我不会再费心去弄清楚其他方法了。如果没有人在接下来的几天内发表一个精彩的答案,我会标记这个问题的答案。感谢大家帮忙解决这个问题。
答案 3 :(得分:0)
我设法通过将查询条件放入代码中来禁用运行时错误“3061”。 Query1的SQL就像:
SELECT * FROM tbl1 WHERE field1=[Forms]![form1]![txt1]
代码:
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("Query1")
触发运行时错误'3061'。我将query2写成:
SELECT * FROM tbl1
并将代码更改为:
dim txt1 as string
txt1=[Forms]![form1]![txt1]"
Set dbs = CurrentDb
Set rst = dbs.OpenRecordset("SELECT * FROM Query2 WHERE field1=" & txt1)
它工作正常。