错误处理多个类属性

OndřejJanča

我有一个将数据保存在单独属性中的类(我选择此设计而不是数组或scripting.dictionary,因为我将使用这些数据来构建决策树,并且在构建时要使用IntelliType。 )。

数据是从Excel电子表格中以浮点数形式加载的,因此我将它们存储在长数据类型中,但是有时会发生这种情况,以至于丢失了一个值,并用“ NA”字符串替换了该值。

我想创建一个错误处理例程,如果遇到非数字值,则将其内容替换为值-1。

我知道我可以通过使用IsNumeric()进行检查或进行错误处理来做到这一点,但是我不知道如何使该方法适用于该类拥有的许多属性中的每一个,而且我真的不喜欢写一个a的解决方案。每个错误处理代码都有一个特定的错误处理代码(将每个错误存储在一个单独的属性中也不是一件很优雅的事情,但是我发现这是我愿意为在决策树中使用较短的语法而付出的代价)。

是否有一种方法可以通过独立于变量名称的错误处理代码将值传递给刚刚遇到类型不匹配错误的变量?

一个简单的示例,其中包含以下几个属性:

Option Explicit
Dim B_LYM           As Long
Dim B_mem           As Long
Dim B_CXCR3         As Long
Dim B_CXCR4_MFI     As Long

Public Sub SetData(data as Range)
    On Error Goto err_handler

    B_LYM = data.Cells(1, 1)
    B_mem = data.Cells(1, 2)
    B_CXCR3 = data.Cells(1, 3)
    B_CXCR4_MFI = data.Cells(1, 4)

err_handler:
    'I need something like this:
    'if valuebeingstored = "NA" then targetvariable = -1
End Sub

可能还有其他更好的方法,我很乐于接受选项,我只想强调一点,我真的很想在构造决策树时使用IntelliType。我当时正在考虑使用scripting.dictionary,但是语法会很快使代码膨胀。

罗宾·麦肯齐

您说您有一个Class,因此可以包括检查输入并在类内返回-1的函数,并使用GetLet属性调用该函数。

这是一个示例类(名为clsDataStuff),说明了这一点:

Option Explicit

Private c_B_LYM As Double
Private c_B_mem As Double
Private c_B_CXCR3 As Double
Private c_B_CXCR4_MFI As Double

Public Property Let B_LYM(varValue As Variant)
    c_B_LYM = ParseDouble(varValue)
End Property
Public Property Get B_LYM()
    B_LYM = c_B_LYM
End Property

Public Property Let B_mem(varValue As Variant)
    c_B_mem = ParseDouble(varValue)
End Property
Public Property Get B_mem()
    B_mem = c_B_mem
End Property

Public Property Let B_CXCR3(varValue As Variant)
    c_B_CXCR3 = ParseDouble(varValue)
End Property
Public Property Get B_CXCR3()
    B_CXCR3 = c_B_CXCR3
End Property

Public Property Let B_CXCR4_MFI(varValue As Variant)
    c_B_CXCR4_MFI = ParseDouble(varValue)
End Property
Public Property Get B_CXCR4_MFI()
    B_CXCR4_MFI = c_B_CXCR4_MFI
End Property

Private Function ParseDouble(varValue As Variant) As Double
    If IsNumeric(varValue) Then
        ParseDouble = CDbl(varValue)
    Else
        ParseDouble = -1
    End If
End Function

注意:

  • Let属性需要一个,Variant因为您说您的输入可以是数字或字符串
  • Get属性返回Double您所说的输入为浮点数,因此DoubleLong
  • ParseDouble函数仅检查数字输入,否则返回-1

然后,在您的模块代码中:

Option Explicit

Dim B_LYM           As Long
Dim B_mem           As Long
Dim B_CXCR3         As Long
Dim B_CXCR4_MFI     As Long

Public Sub Test()

    Dim objDataStuff As clsDataStuff
    
    Set objDataStuff = New clsDataStuff
    
    objDataStuff.B_LYM = 1 'data.Cells(1, 1)
    objDataStuff.B_mem = 2 'data.Cells(1, 2)
    objDataStuff.B_CXCR3 = "a" 'data.Cells(1, 3)
    objDataStuff.B_CXCR4_MFI = True 'data.Cells(1, 4)

    Debug.Print objDataStuff.B_LYM
    Debug.Print objDataStuff.B_mem
    Debug.Print objDataStuff.B_CXCR3
    Debug.Print objDataStuff.B_CXCR4_MFI

End Sub

返回以下内容的输出:

 1 
 2 
-1 
-1 

Intellisense可用,您可以验证输入:

在此处输入图片说明

编辑-关于动态设置目标变量的注释。

您的课程可以是:

Option Explicit

Public B_LYM As Double
Public B_mem As Double
Public B_CXCR3 As Double
Public B_CXCR4_MFI As Double

Public Sub SetVar(ByVal strVarName As String, ByVal varValue As Variant)
    Dim dblValue As Double
    Dim strToEval As String
    
    If Not MemberExists(strVarName) Then Exit Sub
    
    dblValue = ParseDouble(varValue) ' do the parse
    CallByName Me, strVarName, VbLet, dblValue ' dynamically assign the value
    
End Sub

Private Function ParseDouble(varValue As Variant) As Double
    If IsNumeric(varValue) Then
        ParseDouble = CDbl(varValue)
    Else
        ParseDouble = -1
    End If
End Function

Private Function MemberExists(strVarName) As Boolean
    Dim blnTest As Boolean
    Dim varValue As Variant
    
    On Error GoTo ErrHandler
    
    varValue = CallByName(Me, strVarName, VbGet)
    blnTest = True
    GoTo ExitFunction

ErrHandler:
    blnTest = False
ExitFunction:
    MemberExists = blnTest

End Function

在哪里:

  • 所有变量都是,Public并且您仍然会获得Intellisense,但要避免所有重复LetGet代码
  • 一个单一SetVar方法使用CallByName动态设定目标变量

两个问题:

  1. 您需要笨拙的MemberExists函数来防止SetVar尝试为不存在的成员分配值-否则会产生错误(438),但这也许是您逻辑中需要的?

  2. 您仍然可以使用例如为目标变量分配值,objDataStuff.B_CXR3 = "foo"这也会导致数字以外的任何错误。

示例代码显示了下面的问题。但是坚持使用SetVar方法会产生与上述相同的输出。

Option Explicit
 
Dim B_LYM           As Long
Dim B_mem           As Long
Dim B_CXCR3         As Long
Dim B_CXCR4_MFI     As Long

Public Sub Test()

    Dim objDataStuff As clsDataStuff
    
    Set objDataStuff = New clsDataStuff
       
    objDataStuff.SetVar "B_LYM", 1
    objDataStuff.SetVar "B_mem", 2
    objDataStuff.SetVar "B_CXCR3", -1
    objDataStuff.SetVar "B_CXCR4_MFI", True
    objDataStuff.SetVar "foobar", 999
    ' working around SetVar here generates an error
    objDataStuff.B_CXCR3 = "bad"
    
    Debug.Print objDataStuff.B_LYM
    Debug.Print objDataStuff.B_mem
    Debug.Print objDataStuff.B_CXCR3
    Debug.Print objDataStuff.B_CXCR4_MFI

End Sub

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章