MS Access 2013 从 VBA 调用带有奇怪错误的插入查询
MS Access 2013 calling insert queries from VBA with strange errors
我有一个已保存的插入查询,用于将记录添加到 table。查询的参数来自未绑定的表单。 table 的 2 个字段属于 yes/no 数据类型。这些字段的表单控件是一个复选框。
这是保存的查询"qryInsertLog"
PARAMETERS UserPar Text ( 255 ), ApprovedByPar Text ( 255 ), CCedByPar Text ( 255 ),
UnitIdPar Short, NotePar LongText, Z3Par Bit, Z5Par Bit, FollowupNotesPar LongText;
INSERT INTO tblLogBook ( [User], ApprovedBy, CCedBy, UnitID, Notes, Z3, Z5, FollowupNotes )
SELECT [UserPAR] AS Expr1, [ApprovedByPar] AS Expr2, [CCedByPar] AS Expr3,
[UnitIDPar] AS Expr4, [NotePar] AS Expr5, [Z3Par] AS Expr6, [Z5Par] AS Expr7,
[FollowupNotesPar] AS Expr10;
这是我的 VBA 代码绑定到我的表单上的保存按钮:
Private Sub cmdSaveandNew_Click()
Dim db As DAO.Database
Dim qdf1 As DAO.QueryDef
Set db = CurrentDb
Set qdf1 = db.QueryDefs("qryInsertLog")
'put form parameters into insert query
qdf1.Parameters(0).Value = Me.cboUser.Value
qdf1.Parameters(1).Value = Me.cboApprover.Value
qdf1.Parameters(2).Value = Me.cboCCer.Value
qdf1.Parameters(3).Value = Me.cboUnit.Value
qdf1.Parameters(4).Value = Me.txtNotes.Value
qdf1.Parameters(5).Value = Me.chkZ3.Value
qdf1.Parameters(6).Value = Me.chkz5.Value
qdf1.Parameters(7).Value = Me.txtFollowup.Value
qdf1.Execute
Set qdf1 = Nothing
Call resetForm
End Sub
"resetForm" 是一个例程,它只是 returns 表单控件为其默认值。
当我点击保存按钮时,有时会添加记录,但没有获得 Me.chkZ3.Value 和 Me.chkZ5.Value 的正确值(意思是如果我检查了它们,记录将这些值输入为 false)。点击保存按钮几次后,我开始收到以下错误:
Run-time error '3000':
Reserved error (-3033); there is no message for this error.
然而,最有趣的部分是,当我修改我的查询以仅包含 1 个 yes/no 字段时,我没有收到任何错误并且记录被正确更新。
这到底是怎么回事?
编辑:我忘了提到,当我 运行 来自访问对象 window 的查询(而不是 VBA)时,它完全按预期工作。
在将它们分配给 table 之前,您可能应该在表单字段中添加更多错误跟踪和检查 Null 值。也就是说,这一修复可能会解决您眼前的问题。
我假设您的 Z3 和 Z5 字段是位字段 - 因为这是您声明匹配参数类型的方式。
如果是这样,您可能应该捕获 Null 复选框并将 true(-1) 转换为 1
' Set to 0 if checkbox is Null, Set to 1 if checked=true
' Bit fields can't take -1 values
qdf1.Parameters(5).Value = IIf(Nz(Me.chkZ3.Value, 0), 1, 0)
qdf1.Parameters(6).Value = IIf(Nz(Me.chkz5.Value, 0), 1, 0)
作为旁注,我还建议使用命名参数而不是数字索引,以防这些参数的顺序发生变化——同时也为了可读性和将来的维护方便
而不是
qdf1.Parameters(0).Value = Me.cboUser.Value
使用
qdf1.Parameters("UserPar").Value = Me.cboUser.Value
问题出在 LongText
参数上。我尝试了类似的查询:
PARAMETERS pText1 Text ( 255 ), pInt1 Short, pMemo1 LongText, pYesno1 Bit, pYesno2 Bit;
INSERT INTO ForInsert ( text1, int1, Memo1, yesno1, yesno2 )
SELECT [pText1] AS A1, [pInt1] AS A2, [pMemo1] AS A3, [pYesno1] AS A4, [pYesno2] AS A5;
使用此代码
Set db = CurrentDb
Set qdf1 = db.QueryDefs("qAppForInsert")
qdf1.Parameters(0).Value = "asdf"
qdf1.Parameters(1).Value = 77
qdf1.Parameters(2).Value = String(3, "a")
qdf1.Parameters(3).Value = True
qdf1.Parameters(4).Value = False
qdf1.Execute
以及 LongText 参数的各种长度 (2, 10, 3) .
导致这个疯狂的数据(Yes/No 字段总是 yesno1 = True
和 yesno2 = False
!):
+----+-------+------+------------+--------+--------+
| ID | text1 | int1 | Memo1 | yesno1 | yesno2 |
+----+-------+------+------------+--------+--------+
| 8 | asdf | 77 | aa | True | False |
| 9 | asdf | 77 | aaaaaaaaaa | False | False |
| 10 | asdf | 77 | aaa | False | True |
+----+-------+------+------------+--------+--------+
显然,对于 LongText 参数,您最好使用 RecordSet.AddNew
而不是参数化查询。
反正参数是limited to 255 characters。
附录
如果我运行循环查找系统代码,我也会得到Reserved error (-3033)
.
我有一个已保存的插入查询,用于将记录添加到 table。查询的参数来自未绑定的表单。 table 的 2 个字段属于 yes/no 数据类型。这些字段的表单控件是一个复选框。
这是保存的查询"qryInsertLog"
PARAMETERS UserPar Text ( 255 ), ApprovedByPar Text ( 255 ), CCedByPar Text ( 255 ),
UnitIdPar Short, NotePar LongText, Z3Par Bit, Z5Par Bit, FollowupNotesPar LongText;
INSERT INTO tblLogBook ( [User], ApprovedBy, CCedBy, UnitID, Notes, Z3, Z5, FollowupNotes )
SELECT [UserPAR] AS Expr1, [ApprovedByPar] AS Expr2, [CCedByPar] AS Expr3,
[UnitIDPar] AS Expr4, [NotePar] AS Expr5, [Z3Par] AS Expr6, [Z5Par] AS Expr7,
[FollowupNotesPar] AS Expr10;
这是我的 VBA 代码绑定到我的表单上的保存按钮:
Private Sub cmdSaveandNew_Click()
Dim db As DAO.Database
Dim qdf1 As DAO.QueryDef
Set db = CurrentDb
Set qdf1 = db.QueryDefs("qryInsertLog")
'put form parameters into insert query
qdf1.Parameters(0).Value = Me.cboUser.Value
qdf1.Parameters(1).Value = Me.cboApprover.Value
qdf1.Parameters(2).Value = Me.cboCCer.Value
qdf1.Parameters(3).Value = Me.cboUnit.Value
qdf1.Parameters(4).Value = Me.txtNotes.Value
qdf1.Parameters(5).Value = Me.chkZ3.Value
qdf1.Parameters(6).Value = Me.chkz5.Value
qdf1.Parameters(7).Value = Me.txtFollowup.Value
qdf1.Execute
Set qdf1 = Nothing
Call resetForm
End Sub
"resetForm" 是一个例程,它只是 returns 表单控件为其默认值。
当我点击保存按钮时,有时会添加记录,但没有获得 Me.chkZ3.Value 和 Me.chkZ5.Value 的正确值(意思是如果我检查了它们,记录将这些值输入为 false)。点击保存按钮几次后,我开始收到以下错误:
Run-time error '3000':
Reserved error (-3033); there is no message for this error.
然而,最有趣的部分是,当我修改我的查询以仅包含 1 个 yes/no 字段时,我没有收到任何错误并且记录被正确更新。
这到底是怎么回事?
编辑:我忘了提到,当我 运行 来自访问对象 window 的查询(而不是 VBA)时,它完全按预期工作。
在将它们分配给 table 之前,您可能应该在表单字段中添加更多错误跟踪和检查 Null 值。也就是说,这一修复可能会解决您眼前的问题。
我假设您的 Z3 和 Z5 字段是位字段 - 因为这是您声明匹配参数类型的方式。
如果是这样,您可能应该捕获 Null 复选框并将 true(-1) 转换为 1
' Set to 0 if checkbox is Null, Set to 1 if checked=true
' Bit fields can't take -1 values
qdf1.Parameters(5).Value = IIf(Nz(Me.chkZ3.Value, 0), 1, 0)
qdf1.Parameters(6).Value = IIf(Nz(Me.chkz5.Value, 0), 1, 0)
作为旁注,我还建议使用命名参数而不是数字索引,以防这些参数的顺序发生变化——同时也为了可读性和将来的维护方便
而不是
qdf1.Parameters(0).Value = Me.cboUser.Value
使用
qdf1.Parameters("UserPar").Value = Me.cboUser.Value
问题出在 LongText
参数上。我尝试了类似的查询:
PARAMETERS pText1 Text ( 255 ), pInt1 Short, pMemo1 LongText, pYesno1 Bit, pYesno2 Bit;
INSERT INTO ForInsert ( text1, int1, Memo1, yesno1, yesno2 )
SELECT [pText1] AS A1, [pInt1] AS A2, [pMemo1] AS A3, [pYesno1] AS A4, [pYesno2] AS A5;
使用此代码
Set db = CurrentDb
Set qdf1 = db.QueryDefs("qAppForInsert")
qdf1.Parameters(0).Value = "asdf"
qdf1.Parameters(1).Value = 77
qdf1.Parameters(2).Value = String(3, "a")
qdf1.Parameters(3).Value = True
qdf1.Parameters(4).Value = False
qdf1.Execute
以及 LongText 参数的各种长度 (2, 10, 3) .
导致这个疯狂的数据(Yes/No 字段总是 yesno1 = True
和 yesno2 = False
!):
+----+-------+------+------------+--------+--------+
| ID | text1 | int1 | Memo1 | yesno1 | yesno2 |
+----+-------+------+------------+--------+--------+
| 8 | asdf | 77 | aa | True | False |
| 9 | asdf | 77 | aaaaaaaaaa | False | False |
| 10 | asdf | 77 | aaa | False | True |
+----+-------+------+------------+--------+--------+
显然,对于 LongText 参数,您最好使用 RecordSet.AddNew
而不是参数化查询。
反正参数是limited to 255 characters。
附录
如果我运行循环查找系统代码,我也会得到Reserved error (-3033)
.