我怎样才能把这个宏写成几行。我想摆脱这多行

How can I write this Macro into few lines. I want to get rid of this multiple lines

  Sub Flow_Drop() 

   If  ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 1").Value = xlOn 
       And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 5").Value = xlOn 
       And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 6").Value = xlOn 
       And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 7").Value = xlOn 
       And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 8").Value = xlOn 
       And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 9").Value = xlOn Then
       ThisWorkbook.Worksheets(1).Range("B21").Value = "Flow drop"

       Else
        If ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 1").Value = xlOn 
        And ThisWorkbook.Worksheets(1).Range("B24").Value = "Speed" 
        And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 6").Value = xlOn 
        And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 7").Value = xlOn
        And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 8").Value = xlOn 
        And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 9").Value = xlOn Then
        ThisWorkbook.Worksheets(1).Range("B21").Value = "Flow drop"

         Else
           If ThisWorkbook.Worksheets(1).Range("B26").Value = "Flow(from fill level)" 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 5").Value = xlOn 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 6").Value = xlOn 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 7").Value = xlOn 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 8").Value = xlOn 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 9").Value = xlOn Then
           ThisWorkbook.Worksheets(1).Range("B21").Value = "Flow drop"

           Else
           If ThisWorkbook.Worksheets(1).Range("B26").Value = "Flow(from fill level)" 
           And ThisWorkbook.Worksheets(1).Range("B24").Value = "Speed" 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 6").Value = xlOn 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 7").Value = xlOn 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 8").Value = xlOn 
           And ThisWorkbook.Worksheets(2).CHECKBOXES("Check Box 9").Value = xlOn Then
           ThisWorkbook.Worksheets(1).Range("B21").Value = "Flow drop"

              Else
               ThisWorkbook.Worksheets(1).Range("B21").Value = vbNullString

              End If
          End If
         End If
      End If
    End Sub

此代码在两个 sheet sheet 2 中生成,包含多个复选框,当复选框位于 sheet 1 中的变量上时,会自动出现。我想把这么长的代码变成几行代码

你可以这样整理一下:

Sub Flow_Drop()
    Dim s1 As Worksheet, s2 As Worksheet
    Dim check1 As Boolean, check5 As Boolean, check6789 As Boolean, flow As Boolean, speed As Boolean
    
    Set s1 = ThisWorkbook.Worksheets(1)
    Set s2 = ThisWorkbook.Worksheets(2)
    
    check1 = s2.CheckBoxes("Check Box 1").Value = xlOn
    check5 = s2.CheckBoxes("Check Box 5").Value = xlOn
    check6789 = s2.CheckBoxes("Check Box 6").Value = xlOn _
           And s2.CheckBoxes("Check Box 7").Value = xlOn _
           And s2.CheckBoxes("Check Box 8").Value = xlOn _
           And s2.CheckBoxes("Check Box 9").Value = xlOn
    flow = s1.Range("B26").Value = "Flow(from fill level)"
    speed = s1.Range("B24").Value = "Speed"

    If check6789 And _
        ((check1 And check5) Or _
        (check1 And speed) Or _
        (flow And check5) Or _
        (flow And speed)) Then
            s1.Range("B21").Value = "Flow drop"
            s1.Range("B22").Value = "Fill level dropped"
    Else
        s1.Range("B21").Value = vbNullString
    End If
    
End Sub

有多个方面需要改进。 将 Worksheets(1)Worksheets(2) 保存为变量意味着您可以在代码中使用更短的名称来引用它们。

    Dim WS1 As Worksheet
    Set WS1 = ThisWorkbook.Worksheets(1)

    Dim WS2 As Worksheet
    Set WS2 = ThisWorkbook.Worksheets(2)

每个 If 语句都有复选框 6、7、8、9,因此在 If 语句之前执行此操作并将结果保存为变量将显着减少重复代码:

    Dim CB6789 As Boolean
    CB6789 = WS2.CheckBoxes("Check Box 6").Value = xlOn _
             And WS2.CheckBoxes("Check Box 7").Value = xlOn _
             And WS2.CheckBoxes("Check Box 8").Value = xlOn _
             And WS2.CheckBoxes("Check Box 9").Value = xlOn

现在,您可以只检查 CB6789.

,而不是在所有内容上都包含这 4 行

接下来我注意到你有 Else: If 而不是 ElseIf。您正在嵌套 If 语句而不是扩展第一个语句。比较以下内容:

'''''''''''''''''''
If A Then
    
Else
    If B Then
        
    Else
        If C Then
            
        Else
            If D Then
            
            End If
        End If
    End If
End If
'''''''''''''''''''''
If A Then

ElseIf B Then

ElseIf C Then

ElseIf D Then

End If
'''''''''''''''''''''

就我个人而言,我发现第二种格式更容易遵循,看起来更整洁,也更容易编辑或扩展。

最后,你的大部分结果实际上是WS1.Range("B21").Value = "Flow drop"。在大多数情况下,您的 If 语句树都会发生此操作。这些分支可以合并。例如:

'''''''''''''''''''
    If A Then
        MsgBox 1
    ElseIf B Then
        MsgBox 1
    End If
'''''''''''''''''''
    If A Or B Then
        MsgBox 1
    End If
'''''''''''''''''''

将所有这些建议放在一起:

Sub Flow_Drop()
    Dim WS1 As Worksheet
    Set WS1 = ThisWorkbook.Worksheets(1)

    Dim WS2 As Worksheet
    Set WS2 = ThisWorkbook.Worksheets(2)
    
    Dim CB6789 As Boolean
    CB6789 = WS2.CheckBoxes("Check Box 6").Value = xlOn _
             And WS2.CheckBoxes("Check Box 7").Value = xlOn _
             And WS2.CheckBoxes("Check Box 8").Value = xlOn _
             And WS2.CheckBoxes("Check Box 9").Value = xlOn
    
    Dim CB1 As Boolean
    CB1 = WS2.CheckBoxes("Check Box 1").Value = xlOn

    Dim CB5 As Boolean
    CB5 = WS2.CheckBoxes("Check Box 5").Value = xlOn
    
    Dim IsSpeed As Boolean
    IsSpeed = WS1.Range("B24").Value = "Speed"
    
    Dim IsFlow As Boolean
    IsFlow = WS1.Range("B26").Value = "Flow(from fill level)"

    If CB6789 _
    And (CB1 Or IsFlow) _
    And (CB5 Or IsSpeed) _
    Then
        WS1.Range("B21").Value = "Flow drop"
        
    Else
        WS1.Range("B21").Value = vbNullString
    End If
End Sub

或者,由于问题是关于减少行数:

Sub Flow_Drop()
    ThisWorkbook.Worksheets(1).Range("B21").Value = IIf(ThisWorkbook.Worksheets(2).CheckBoxes("Check Box 6").Value = xlOn And ThisWorkbook.Worksheets(2).CheckBoxes("Check Box 7").Value = xlOn And ThisWorkbook.Worksheets(2).CheckBoxes("Check Box 8").Value = xlOn And ThisWorkbook.Worksheets(2).CheckBoxes("Check Box 9").Value = xlOn And (ThisWorkbook.Worksheets(2).CheckBoxes("Check Box 1").Value = xlOn Or ThisWorkbook.Worksheets(1).Range("B26").Value = "Flow(from fill level)") And (ThisWorkbook.Worksheets(2).CheckBoxes("Check Box 5").Value = xlOn Or ThisWorkbook.Worksheets(1).Range("B24").Value = "Speed"), "Flow drop", vbNullString)
End Sub

简化版

Sub Flow_Drop()
Dim bolFD as Boolean 'boolean representing whether B21 should be 'Flow Drop' or not
Dim sht1 as Worksheet, sht2 as Worksheet

bolFD = True
With ThisWorkbook
   Set sht1 = .Worksheets(1): Set sht2 = .Worksheets(2)
   For a = 6 To 9 'the checkboxes first
       bolFD = sht2.CHECKBOXES("Check Box " & a).Value = xlOn
       If Not bolfd Then Exit For
   Next
   
   If Not _
        (sht1.CHECKBOXES("Check Box 1").Value = xlOn Or sht1.Range("B26").Value = "Flow(from fill level)") _
    Or Not _
        (sht2.CHECKBOXES("Check Box 5").Value = xlOn Or sht1.Range("B24").Value = "Speed" ) _
    Then bolFD = False

    If bolFD Then 
        sht1.Range("B21").Value = "Flow drop"
    Else
        sht1.Range("B21").Value = vbNullString
    End If
End With

End Sub

首先,第 6、7、8、9 项有很多重复检查。所有这些都必须是 xlOn,所以我们可以 short-circuit 这里的例程,如果不正确就退出。

那么我们说:

a = 复选框 (1) 已打开

b = 复选框 (5) 已打开

c = 范围(“B24”)是“速度”

d = Range("B26") 是"Flow(fill from level)"

在布尔代数表示法中,输出范围将设置为“流量下降”,如果

(a * b) + (a * c) + (d * b) + (d * c) 为真

= a * (b + c) + d * (b + c)

= (a + d) * (b + c)

为复选框放入一个函数助手会产生这个:

Private Function isOn(nBox As Integer) As Boolean
    isOn = ThisWorkbook.Worksheets(2).CheckBoxes("Check Box " & nBox).Value = xlOn
End Function

Sub flow_drop()
    Dim ws as Worksheet, rngOut As Range
    Set ws = ThisWorkbook.Worksheets(1)
    Set rngOut = ws.Range("B21")

    rngOut.Value = vbNullString

    If Not (isOn(6) And isOn(7) And isOn(8) And isOn(9)) Then Exit Sub
   
    Dim c,d
    c = ws.Range("B24").Value = "Speed"
    d = ws.Range("B26").Value = "Flow(from fill level)"
    
    If (isOn(1) Or d) And (isOn(5) Or c) Then rngOut.Value = "Flow drop"
End Sub