记录集出错,但相同的 SQL 在其他地方有效

问题描述 投票:0回答:5

错误:“运行时错误‘3061’参数太少。预期为 2。

我编写了这个简单的函数,它返回根据更改的记录数计算的剩余百分比。当用户更新名为“百分比”的字段时应该会发生这种情况,我确信下面的代码应该可以工作,但显然有些问题。 它发生在线路上:

Set rs = db.OpenRecordset("SELECT Tier1, [Percentage], Tier3 AS Battalion, Month " _
    & "FROM tbl_CustomPercent " _
    & "WHERE (((Tier1)=[Forms]![frmEntry]![cmbImport_T1]) AND ((Month)=[Forms]![frmEntry]![cmbMonth]));", dbOpenSnapshot)

我想知道当同一个查询使用“百分比”文本框填充表单的“记录源”时,它怎么会失败。

Function RemainingPercentAvailable() As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String


Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT Tier1, [Percentage], Tier3 AS Battalion, Month " _
& "FROM tbl_CustomPercent " _
& "WHERE (((Tier1)=[Forms]![frmEntry]![cmbImport_T1]) AND ((Month)=[Forms]![frmEntry]![cmbMonth]));", dbOpenSnapshot)

Dim CurrentTotal As Single

CurrentTotal = 0

If Not (rs.EOF And rs.BOF) Then
    rs.MoveFirst

    Do Until rs.EOF = True
        CurrentTotal = CurrentTotal + rs!Percentage
        rs.MoveNext
    Loop

End If


RemainingPercentAvailable = "Remaing available: " & Format(1 - CurrentTotal, "0.000%")

Set rs = Nothing
Set db = Nothing

End Function
ms-access vba recordset
5个回答
2
投票

调整您的代码以将

SELECT
语句与 QueryDef 一起使用,提供参数值,然后从 QueryDef 打开记录集。

Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset
Dim strSQL As String

strSQL = "SELECT Tier1, [Percentage], Tier3 AS Battalion, [Month] " _
    & "FROM tbl_CustomPercent " _
    & "WHERE (((Tier1)=[Forms]![frmEntry]![cmbImport_T1]) AND (([Month])=[Forms]![frmEntry]![cmbMonth]));"

Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strSQL )
' supply values for the 2 parameters ...
qdf.Parameters(0).Value = Eval(qdf.Parameters(0).Name)
qdf.Parameters(1).Value = Eval(qdf.Parameters(1).Name)
Set rs = qdf.OpenRecordset

注:

Month
是保留字。 尽管该名称之前显然没有引起任何问题,但我将其括在方括号中,以便数据库引擎不能将字段名称与
Month
函数混淆。 这可能是一种不必要的预防措施,但很难准确预测保留字何时会产生问题。 实际上,如果可能的话最好完全避免它们。


0
投票

这个直接在 DAO.Recordset 中调用查询,它工作得很好。
请注意相同的 'Set rs = db.OpenRecordset(strSQL, dbOpenDynaset) 这也是一个参数 SQL。 唯一的区别是,我不需要移动并分析记录集 - 但错误发生在“Set rs =”行,所以我无论如何也无法进一步了解。

将 rs 调暗为 DAO.Recordset Dim db As DAO.Database Dim strSQL 作为字符串

strSQL =“选择总和(tbl_SP.AFP)作为AFP_TOTAL,tbl_SP.T1_UNIT”_ &“来自tbl_SP”_ &“按 tbl_SP.T1_UNIT 分组”_ &“有(((tbl_SP.T1_UNIT)='”&strUnit&“'));”

设置 db = CurrentDb 设置 rs = db.OpenRecordset(strSQL, dbOpenDynaset)

AFP_Total = rs!AFP_Total


0
投票

还有一种更简单的方法来计算总百分比。

您可以使用 DSum() 函数,而不是循环遍历记录。

注意,如果没有记录,DSum 将返回 Null,因此需要将其包装在 Nz() 中。

只是为了好玩,这是你的函数,但写成一个语句:

    Function RemainingPercentAvailable() As String
    RemainingPercentAvailable = "Remaining available: " & Format(1 - _
        Nz(DSum("Percentage", _
                "tbl_CustomPercent", _
                "Tier1 = " & QString(cmbImport_T1) & _
                " AND [Month] = " & QString(cmbMonth))) _
        , "0.000%")
    End Function

0
投票

我遇到了同样的错误

3061' 参数太少。预计2。 请有人帮助我

这是vb代码

Private Sub Form_AfterUpdate()
On Error GoTo ErrorHandler

Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim calculatedSalesPercents As Double
Dim salesPercentsID As Variant

' Store the value of the SalesPercents control and calculate the result
calculatedSalesPercents = IIf([RePrice] = 0 Or [BDDUTY] = 0, 0, Round(1 - ([BDDUTY] / [RePrice]), 2))
salesPercentsID = Forms![Item Menu Suplier(03)]![SalesPercents]  ' Value from the SalesPercents textbox

' Set up the database and recordset
Set db = CurrentDb()
' Add the value from the SalesPercents textbox directly to the SQL statement
Set rs = db.OpenRecordset("SELECT * FROM ItemName WHERE ID = " & salesPercentsID, dbOpenDynaset)

' If a record is found, update it
If Not rs.EOF Then
    rs.Edit
    rs("SalesPercents") = calculatedSalesPercents
    rs.Update
End If

rs.Close
Set rs = Nothing
Set db = Nothing
Exit Sub

错误处理程序: MsgBox "Error " & Err.Number & ": " & Err.Description 结束子


-1
投票

我不建议在VBA中构建临时参数化查询,因为这会使代码过于复杂。而且速度更慢。我更喜欢构建“纯”SQL,它将直接在数据库引擎中运行,而不需要对 Access 进行任何回调。我假设您的函数是在 frmEntry 表单中定义的,并且

cmbImport_T1
cmbMonth
是字符串字段。如果它们是数字,请省略
qString()

这是我的函数版本。它正确处理空记录集的情况。

Function RemainingPercentAvailable() As String
Dim CurrentTotal As Double, q As String
q = "SELECT Percentage" & _
    " FROM tbl_CustomPercent" & _
    " WHERE Tier1 = " & QString(cmbImport_T1) & _
    " AND [Month] = " & QString(cmbMonth)
CurrentTotal = 0
With CurrentDb.OpenRecordset(q)
  While Not .EOF
    CurrentTotal = CurrentTotal + .Fields("Percentage")
    .MoveNext
  Wend
End With
RemainingPercentAvailable = "Remaining available: " & _
                            Format(1 - CurrentTotal, "0.000%")
End Function

' Return string S quoted, with quotes escaped, for building SQL.
Public Function QString(ByVal S As String) As String
   QString = "'" & Replace(S, "'", "''") & "'"
End Function
© www.soinside.com 2019 - 2024. All rights reserved.