我怎样才能把这个宏写成几行。我想摆脱这多行
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
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
.
接下来我注意到你有 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