为啥我的脚本字典函数在 access vba 中只返回键?
Posted
技术标签:
【中文标题】为啥我的脚本字典函数在 access vba 中只返回键?【英文标题】:Why does my scripting dictionary function in access vba only return keys?为什么我的脚本字典函数在 access vba 中只返回键? 【发布时间】:2019-07-22 20:09:59 【问题描述】:我有一个 Access 2016 函数,该函数根据历史值数据库检查脚本字典的值,并返回不属于计算的错误范围内的键/项对的字典。但是,该函数仅返回键,并且对该项目的调用会导致运行时错误 3420 - 对象无效或不再设置。
我在函数末尾调试字典,它打印正常,但是当函数返回时,它会出错。
这是对该函数的简化调用:
sub Verify(index as long, frm as form)
dim badComps as object
dim comp as variant
Set badComps = Check_History(INDEX, custID, Station)
For Each comp In badComps.Items
Debug.Print "'" & comp & "'"
Next
End Sub
这是函数本身:(编辑:该函数有效,所以我对其进行了简化。最后的调试语句打印了我需要返回到验证子的所有内容)
Function Check_History(INDEX As Long, ByVal frmCust As String, ByVal frmStat As String) As Scripting.dictionary
Dim avgs As Object, mPercents As Object, dict As Object
Dim rst As DAO.Recordset, rst2 As DAO.Recordset
Dim db As DAO.Database
Dim compName As Variant, badKeys As Variant
Dim i As Long
Set db = CurrentDb
Set mPercents = CreateObject("Scripting.Dictionary")
Set dict = CreateObject("Scripting.Dictionary")
'pull history for the passed station
Set rst = db.OpenRecordset("SELECT * FROM [tblCalculated_Values] WHERE [INDEX] = " & INDEX)
rst.MoveLast
'pull history for the passed station.
Set rst2 = db.OpenRecordset("SELECT * FROM [Sample History] WHERE [INDEX] = '" & frmCust & frmStat & "'")
If rst2.RecordCount = 0 Then GoTo nohist
rst2.MoveLast
rst2.MoveFirst
'calculate the average historical value for each component
For i = 0 To rst2.RecordCount - 1
For Each compName In mults.keys
If avgs.Exists(compName) Then
avgs.Item(compName) = avgs.Item(compName) + rst2.fields(compName)
Else
avgs.Add compName, rst2.fields(compName)
End If
Next
rst2.MoveNext
Next
rst2.MoveFirst
For Each compName In mults.keys
If avgs.Exists(compName) Then
If IsNull(avgs.Item(compName)) Then avgs.Item(compName) = 0
avgs.Item(compName) = avgs.Item(compName) / rst2.RecordCount
End If
Next
'If sample falls outside the range of avg +- 1, add error to dictionary
If mPercents.Item(compName) > 0 And avgs.Item(compName) > 0 Then
If mPercents.Item(compName) < WorksheetFunction.Max(0.001, Round(avgs.Item(compName) - 1, 3)) Or _
mPercents.Item(compName) > Round(avgs.Item(compName) + 1, 3) Then dict.Add compName, mPercents.Item(compName)
If dict.Exists(compName) Then Debug.Print compName, dict.Item(compName)
End If
Next
badKeys = dict.keys
'if no errors, add key = "clean" & item = 0, else return dictionary of component, avg value
If UBound(badKeys) = -1 Then dict.Add "clean", 0
Set Check_History = dict
nohist:
End Function
任何帮助/见解/提示都会让我的一天变得更加美好。蒂亚!
【问题讨论】:
“它出错了”具体是什么意思?另外,如果引用了Scripting
库,为什么要声明您的字典As Object
并用= CreateObject("Scripting.Dictionary")
而不是= New Scripting.Dictionary
分配它们?让你的生活更轻松,不要针对早期绑定的引用编写后期绑定的代码......
您在check_History
的哪个位置为返回的字典dict
提供任何值(除了单行If UBound(badKeys) = -1 Then dict.Add "clean", 0
?请提供minimal reproducible example,强调“最小”。
另外nohist
标签也没有分配返回引用,所以badcomps
很可能是Nothing
- 在这种情况下,Verify
中会出现错误 91。
在函数中创建字典不是问题。最后一个 For 循环中的调试语句为我提供了函数应该传递的所有数据。但是,当我回到验证子时,For...Each 循环会抛出帖子开头提到的错误 3420。
在您发布的代码中您在dict
中没有设置任何键。请查看您发布的代码。
【参考方案1】:
忽略您发布的代码的其他问题,这个:
avgs.Add compName, rst2.fields(compName)
有点模棱两可:你的意思是添加 Field 对象本身,还是字段的 Value ?
看起来你打算做后者,但实际上你正在做前者。因此,当您的字典从函数返回时,它可能包含对您(现已关闭)记录集的引用。
您的Debug.Print
输出可能没问题,因为会调用默认的Value
属性来创建Print
输出
avgs.Add compName, rst2.fields(compName).Value
应该解决这个问题。
【讨论】:
以上是关于为啥我的脚本字典函数在 access vba 中只返回键?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 Access VBA 在 Excel 中添加小计在一个数据库中工作,但在另一个数据库中出现错误 1004?
使用拼写检查时使用 VBA 切换字典 (MS Access)
为啥在 Access 中返回 835 条记录的查询会在 VBA 代码中返回一个空记录集?