Vba 重构嵌套的';如果';声明

Vba 重构嵌套的';如果';声明,vba,excel,Vba,Excel,下面是一些代码,它在电子表格中的某个区域循环,并根据源单元格不包含值“(空白)”的条件执行代码。代码可以工作,但是以这种方式运行嵌套的if语句效率很低。从长远来看,我试着让它更有效率,但我没有主意了 有什么建议吗 Sub NestedIfStatement() Dim lastrow1 As Long Dim I As Integer, J As Integer, N As Integer, MaxPriority as Integer Dim Maxnumber as Range Dim WS

下面是一些代码,它在电子表格中的某个区域循环,并根据源单元格不包含值“(空白)”的条件执行代码。代码可以工作,但是以这种方式运行嵌套的if语句效率很低。从长远来看,我试着让它更有效率,但我没有主意了

有什么建议吗

Sub NestedIfStatement()
Dim lastrow1 As Long
Dim I As Integer, J As Integer, N As Integer, MaxPriority as Integer
Dim Maxnumber as Range
Dim WS1 As Worksheet, WS3 as Worksheet
Dim WB As Workbook

Set WB = ThisWorkbook
Set WS1 = WB.Worksheets("Config")
Set WS2 = WB.Worksheets("Data")
Set WS3 = WB.Worksheets("Status Report") 

lastrow1 = WS1.Cells(Rows.Count, 1).End(xlUp).Row
I = 1
J = 1    
N = 3
Set Maxnumber = WS1.Range("A" & I & ":A" & lastrow1)
    MaxPriority = Application.Max(Maxnumber)

For J = 1 To lastrow1
    If WS1.Cells(J, 1) <= MaxPriority Then
       If WS1.Cells(J, 6).Value <> "(blank)" Then
          WS3.Cells(N, 7).Value = WS1.Cells(J, 6).Value
       End If
       If WS1.Cells(J, 5).Value <> "(blank)" Then
          WS3.Cells(N, 6).Value = WS1.Cells(J, 5).Value
       End If
       If WS1.Cells(J, 4).Value <> "(blank)" Then
          WS3.Cells(N, 4).Value = WS1.Cells(J, 4).Value
       End If
       If WS1.Cells(J, 3).Value <> "(blank)" Then
          WS3.Cells(N, 3).Value = WS1.Cells(J, 3).Value
       End If
       If WS1.Cells(J, 2).Value <> "(blank)" Then
          WS3.Cells(N, 2).Value = WS1.Cells(J, 2).Value
       End If
       N = N + 1
    End If
Next J

End Sub
Sub-NestedIfStatement()
变暗最后一行1的长度
Dim I为整数,J为整数,N为整数,MaxPriority为整数
Dim Maxnumber as范围
将WS1标注为工作表,将WS3标注为工作表
将WB设置为工作簿
设置WB=ThisWorkbook
设置WS1=WB.Worksheets(“配置”)
设置WS2=WB.工作表(“数据”)
设置WS3=WB.工作表(“状态报告”)
lastrow1=WS1.Cells(Rows.Count,1).End(xlUp).Row
I=1
J=1
N=3
设置Maxnumber=WS1.Range(“A”&I&“:A”&lastrow1)
MaxPriority=Application.Max(Maxnumber)
对于J=1到最后一行1

如果WS1.Cells(J,1)在循环之前您是否尝试过将计算模式切换到手动模式,然后在循环之后将其切换回手动模式?您所描述的是,在
WS3
中的每次更改都会刷新大量计算。另外,关闭屏幕更新可能会有所帮助

比如说:

Dim CalcMode As Long
'...
Application.ScreenUpdating = False
CalcMode = Application.Calculation
Application.Calculation = xlCalculationManual ' Change it to manual update
For J = 1 To lastrow1
    '...
Next
Application.Calculation = CalcMode ' Restore to what it was before
Application.ScreenUpdating = True
或者,您可以将
WS1
中的值加载到数组(Variant)中,然后执行嵌套If

您可能遇到的另一个问题是,在循环填充细节之前,您没有清除WS3的内容,这会产生不相关的数据。
编辑(可能的解决方案)

根据您的代码试图实现的目标,您可以使用VBA将公式指定给关联的单元格-无循环

假设WS3中的第2行有一个标题,那么B、C、D列的结果公式1c1是:
=IF(Config!R[-2]C“(blank)”,Config!R[-2]C“(blank)”,
列F、G是:
=IF(Config!R[-2]C[-1],“(blank)”,Config!R[-2]C[-1],“)

为了使公式更通用,我将
'
放入常量字符串中。
lastrow3
基本上是WS3中需要这些公式的最后一行,它取决于WS1的A列中使用的行数

请使用此代码计算时间差并发回,我们都对真实世界数据的效率感到好奇

Option Explicit

Sub NestedIfStatement()
    Const Formula_FG = "=IF('<S1>'!R[-2]C[-1]<>""(blank)"",'<S1>'!R[-2]C[-1],"""")"
    Const Formula_BCD = "=IF('<S1>'!R[-2]C<>""(blank)"",'<S1>'!R[-2]C,"""")"

    Dim CalcMode As Long, sFormula As String
    Dim lastrow3 As Long
    Dim WS1 As Worksheet

    Application.ScreenUpdating = False
    CalcMode = Application.Calculation
    Application.Calculation = xlCalculationManual

    With ThisWorkbook
        Set WS1 = .Worksheets("Config")
        lastrow3 = WS1.Cells(Rows.Count, 1).End(xlUp).Row + 2 ' Offset from row 1 to 3 (N)
        With .Worksheets("Status Report")
            .UsedRange.Offset(1, 0).ClearContents ' Remove old data below the header row
            sFormula = Replace(Formula_BCD, "<S1>", WS1.Name)
            .Range("B3:D" & lastrow3).FormulaR1C1 = sFormula
            sFormula = Replace(Formula_FG, "<S1>", WS1.Name)
            .Range("F3:G" & lastrow3).FormulaR1C1 = sFormula
        End With
        Set WS1 = Nothing
    End With

    Application.Calculation = CalcMode
    Application.ScreenUpdating = True

End Sub
选项显式
子嵌套子报表()
常量公式_FG=“=IF(“”!R[-2]C[-1]“”(空白)”,“”!R[-2]C[-1],“”)
常量公式_BCD=“=IF(“”!R[-2]C”“(空白)”,“”!R[-2]C”““”)
Dim CalcMode为长,sFormula为字符串
最后一行的长度为3
将WS1设置为工作表
Application.ScreenUpdating=False
CalcMode=应用程序计算
Application.Calculation=xlCalculationManual
使用此工作簿
设置WS1=.Worksheets(“配置”)
lastrow3=WS1.Cells(Rows.Count,1).End(xlUp).Row+2'从第1行到第3行的偏移量(N)
带.工作表(“状态报告”)
.UsedRange.Offset(1,0).ClearContent'删除标题行下方的旧数据
sFormula=Replace(公式_BCD,“,WS1.Name)
.范围(“B3:D”和最后一行3).公式1c1=s公式
sFormula=Replace(公式_FG,“,WS1.Name)
.范围(“F3:G”和最后一行3).公式1c1=s公式
以
设置WS1=Nothing
以
Application.Calculation=CalcMode
Application.ScreenUpdating=True
端接头

您是否尝试过在循环前将计算模式切换为手动模式,然后在循环后将其切换回手动模式?您所描述的是,在
WS3
中的每次更改都会刷新大量计算。另外,关闭屏幕更新可能会有所帮助

比如说:

Dim CalcMode As Long
'...
Application.ScreenUpdating = False
CalcMode = Application.Calculation
Application.Calculation = xlCalculationManual ' Change it to manual update
For J = 1 To lastrow1
    '...
Next
Application.Calculation = CalcMode ' Restore to what it was before
Application.ScreenUpdating = True
或者,您可以将
WS1
中的值加载到数组(Variant)中,然后执行嵌套If

您可能遇到的另一个问题是,在循环填充细节之前,您没有清除WS3的内容,这会产生不相关的数据。
编辑(可能的解决方案)

根据您的代码试图实现的目标,您可以使用VBA将公式指定给关联的单元格-无循环

假设WS3中的第2行有一个标题,那么B、C、D列的结果公式1c1是:
=IF(Config!R[-2]C“(blank)”,Config!R[-2]C“(blank)”,
列F、G是:
=IF(Config!R[-2]C[-1],“(blank)”,Config!R[-2]C[-1],“)

为了使公式更通用,我将
'
放入常量字符串中。
lastrow3
基本上是WS3中需要这些公式的最后一行,它取决于WS1的A列中使用的行数

请使用此代码计算时间差并发回,我们都对真实世界数据的效率感到好奇

Option Explicit

Sub NestedIfStatement()
    Const Formula_FG = "=IF('<S1>'!R[-2]C[-1]<>""(blank)"",'<S1>'!R[-2]C[-1],"""")"
    Const Formula_BCD = "=IF('<S1>'!R[-2]C<>""(blank)"",'<S1>'!R[-2]C,"""")"

    Dim CalcMode As Long, sFormula As String
    Dim lastrow3 As Long
    Dim WS1 As Worksheet

    Application.ScreenUpdating = False
    CalcMode = Application.Calculation
    Application.Calculation = xlCalculationManual

    With ThisWorkbook
        Set WS1 = .Worksheets("Config")
        lastrow3 = WS1.Cells(Rows.Count, 1).End(xlUp).Row + 2 ' Offset from row 1 to 3 (N)
        With .Worksheets("Status Report")
            .UsedRange.Offset(1, 0).ClearContents ' Remove old data below the header row
            sFormula = Replace(Formula_BCD, "<S1>", WS1.Name)
            .Range("B3:D" & lastrow3).FormulaR1C1 = sFormula
            sFormula = Replace(Formula_FG, "<S1>", WS1.Name)
            .Range("F3:G" & lastrow3).FormulaR1C1 = sFormula
        End With
        Set WS1 = Nothing
    End With

    Application.Calculation = CalcMode
    Application.ScreenUpdating = True

End Sub
选项显式
子嵌套子报表()
常量公式_FG=“=IF(“”!R[-2]C[-1]“”(空白)”,“”!R[-2]C[-1],“”)
常量公式_BCD=“=IF(“”!R[-2]C”“(空白)”,“”!R[-2]C”““”)
Dim CalcMode为长,sFormula为字符串
最后一行的长度为3
将WS1设置为工作表
Application.ScreenUpdating=False
CalcMode=应用程序计算
Application.Calculation=xlCalculationManual
使用此工作簿
设置WS1=.Worksheets(“配置”)
lastrow3=WS1.Cells(Rows.Count,1).End(xlUp).Row+2'从第1行到第3行的偏移量(N)
带.工作表(“状态报告”)
.UsedRange.Offset(1,0).ClearContent'删除标题行下方的旧数据
sFormula=Replace(公式_BCD,“,WS1.Name)
.范围(“B3:D”和最后一行3).公式1c1=s公式
sFormula=Replace(公式_FG,“,WS1.Name)
.范围(“F3:G”和最后一行3).公式1c1=s公式
以
设置WS1=Nothing
以
Application.Calculation=CalcMode
Application.ScreenUpdating=True
端接头

您是否尝试过在循环前将计算模式切换为手动模式,然后在循环后将其切换回手动模式?你所描述的是有很多计算需要刷新