我有一本包含很多工作表的工作簿。
在 Sheet1 上,我有很多“部分”。
在每个“部分”中,我都有一个单元格(例如 B31),可以是“是”或“否”。
如果单元格为“是”,那么我想:
如果单元格为“否”,那么我想:
这是 Sheet1 上 30 个不同“部分”的前提。
每个部分都会评估不同单元格中的“是”或“否”值,并显示/隐藏同一张工作表中接下来的 15 行,显示/隐藏 Sheet2 行,并完全隐藏某个工作表(范围从 Sheet3 到 Sheet 30) ).
我可以使用它,但我觉得我编码得不好。
如果有人添加部分,维护将变得很困难。
有时我会黑屏几秒钟,因为它需要很长时间才能运行。
每个部分都会重复该代码。下面的代码分为三个部分。
有没有一种方法可以更好地编码以提高可重用性和性能?
Dim ScopeChange As Range
Dim Module_1 As Variant
Dim Module_2 As Variant
Dim Module_3 As Variant
Module_1 = Range("B31").Value
Module_2 = Range("B49").Value
Module_3 = Range("B67").Value
Set ScopeChange = Range("B31")
If Not ScopeChange Is Nothing Then
Application.EnableEvents = False
Select Case Module_1
Case "Yes": Rows("32:46").EntireRow.Hidden = False
Worksheets("Sheet2").Rows("19:36").EntireRow.Hidden = False
Worksheets("Sheet3").Visible = True
Case "No": Rows("32:46").EntireRow.Hidden = True
Worksheets("Sheet2").Rows("19:36").EntireRow.Hidden = True
Worksheets("Sheet3").Visible = False
End Select
Application.EnableEvents = True
End If
Set ScopeChange = Range("B49")
If Not ScopeChange Is Nothing Then
Application.EnableEvents = False
Select Case Module_2
Case "Yes": Rows("50:64").EntireRow.Hidden = False
Worksheets("Sheet2").Rows("37:54").EntireRow.Hidden = False
Worksheets("Sheet4").Visible = True
Case "No": Rows("50:64").EntireRow.Hidden = True
Worksheets("Sheet2").Rows("37:54").EntireRow.Hidden = True
Worksheets("Sheet4").Visible = False
End Select
Application.EnableEvents = True
End If
Set ScopeChange = Range("B67")
If Not ScopeChange Is Nothing Then
Application.EnableEvents = False
Select Case Module_3
Case "Yes": Rows("68:82").EntireRow.Hidden = False
Worksheets("Sheet2").Rows("55:72").EntireRow.Hidden = False
Worksheets("Sheet5").Visible = True
Case "No": Rows("68:82").EntireRow.Hidden = True
Worksheets("Sheet2").Rows("55:72").EntireRow.Hidden = True
Worksheets("Sheet5").Visible = False
End Select
Application.EnableEvents = True
End If
End Sub
无论更改的单元格数量有多少,代码始终会评估所有部分(将来 30 个或什至更多)以隐藏/取消隐藏行和工作表。这会显着增加处理时间。
更改:利用更改事件代码仅验证更改的单元格并调整相关行和工作表的可见性。
另一个优点是,如果用户添加新部分,只要该部分的布局遵循相同的模式,您就不必修改代码。
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
With Target
If .CountLarge = 1 And .Column = 2 And .Row > 30 Then
If ((.Row - 13) Mod 18 = 0) And Len(.Value) > 0 Then
Dim iIndex As Long, rngSht1 As Range, rngSht2 As Range
iIndex = (.Row - 13) / 18
Application.EnableEvents = False
Set rngSht1 = Me.Cells(iIndex * 18 + 14, 1).Resize(15).EntireRow
Set rngSht2 = Worksheets("Sheet2").Cells(iIndex * 18 + 1, 1).Resize(18).EntireRow
Select Case UCase(.Value)
Case "YES"
rngSht1.Hidden = False
rngSht2.Hidden = False
Worksheets("Sheet" & iIndex + 2).Visible = True
Case "NO"
rngSht1.Hidden = True
rngSht2.Hidden = True
Worksheets("Sheet" & iIndex + 2).Visible = False
End Select
Application.EnableEvents = True
End If
End If
End With
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Long, Hide As Boolean
With Target
If .Cells.CountLarge > 1 Then Exit Sub
If .Column <> 2 Then Exit Sub
r = .Row
If r < 31 Then Exit Sub
If r Mod 18 <> 13 Then Exit Sub
If StrComp(CStr(.Value), "Yes", vbTextCompare) <> 0 Then Hide = True
.Offset(1).EntireRow.Resize(15).Hidden = Hide
With .Worksheet.Parent
.Sheets("Sheet2").Rows(r - 12).Resize(18).Hidden = Hide
.Sheets("Sheet" & (Int(r / 18) + 2)).Visible = Not Hide
End With
End With
End Sub
常数介绍
Private Sub Worksheet_Change(ByVal Target As Range)
Const S_FIRST_ROW As Long = 31
Const S_FLAG_COLUMN As Long = 2
Const S_ROWS_COUNT As Long = 15
Const S_ROW_OFFSET As Long = 1
Const S_FLAG As String = "Yes"
Const D_SHEET_NAME As String = "Sheet2"
Const D_SHEET_LEFT As String = "Sheet"
Const D_ROWS_COUNT As Long = 18
Const D_ROW_OFFSET As Long = 13
Dim r As Long, Hide As Boolean
With Target
If .Cells.CountLarge > 1 Then Exit Sub
If .Column <> S_FLAG_COLUMN Then Exit Sub
r = .Row
If r < S_FIRST_ROW Then Exit Sub
If r Mod D_ROWS_COUNT <> D_ROW_OFFSET Then Exit Sub
If StrComp(CStr(.Value), S_FLAG, vbTextCompare) <> 0 Then Hide = True
.Offset(S_ROW_OFFSET).EntireRow.Resize(S_ROWS_COUNT).Hidden = Hide
With .Worksheet.Parent
.Sheets(D_SHEET_NAME).Rows(r - D_ROW_OFFSET + 1) _
.Resize(D_ROWS_COUNT).Hidden = Hide
.Sheets(D_SHEET_LEFT & (Int(r / D_ROWS_COUNT) + 2)) _
.Visible = Not Hide
End With
End With
End Sub