Access 2003 VBA:查询在直接运行时有效,但从代码运行时运行时错误3061?

时间:2013-04-26 14:55:32

标签: sql vba ms-access access-vba ms-access-2003

所以我有一个相对简单的查询,它只有两个参数,其中一个从表单中拉出一个长整数,只从一个表中选择记录,其中一个字段具有该值。 (这是一个设计项目表,用户正在选择应列出项目的设计师。)

如果我打开表单然后手动打开查询,则完美。如果我有第二个表单(用查询结果填充列表框)尝试设置一个等于查询结果的记录集,它会失败并显示“运行时错误'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命令的方式肯定存在某种错误,对吗?

4 个答案:

答案 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)

它工作正常。