记录集上的错误,但同样的SQL在其他地方工作

时间:2014-12-13 05:02:28

标签: ms-access access-vba recordset

错误:"运行时错误' 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

4 个答案:

答案 0 :(得分:2)

调整代码以使用带有QueryDef的SELECT语句,为参数提供值,然后从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是保留字。虽然这个名称之前显然没有引起任何问题,但我将其括在方括号中,因此db引擎不能将字段名称与Month函数混淆。这可能是一种不必要的预防措施,但很难准确预测保留字何时会产生问题。实际上,如果可能的话,最好完全避免它们。

答案 1 :(得分:0)

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

Dim rs As DAO.Recordset Dim db作为DAO.Database Dim strSQL As String

strSQL =“SELECT Sum(tbl_SP.AFP)AS AFP_TOTAL,tbl_SP.T1_UNIT”_        &安培; “FROM tbl_SP”_        &安培; “GROUP BY tbl_SP.T1_UNIT”_        &安培; “HAVING(((tbl_SP.T1_UNIT)='”& strUnit&“'));”

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

AFP_Total = rs!AFP_Total

答案 2 :(得分: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

答案 3 :(得分:-1)

我不建议在VBA中构建临时参数化查询,因为它使代码太复杂。而且速度慢。我更喜欢构建“纯”SQL,它将直接在db引擎中运行,而不需要对Access进行任何回调。我假设您的函数是在frmEntry表单中定义的,cmbImport_T1cmbMonth是字符串字段。如果它们是数字,请省略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