Excel 对于编写这段代码来说,这种方法更好、更优雅、更高效吗

Excel 对于编写这段代码来说,这种方法更好、更优雅、更高效吗,excel,vba,Excel,Vba,我在想,因为这里的常数是细胞B5,我将它与3个不同的值进行比较,每个值给出不同的结果,有没有更聪明的方法来写这个 我问这个问题的主要原因是因为我对答案很感兴趣(我只有4天的编程经验),我想尽可能多地学习。2因为这是纸上仅有的3个变化,每次有变化时都会有闪烁,你可以看到,因为我有形状,每次有纸变化时都会闪烁。如果我删除屏幕更新行,会有多个迷你闪烁,老实说,我无法决定哪一个最不分散注意力 编辑:我已经添加了我修改过的代码,非常感谢@jamheadart@dwirony它看起来好多了,运行起来也很流畅

我在想,因为这里的常数是细胞B5,我将它与3个不同的值进行比较,每个值给出不同的结果,有没有更聪明的方法来写这个

我问这个问题的主要原因是因为我对答案很感兴趣(我只有4天的编程经验),我想尽可能多地学习。2因为这是纸上仅有的3个变化,每次有变化时都会有闪烁,你可以看到,因为我有形状,每次有纸变化时都会闪烁。如果我删除屏幕更新行,会有多个迷你闪烁,老实说,我无法决定哪一个最不分散注意力

编辑:我已经添加了我修改过的代码,非常感谢@jamheadart@dwirony它看起来好多了,运行起来也很流畅,除了添加和删除列时,它仍然闪烁,我删除了这一点,让它只是更改边框,它没有闪烁,所以这肯定是隐藏和取消隐藏的问题。有人有什么想法吗?我开始相信这很正常
Private子工作表\u更改(ByVal目标作为范围)
如果目标地址为“$B$3”,则退出Sub
Application.ScreenUpdating=False
Application.Calculation=xlCalculationManual
Application.EnableEvents=False
呼叫解锁单
选择案例表(“日历”).范围(“B5”).值
案件“小时”
范围(“AV2:AV8”)。边框(xlEdgeRight)。线型=xlLineStyleNone
范围(“AV3:AV8”)。边框(xlEdgeRight)。线型=xlDashDotDot
范围(“AU:AW”).entireclumn.Hidden=False
案件“天”
范围(“AV2:AV8”)。边框(xlEdgeRight)。线型=XleContinuous
范围(“AV2:AV8”)。边框(xlEdgeRight)。重量=xlThin
范围(“AV2:AV8”)。边框(xlEdgeRight)。颜色索引=1
范围(“AU:AV”).entireclumn.Hidden=False
范围(“AW:AW”).entireclumn.Hidden=True
案例“周”
范围(“AU:AW”).entireclumn.Hidden=True
其他情况
范围(“AU:AW”).entireclumn.Hidden=True
结束选择
呼叫锁单
Application.EnableEvents=True
Application.Calculation=xlCalculationAutomatic
Application.ScreenUpdating=True
端接头

我会用s去掉所有的
,只在
工作表(“日历”)
中使用一个,而且这里只需要1个
If/ElseIf/Else
-不需要嵌套的
If
s:

此外,您还需要
Application.EnableEvents=False
来防止递归-如果您的工作表发生更改,它将不断反复触发事件

Private Sub Worksheet_Change(ByVal Target As Range)

    If Target.Address <> "$B$5" Then Exit Sub

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Call UnlockSheet

    With Worksheets("Calendar")

        If .Range("B5") = "Hours" Then

            .Range("AU:AW").EntireColumn.Hidden = False
            .Range("AV2:AV8").Borders(xlEdgeRight).LineStyle = xlLineStyleNone
            .Range("AV3:AV8").Borders(xlEdgeRight).LineStyle = xlDashDotDot

        ElseIf .Range("B5") = "Weeks" Then

            .Range("AU:AW").EntireColumn.Hidden = True
            .Range("AV2:AV8").Borders(xlEdgeRight).LineStyle = xlContinuous
            .Range("AV2:AV8").Borders(xlEdgeRight).Weight = xlThin
            .Range("AV2:AV8").Borders(xlEdgeRight).ColorIndex = 1

        ElseIf .Range("B5") = "Days" Then

            .Range("AU:AV").EntireColumn.Hidden = False
            .Range("AW:AW").EntireColumn.Hidden = True
            .Range("AV2:AV8").Borders(xlEdgeRight).LineStyle = xlContinuous
            .Range("AV2:AV8").Borders(xlEdgeRight).Weight = xlThin
            .Range("AV2:AV8").Borders(xlEdgeRight).ColorIndex = 1

        End If

    End With

    Call LockSheet

End Sub
Private子工作表\u更改(ByVal目标作为范围)
如果目标地址为“$B$5”,则退出Sub
Application.ScreenUpdating=False
Application.EnableEvents=False
呼叫解锁单
带工作表(“日历”)
如果.Range(“B5”)=小时,则
.Range(“AU:AW”).entireclumn.Hidden=False
.Range(“AV2:AV8”).Borders(xlEdgeRight).LineStyle=xlLineStyleNone
.Range(“AV3:AV8”).Borders(xlEdgeRight).LineStyle=xlDashDotDot
其他范围(“B5”)=则为“周”
.Range(“AU:AW”).EntireColumn.Hidden=True
.Range(“AV2:AV8”).Borders(xlEdgeRight).LineStyle=xlContinuous
.范围(“AV2:AV8”).边框(xlEdgeRight)。重量=xlThin
.Range(“AV2:AV8”).Borders(xlEdgeRight)。ColorIndex=1
其他范围(“B5”)=则为“天”
.Range(“AU:AV”).entireclumn.Hidden=False
.Range(“AW:AW”).entireclumn.Hidden=True
.Range(“AV2:AV8”).Borders(xlEdgeRight).LineStyle=xlContinuous
.范围(“AV2:AV8”).边框(xlEdgeRight)。重量=xlThin
.Range(“AV2:AV8”).Borders(xlEdgeRight)。ColorIndex=1
如果结束
以
呼叫锁单
端接头

我会用
s去掉所有的
,只在
工作表(“日历”)
中使用一个,而且这里只需要1个
If/ElseIf/Else
-不需要嵌套的
If
s:

此外,您还需要
Application.EnableEvents=False
来防止递归-如果您的工作表发生更改,它将不断反复触发事件

Private Sub Worksheet_Change(ByVal Target As Range)

    If Target.Address <> "$B$5" Then Exit Sub

    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Call UnlockSheet

    With Worksheets("Calendar")

        If .Range("B5") = "Hours" Then

            .Range("AU:AW").EntireColumn.Hidden = False
            .Range("AV2:AV8").Borders(xlEdgeRight).LineStyle = xlLineStyleNone
            .Range("AV3:AV8").Borders(xlEdgeRight).LineStyle = xlDashDotDot

        ElseIf .Range("B5") = "Weeks" Then

            .Range("AU:AW").EntireColumn.Hidden = True
            .Range("AV2:AV8").Borders(xlEdgeRight).LineStyle = xlContinuous
            .Range("AV2:AV8").Borders(xlEdgeRight).Weight = xlThin
            .Range("AV2:AV8").Borders(xlEdgeRight).ColorIndex = 1

        ElseIf .Range("B5") = "Days" Then

            .Range("AU:AV").EntireColumn.Hidden = False
            .Range("AW:AW").EntireColumn.Hidden = True
            .Range("AV2:AV8").Borders(xlEdgeRight).LineStyle = xlContinuous
            .Range("AV2:AV8").Borders(xlEdgeRight).Weight = xlThin
            .Range("AV2:AV8").Borders(xlEdgeRight).ColorIndex = 1

        End If

    End With

    Call LockSheet

End Sub
Private子工作表\u更改(ByVal目标作为范围)
如果目标地址为“$B$5”,则退出Sub
Application.ScreenUpdating=False
Application.EnableEvents=False
呼叫解锁单
带工作表(“日历”)
如果.Range(“B5”)=小时,则
.Range(“AU:AW”).entireclumn.Hidden=False
.Range(“AV2:AV8”).Borders(xlEdgeRight).LineStyle=xlLineStyleNone
.Range(“AV3:AV8”).Borders(xlEdgeRight).LineStyle=xlDashDotDot
其他范围(“B5”)=则为“周”
.Range(“AU:AW”).EntireColumn.Hidden=True
.Range(“AV2:AV8”).Borders(xlEdgeRight).LineStyle=xlContinuous
.范围(“AV2:AV8”).边框(xlEdgeRight)。重量=xlThin
.Range(“AV2:AV8”).Borders(xlEdgeRight)。ColorIndex=1
其他范围(“B5”)=则为“天”
.Range(“AU:AV”).entireclumn.Hidden=False
.Range(“AW:AW”).entireclumn.Hidden=True
.Range(“AV2:AV8”).Borders(xlEdgeRight).LineStyle=xlContinuous
.范围(“AV2:AV8”).边框(xlEdgeRight)。重量=xlThin
.Range(“AV2:AV8”).Borders(xlEdgeRight)。ColorIndex=1
如果结束
以
呼叫锁单
端接头

您可以使用
elseif
将if-else语句组合在一起,使其更简洁:

Sub example1()
    If Sheets("Calendar").Range("B5").Value = "Hours" Then
        'do something
    ElseIf Sheets("Calendar").Range("B5").Value = "Days" Then
        'do something else
    ElseIf Sheets("Calendar").Range("B5").Value = "Weeks" Then
        'do a third thing
    Else
        'do something if range("B5") isn't any of those values
    End If
End Sub
但实际上,您可以用一个
select case
station来代替它,这样您就只需要引用
B5
一次:

Sub example2()
Select Case Sheets("Calendar").Range("B5").Value
    Case "Hours"
        'do something
    Case "Days"
        'do something else
    Case "Weeks"
        'do a third thing
    Case Else
        'do something if range("B5") isn't any of those values
End Select
End Sub
但你的闪烁问题实际上是另一回事。这是因为您正在对工作表进行更改,从而触发对工作表的更改

这是一个循环引用的事情。我认为当工作表上有您的自动更改时,您需要禁用工作表更改事件,然后
Sub example2()
Select Case Sheets("Calendar").Range("B5").Value
    Case "Hours"
        'do something
    Case "Days"
        'do something else
    Case "Weeks"
        'do a third thing
    Case Else
        'do something if range("B5") isn't any of those values
End Select
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Select Case Target.Address(False, False)
    Case "B5"
        ' call the routine with all your if-else and change logic here
    Case "Z55"
        ' do other things
End Select
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    Call UnlockSheet


    With Worksheets("Calendar")
        If Not Intersect(Target, .Range("B3")) Is Nothing Then 'Only run if B5 is changed otherwise skip.
            .Range("AU:AW").EntireColumn.Hidden = False
            .Range("AU:AW").EntireColumn.Hidden = .Range("B5") = "Weeks"
            .Range("AW:AW").EntireColumn.Hidden = .Range("B5") = "Days"
            With .Range("AV2:AV8")
                .Borders(xlEdgeRight).LineStyle = xlLineStyleNone
                If .Range("B5") = "Hours" Then
                    .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count).Borders(xlEdgeRight).LineStyle = xlDashDotDot
                Else
                    With .Borders(xlEdgeRight)
                        .LineStyle = xlContinuous
                        .Weight = xlThin
                        .ColorIndex = 1
                    End With
                End If
            End With
        End If
    End With


    Call LockSheet
    Application.EnableEvents = True
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True

End Sub