它有一个更好的方法来执行这个If语句代码,以便它更快地工作?

时间:2018-02-08 18:22:40

标签: vba excel-vba excel

作为VBA代码的新学徒,我开发了以下代码,该代码适用于电子表格以更新Col(17)中的数据,更新Col(13)中的优先级并根据Col(14)放置字符在更新时,数据从Col(2)到Col(19)填充。它有任何可能的方法使这些代码更好,更快。 非常感谢。

CODE:

Sub StatusUpdate()
Dim ws As Worksheet
Dim c As Range
Dim Rng As Range

Set ws = Sheet1
Set Rng = ws.Range("b10", ws.Cells(Rows.Count, 2).End(xlUp).Rows)
For Each c In Rng
    days = c.Offset(0, 6) - Date
    'if activity is complete
    If c.Offset(0, 16) = 1 Then
      c.Offset(0, 15) = "Closed"
    'If activity is canceled
    ElseIf c.Offset(0, 15) = "Canceled" Then
        c.Offset(0, 14) = ChrW(&H25AC)
    'activity is in hold
    ElseIf c.Offset(0, 15) = "Hold" Then
        c.Offset(0, 14) = ChrW(&H221E)
    'if the area is in hold and finish date is less than 14 dias
    ElseIf c.Offset(0, 15) = "Hold" And days < 14 Then
        c.Offset(0, 14) = ChrW(&H221E)
        c.Offset(0, 13) = "High"

    'if final date passed and activity is not completed
    ElseIf c.Offset(0, 16) < 1 And c.Offset(0, 6) < Date And c.Offset(0, 15) <> "Canceled" Then
        c.Offset(0, 15) = "Behind"
        c.Offset(0, 14) = ChrW(&H25BC)
        c.Offset(0, 13) = "Critical"
    'if activity is less than 85% and only only remains 7 days in calendar
    ElseIf c.Offset(0, 6) > Date And days <= 7 And c.Offset(0, 16) < 0.85 And c.Offset(0, 15) <> "Canceled" Then
        c.Offset(0, 15) = "At risk"
        c.Offset(0, 14) = ChrW(&HA4)
        c.Offset(0, 13) = "High"
    'if activiy is in progress and final date is not overdue
     ElseIf c.Offset(0, 6) > Date And c.Offset(0, 16) > 0 And c.Offset(0, 15) <> "Canceled" And c.Offset(0, 15) <> "Hold" Then
        c.Offset(0, 15) = "In progress"
        c.Offset(0, 14) = ChrW(&H25B2)

    ElseIf c.Offset(0, 6) > Date And days > 7 And c.Offset(0, 3) > 0 Then
        c.Offset(0, 15) = "Open"
        c.Offset(0, 14) = ChrW(&H25D9)
    End If
Next c
End Sub

2 个答案:

答案 0 :(得分:0)

我选择:

  • Select Case结构(更多是为了便于阅读)

  • 消除一些无用的检查(是以前的检查的逻辑后果)

  • With ... End With阻止,以避免多次引用相同的对象

    Option Explicit
    
    Sub StatusUpdate()
        Dim c As Range
        Dim Days As Variant
    
        With Worksheets("Sheet1") 'reference your sheet
            For Each c In .Range("B10", .Cells(.Rows.Count, 2).End(xlUp)) 'loop through referenced sheet column B cells from row 10 down to last not empty one
                With c 'reference current cell
                    Days = .Offset(0, 6) - Date
                    Select Case True
                        'if activity is complete
                        Case .Offset(0, 16) = 1
                            .Offset(0, 15) = "Closed"
    
                        'If activity is canceled
                        Case .Offset(0, 15) = "Canceled"
                            .Offset(0, 14) = ChrW(&H25AC)
    
                        'activity is in hold
                        Case .Offset(0, 15) = "Hold"
                            .Offset(0, 14) = ChrW(&H221E)
                            If Days < 14 Then .Offset(0, 13) = "High" 'if finish date is less than 14 dias
    
                        'if final date passed
                        Case .Offset(0, 6) < Date
                            If .Offset(0, 16) < 1 Then 'and  if activity is not completed
                                .Offset(0, 15) = "Behind"
                                .Offset(0, 14) = ChrW(&H25BC)
                                .Offset(0, 13) = "Critical"
                            End If
    
                        'if final date is not overdue
                        Case .Offset(0, 6) > Date
                            Select Case True
                                'if activity is less than 85% and only only remains 7 days in calendar
                                Case Days <= 7 And .Offset(0, 16) < 0.85
                                    .Offset(0, 15) = "At risk"
                                    .Offset(0, 14) = ChrW(&HA4)
                                    .Offset(0, 13) = "High"
    
                                'if activity is in progress
                                Case .Offset(0, 16) > 0
                                    .Offset(0, 15) = "In progress"
                                    .Offset(0, 14) = ChrW(&H25B2)
    
                                Case Days > 7 And .Offset(0, 3) > 0
                                    .Offset(0, 15) = "Open"
                                    .Offset(0, 14) = ChrW(&H25D9)
                        End Select
                    End Select
                End With
            Next
        End With
    End Sub
    

答案 1 :(得分:0)

代码审查。

你的大时间驱动程序是整个范围的循环,从表面上看,这看起来很好 - 没有内环的单循环。

我不会将c As Range用于你的循环。您已经定义了一个范围,现在可以从1 to .Rows.Count进行迭代以获取您的数据(.Cells(iterator,<colno>)),因为您的数据具有强大的结构。这样可以避免使用另一个复杂的对象来完成您已经设置的简单工作。

我还会对复杂的If结构进行分析。有时嵌套的if更容易阅读和维护。有时,通过查看解析方式,您可以获得较低的效率。但与有效管理循环相比,这将是一个小小的收获。