2

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

如果我打开表单,然后手动打开查询,它就可以完美运行。如果我有第二个表单(用查询结果填充列表框)尝试设置一个等于查询结果的记录集,它会失败并显示“运行时错误'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没有关闭,点击OK时隐藏,但保持打开状态。

编辑2:如果我包括该行

DoCmd.OpenQuery "qryDesignerProjectPrioritySet"

查询打开并具有正确的结果。如果下一行尝试将该查询的结果分配为如上所述的记录集,它会给出 3601 错误?我编写 OpenRecordset 命令的方式一定有某种错误,对吧?

4

4 回答 4

1

OpenRecordset() 应该是一个简单的基本操作;我不明白为什么它在DoCmd.OpenQuery "qryDesignerProjectPrioritySet"工作时会失败。看看只够尝试的最小程序会发生什么OpenRecordset()

插入以下代码作为新的标准模块,然后从 VB 编辑器的主菜单运行 Debug->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也引发相同的错误,我能想到的建议就是如何反编译和重新编译

于 2013-04-26T18:42:52.917 回答
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)

这很好用,所以我不会再花更多精力去找出另一种方法来做到这一点。如果在接下来的几天内没有人发布出色的答案,我会将此问题标记为已回答。感谢大家帮助解决这个问题。

于 2013-04-29T14:47:54.570 回答
0

您可以像这样在代码中设置参数(您也必须调暗/设置查询):

...
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
...
于 2013-04-26T16:56:55.070 回答
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)

它工作得很好。

于 2015-10-19T17:49:57.013 回答