一段时间以来,我试图在打开某些报告的打印预览时解决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
答案 0 :(得分:2)
我想知道是否有一些常用的方法用于 为了避免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中这样做)。不过,这项技术可以根据需要使用And
或Or
运算符将表达式简化为简单的掩码。
答案 1 :(得分:1)
当您基于同一值有多个Select Case Statements
时,请考虑使用If Statement
。
根据表达式的值执行几组语句之一。
For Each c In Me.Controls
Select Case c.Tag
Case "IDSpec2Table", "IDSpec1Table", "IDSpec1TableExtra"
c.Height = 0
c.Visible = False
Case "IDSpec2Texts", "IDSpec1Texts"
c.Visible = True
c.Height = 330
Case "IDSpec1TextsExtra"
If ModuleTarget.TargetGroup <> "23C" Then
c.Visible = True
c.Height = 330
End If
End Select
Next
我在评论中提到,使用Select Case
的可读性远胜于性能。如果我们比较Select Case
和If ElseIf
语句(读Which way is faster? If elseif or select case),这是正确的。
Select Case
和If ElseIf
可能比多个If
语句要快得多。这是因为VBA会评估If
语句中的每个条件,并且会在Select Case
语句中满足一个条件时停止评估。注意:并非所有语言都可以。
考虑这个简单的测试。
Sub Test()
Debug.Print "Test:If Statement Test:"
If ret(1) = 1 Or ret(2) = 2 Or ret(3) = 3 Or ret(4) = 4 Or ret(5) = 5 Then
End If
Debug.Print vbNewLine; "Test:If ElseIf Statement"
If ret(1) = 1 Or ret(2) = 2 Then
ElseIf ret(3) = 3 Then
ElseIf ret(4) = 4 Then
ElseIf ret(5) = 5 Then
End If
Debug.Print vbNewLine; "Test:Select Case Statement"
Select Case 1
Case ret(1), ret(2)
Case ret(3)
Case ret(4)
Case ret(5)
End Select
End Sub
Function ret(n As Long) As Long
ret = n
Debug.Print n,
End Function
请注意,If
语句必须执行5个操作,即使它们都是正确的。 ElseIf
必须执行2个操作,因为前2个操作被分组在单个If
子句中。 Select Case
仅执行了一个操作,即使两个操作被分组在一起。这是因为Select Case
会在单个条件为true时始终停止评估条件。