VBA字典作为类的属性

huangapple go评论61阅读模式
英文:

VBA dictionary as a property of a class

问题

我有这个名为clsWarehouseSum的简化类。

Option Compare Database
Option Explicit

Private wh_units As Scripting.Dictionary    

Public Function availableUnits(warehouse As String) As Long
    'Debug.Print wh_units(warehouse)
    If wh_units Is Nothing Then Set wh_units = New Scripting.Dictionary
    
    If Not wh_units.Exists(warehouse) Then
    
        Dim SQL As String
        Dim RS As DAO.Recordset
        SQL = "SELECT sum(units) as tot_units " _
            & "FROM warehouse " _
            & "WHERE warehouse = '" & warehouse & "' " 
        
        Set RS = CurrentDb.OpenRecordset(SQL)
       
        wh_units.Add warehouse, RS("tot_units")
        
    End If
    
    availableUnits = wh_units(warehouse)
    
End Function

我尝试像这样使用它:

Sub test()

Dim wh As New clsWarehouseSum    
Debug.Print wh.availableUnits("Cohasset")
Debug.Print wh.availableUnits("Cohasset")

End Sub

在第一个Debug.Print输出预期值,但第二个输出会导致错误:Run time error 3420, Object Invalid or no longer set. 当我逐步执行代码时,它正确地将两个if语句评估为false。然而,函数的最后一行给出了上述错误。我做错了什么?为什么?

英文:

I have this simplified class named clsWarehouseSum.

Option Compare Database
Option Explicit

Private wh_units As Scripting.Dictionary    

Public Function availableUnits(warehouse As String) As Long
    'Debug.Print wh_units(warehouse)
    If wh_units Is Nothing Then Set wh_units = New Scripting.Dictionary
    
    If Not wh_units.Exists(warehouse) Then
    
        Dim SQL As String
        Dim RS As DAO.Recordset
        SQL = "SELECT sum(units) as tot_units " _
            & "FROM warehouse " _
            & "WHERE warehouse = '" & warehouse & "' "   
    
        Set RS = CurrentDb.OpenRecordset(SQL)
       
        wh_units.Add (warehouse), RS("tot_units")
        
    End If
    
    availableUnits = wh_units(warehouse)
    
    

End Function

I try to use it like this:

Sub test()

Dim wh As New clsWarehouseSum    
Debug.Print wh.availableUnits("Cohasset")
Debug.Print wh.availableUnits("Cohasset")

End Sub

While the first Debug.Print prints what's expected, the second one gives me an error:
Run time error 3420, Object Invalid or no longer set. When I step through the code, it correctly evaluates both if statements as false. Yet, the last line of the function gives me the error mentioned above. What am I doing wrong?
Why?

答案1

得分: 2

availableUnits = wh_units(warehouse) 行之前添加Debug.Print TypeName(wh_units(warehouse)),如果它在Immediate窗口中打印出除了Long之外的任何内容,那么你可能需要使用CLng进行强制类型转换,同时确保你有一些错误处理程序。

或者,你可能需要确保wh_units.Add (warehouse), RS("tot_units") 这一行将Long添加到你的字典中,因此在添加之前应该检查类型。

作为一般规则,当你从字典或集合中返回特定的数据类型时,你应该始终在将数据添加到字典/集合或返回数据时进行检查,以避免类型不兼容和运行时错误。

英文:

Add Debug.Print TypeName(wh_units(warehouse)) before the availableUnits = wh_units(warehouse) line and if it prints anything else than Long to the Immediate window then you might want to cast to Long using CLng while you also have some error handler in place.

Or, you might want to make sure that the line wh_units.Add (warehouse), RS("tot_units") is adding a Long to your dictionary so you should check the type before you add.

As a general rule, when you return a specific data type from a dictionary or collection, you should always have checks in place either when you add the data to the dict/coll or when you return it so that you avoid type incompatibility and runtime errors.

huangapple
  • 本文由 发表于 2023年1月9日 19:19:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056530.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定