首页 > 解决方案 > 有没有办法优化嵌套的 if 子句?

问题描述

一段时间以来,我试图解决我的 Access 应用程序在打开某些报告的打印预览时速度下降的问题。我注意到慢速报告有一个共同点——长而嵌套的 if 子句。我试图在 Internet 上搜索此问题的答案,但某些解决方案不适用于 Access VBA,或者在我的应用程序中无法实现。

我想知道是否有一些众所周知的方法可以用来避免 if 子句怪物?

编辑:一段代码 - 它主要根据某些条件处理报告的结构。

If (strCcDocNumber <> vbNullString) Then
    Dim strUpperPart As String, strLowerPart As String

    IDModule.placeIDStringsToPrivateVariables strCcDocNumber, ", "
    strUpperPart = IDModule.returnUpper()
    strLowerPart = IDModule.returnLower()

    txtIDs = strUpperPart & vbCrLf & strLowerPart
Else
    txtIDs = " " & vbCrLf & " "
End If

If (strOrderNumber = IO_OrderNumber.OrderNumberCode & "12345") Then
    txtIDs = txtIDs
    txtIDSpec1 = ModuleIDSpec1.getIDSpec1
    txtIDSpec2 = ModuleIDSpec2.getIDSpec2
    txtIDSpec1.Height = 330
    txtIDSpec2.Height = 330
    txtUpperLower = "- Ex" & vbCrLf & "- Ex2" & vbCrLf & vbCrLf & "- Ex3"
    On Error Resume Next
    For Each c In Me.Controls
        If (c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1Table") Then c.Height = 0
        If (c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1Table") Then c.Visible = False
        If (c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1TableExtra") Then c.Height = 0
        If (c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1TableExtra") Then c.Visible = False
        If (c.Tag = "IDSpec2Texts" Or c.Tag = "IDSpec1Texts") Then c.Visible = True
        If (c.Tag = "IDSpec2Texts" Or c.Tag = "IDSpec1Texts") Then c.Height = 330
        If (c.Tag = "IDSpec2Texts" Or c.Tag = "IDSpec1TextsExtra" And ModuleTarget.TargetGroup <> "23C") Then c.Visible = True
        If (c.Tag = "IDSpec2Texts" Or c.Tag = "IDSpec1TextsExtra" And ModuleTarget.TargetGroup <> "23C") Then c.Height = 330
        '+ many more tags
    Next
    On Error GoTo 0
    txtIDSpec1.Visible = True
    txtIDSpec2.Visible = True
    If (txtIDSpec1 = vbNullString And txtIDSpec2 = vbNullString) Then
        txtIDSpec1.Height = 0
        txtIDSpec2.Height = 0
        txtIDSpec1.Visible = False
        txtIDSpec2.Visible = False
    End If
Else
    '+a lot more similar conditions

编辑:我记得哪些 if 语句是最麻烦的。我认为您不能将这些更改为选择案例或 ElseIf 语句,因为需要检查所有条件...

它是这样的:

If (condition) Then
Do this
   If (differentCondition) Then
       Do this also
        If (completelyDifferentCondition) Then
            Do this as well
        Else
            Do this instead
        End If
   End If
Else
   If (yetAnotherCondition) Then
        Do this
   Else
        Do this instead
   End If
End If

标签: vbams-access

解决方案


我想知道是否有一些众所周知的方法可以用来避免 if 子句怪物?

第一步是弄清楚你想要达到什么,而不是你想怎么做。在这种情况下,您要设置高度和可见性。从这里,您可以计算出设置它需要什么条件。

当你第一次这样做时,你会有一些怪物子句——但这没关系,因为你还没有澄清你的想法。除非另有证明,否则从一种状态的假设开始工作。这是一个例子:

c.visible = True
If ((c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1Table") OR (c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1TableExtra")) then c.visible = True

当然,第二行现在可以简化一点。

If (c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1Table" Or c.Tag = "IDSpec1TableExtra") then c.visible = True

我还设置了标记布尔值 - 例如:

IsSpecTable = (c.Tag = "IDSpec2Table" Or c.Tag = "IDSpec1Table")
IsMySpecialFriend = (c.Tag = "IDSpec1TextsExtra" And ModuleTarget.TargetGroup <> "23C")
[...]
c.Visible = IsSpecTable Or IsMySpecialFriend

这些是我用来简化复杂业务逻辑的几种技术。我也在研究标志的使用,但这意味着将文本转换Tag为枚举值(我在 VB.Net 中这样做)。但是,这种技术将表达式简化为一个简单的掩码,并酌情使用AndOr运算符。


推荐阅读