首页 > 解决方案 > Excel VBA嵌套for循环输出复制/错误结果

问题描述

我有一个嵌套的 for 循环,它遍历两个不同人的生日年份(1919 年到 2001 年)。

目的是找到两个人的每个年龄组合(基于出生日期)。

我遇到的问题是嵌套循环(带有变量 j 的循环)中的人的年龄似乎有时会随机重复,没有模式。

例如,当人 N 为 100-20 岁时,每个组合都可以正常工作,而人 J 没有重复的年龄值。然后突然之间,当人 N 为 19 岁时,人 J 将从 100-50 岁变为 49 岁两次然后到 47 岁。

以下是我的代码:

Sub ChangeDOB()
Application.ScreenUpdating = False
Dim n As Long
Dim i As Long
Dim j As Long
i = 2

For n = 1919 To 2001
    Sheets("Inputs").Range("E6").FormulaR1C1 = "1/15/" & n
    'j = 1919

    For j = 1919 To 2001
        Sheets("FF Tool Rates").Range("B" & i).Value = Sheets("Inputs").Range("E7").Value
        Sheets("Inputs").Range("E10").FormulaR1C1 = "1/15/" & j

        Sheets("FF Tool Rates").Range("C" & i).Value = Sheets("Inputs").Range("E11").Value
        Sheets("FF Tool Rates").Range("D" & i).Value = Sheets("Inputs").Range("S8").Value
        i = i + 1
    Next j
Next n
Application.ScreenUpdating = True

End Sub

Inputs!E7 中的公式计算人员 N 的年龄。Inputs!E11 中的公式计算人 J 的年龄。Inputs!S8 中的公式根据两人的年龄计算一个值。我希望这会增加清晰度。

以下是预期结果的示例:

Person N Age   Person J Age
90             90
90             89
90             88
90             87
90             86
90             85
90             84
90             83
90             82
90             81

下面是一个错误结果的例子(看看age 85是怎么出现的两次):

Person N Age   Person J Age
33             90
33             89
33             88
33             87
33             85 <-should've been 86
33             85 
33             84
33             83
33             82
33             81

最初我认为这是我设置 Excel 根据出生日期计算年龄的方式。但如果我在单元格中手动输入年份,Excel 会产生不重复的结果。因此,手动输入时 85 岁不会出现两次。

似乎没有关于何时出现此错误的模式,如果我重新运行代码,有时不会出现错误,有时错误会出现在其他地方。这就是为什么我很难调试它。

关于我可能遗漏了什么或者我在代码中搞砸了任何逻辑的任何建议或建议?

先感谢您!

标签: excelvbaloopsfor-loop

解决方案


我想我遇到了完全相同的问题,你的问题是我发现的唯一一个似乎它的答案可以帮助我的问题。可惜没有任何答案。

我最终修复了它,所以希望这对其他人有帮助:

我有一个工作簿,它根据 4 个变量计算产品价格(这些变量本身分为不同的工作表和其他工作簿)。变量a有 25 种可能性,b有 52 种,c有 3 种,d有 6 种。这给了我 22,464 种不同的价格可能性。我的代码有 4 个嵌套循环,可以在不同的行中打印每种可能性,因此我可以将输出导入到不同的系统。
我遇到的问题是,除了在高端计算机上运行将近 30 分钟外,我还会随机获取包含错误数据的行。

我的(未经证实的)诊断是,因为在For循环中,工作表的其他地方(实际上是 Excel 中的任何地方)都在进行大量计算,有时 VBA 会继续迭代并在源之前填写下一行有机会更新。
这就是为什么当我进行单步调试时错误不会出现,以及为什么即使在运行整个代码时它也是断断续续且看似随机的。

我首先使用来简化我的代码,并避免 VBA 在每一行代码中遍历With整个数组。我还为我的许多引用中的每一个创建了、和变量。WorkbooksWorksheetsExcel.WorkbookExcel.WorksheetExcel.Range

然而,最终似乎已经修复它的是添加Application.Calculation = xlCalculationManual到 sub 的开头,以及Application.Calculate嵌套循环中的适当点。我添加了一个检查Application.CalculationState,然后添加了一个DoEvents,但我什至不确定如何测试它是否有效。

这是代码的相关部分:

Sub test()
    '
    ' (Variable declarations suppressed)
    '
    
    Application.ScreenUpdating = False
        
    'Set to manual
    Application.Calculation = xlCalculationManual
        
    For a = 0 To 22464
        rngTabCusto.Value = wksCalculos.Cells(a / 936 + 23, 28).Value
        For b = 0 To 918
            rngFrete.Value = wksFrete.Cells(b / 18 + 4, 1).Value
            For c = 0 To 12
                rngTipoFat.Value = wksCalculos.Cells(c / 6 + 3, 3).Value

                '
                ' Calculate sheets after changing variables
                '
                Application.Calculate
                
                '
                ' Waits until calculations are done
                '
                If Not Application.CalculationState = xlDone Then
                    DoEvents
                End If
                
                '
                ' Prints calculation results
                '
                With wksDescontos
                    For d = 0 To 5
                        .Cells(a + b + c + d + 2, 1).Value = rngEstab.Value
                        .Cells(a + b + c + d + 2, 2).Value = wksOrcamento.Cells(2, d + 2).Value
                        .Cells(a + b + c + d + 2, 3).Value = rngContrib.Value
                        .Cells(a + b + c + d + 2, 4).Value = wksRegiao.Cells(b / 18 + 2, 1).Value
                        .Cells(a + b + c + d + 2, 5).Value = wksRegiao.Cells(b / 18 + 2, 2).Value
                        .Cells(a + b + c + d + 2, 6).Value = wksOrcamento.Cells(4, d + 2).Value
                        .Cells(a + b + c + d + 2, 7).Value = rngTabOrc.Value
                        .Cells(a + b + c + d + 2, 8).Value = data
                        .Cells(a + b + c + d + 2, 11).Value = rngFat.Value
                    Next d
                End With
            c = c + 5
            Next c
        b = b + 17
        Next b
    a = a + 935
    Next a
    
    'Reset
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
    
End Sub

推荐阅读