VBA嵌套循环提前退出

时间:2012-03-08 02:40:28

标签: excel excel-vba nested-loops vba

我有一个vba脚本,它应该将数据从一个工作表复制到另一个工作表。它通过三个嵌套的for循环来实现。在调试这些代码时单步执行代码看起来效果很好,但是当运行vba脚本时,它们似乎太早停止了。否则vba脚本可以工作。

我一直盯着这看了好几个小时,不能为我的生活看到什么会导致循环提前停止。我希望这个解决方案很简单,我错过了,但我真的很失落,而不是自从我开始这个以来的第一次。

表单的组织如下:

Sheet1,包含要复制的数据。

  • 每行包含一个单独的响应,其中测试数据中有55个
  • 该表包含九个数据块,名为Episode 1-9。每集都包含一个列,其中整数表示开始,结束和间隔时间。
  • 在测试数据中,除开始/结束时间外,每集都相同。
  • EndTime的最大值为36
  • 测试数据仅限于前四个Episode块,因此Episode4包含每行的EndTime = 36

Sheet2,数据的去处 -First列包含复制超过36行的每个RespondentID - 第二列包含数字1-36,因此表示该响应者的时间段 -11之后的列包含放置从Sheet1为该Respondent / Time复制的数据的区域。这些36x11区域在测试数据中被命名为“Response1-55”

vba脚本的逻辑如下:

计数器: - n个受访者数量的计数器 - r集数量的剧集 - 我计算复制到的响应中的行。

- >对于每个回复(从受访者的n = 1开始)
- >选择第一集(从r = 1到9开始)
     --->对于每一集
     --->读取开始,结束和间隔时间
     --->从i =开始到i =结束从第r集的第n行开始复制相关单元格      --->将这些单元格复制到sheet2上当前响应的第i行      --->当你到达当前剧集的结束时间时,转到下一个(下一个r)
- >如果您刚刚完成的剧集有36个作为其EndTime,那么请转到下一个回复,或继续直到您用完剧集。
- >下一个回复

在调试中,代码看起来就是这样做的。

但是,当我在测试表上运行vba脚本时,它仅适用于第1集和第2集。第3集和第4集中的数据不会被复制。没有任何东西被复制到位,并且被复制的数据在各方面都是正确的。任何时候都没有错误消息。

如果有人能说明为什么会这样,我会建立一个真正的教会。答案也可以在这里添加:https://stackoverflow.com/questions/119323/nested-for-loops-in-different-languages其中还没有VBA部分。

指向测试表的链接位于:http://dl.dropbox.com/u/41041934/MrExcelExample/TornHairExampleSheet.xlsm

代码的相关部分在这里

Sub PopulateMedia()
    Application.ScreenUpdating = False

    'Count the total number of response rows in original sheet
    Dim Responses As Long, n As Integer, i As Integer, r As Integer
        Responses = (Sheets("Sheet1").UsedRange.Rows.Count - 3) ' equals 55 in test sheet

    'For each response...
    For n = 1 To Responses
        i = 1 'Reset i for new response
            Dim curr_resp As Range
                Set curr_resp = Sheets(2).Range("Response" & n) 'Define a range containing all response data

            For r = 1 To 9  'For each episode...
                Dim curr_ep As Range 'Define a range containing episode data for all responses
                    Set curr_ep = Sheets(1).Range("episode" & r)

                Dim Stime As Integer, Etime As Integer, Itime As Integer 'Variables contain start, end and inter-episode times
                    Stime = curr_ep.Cells(n, 1)
                    Etime = curr_ep.Cells(n, 17)
                    Itime = curr_ep.Cells(n, 19)

                    For i = Stime To (Etime + Itime) 'for each time-slot...
                        If i <= Etime Then
                          Dim a As Variant
                            a = curr_ep.Range(curr_ep.Cells(n - 3, 1), curr_ep.Cells(n - 3, 11))
                            curr_resp.Rows(i) = a 'Copy data from above current episode to current response for slots between Stime and Etime
                        End If
                    Next i
                If Etime = 36 Then Exit For
             Next r
     Next n

    Application.ScreenUpdating = True
End Sub

要透露,我已经从这个网站VBA copy from a union of two ranges to a row of another range获得了有关此项目的帮助,但从那时起代码已经略有改变,这是一个不同的问题。

再一次,非常感谢您提供的任何帮助。我一直盯着这几个小时,看不出错误在哪里。任何指导都非常赞赏。

1 个答案:

答案 0 :(得分:5)

如果可以,我会将此作为评论发布,但这太长了。所以这里是一个查询/潜在的解决方案

我认为您的范围参考是问题

以下代码是代码的简化版本

curr_ep episode1 的命名范围。它的范围地址为$Y$4:$AQ$58

当您遍历a变体时,您将使用此语法设置范围 a = curr_ep.Range(curr_ep.Cells(n - 3, 1), curr_ep.Cells(n - 3, 11))
这相当于 a = curr_ep.Range("Y2:AQ2")

这意味着您实际上正在查看 AW2:BG2 而不是Y2:AQ2这是我认为您可能想要的,即您正在构建一个非预期的偏移量

Sub PopulateMedia()
    n = 1
    r = 1
    Dim curr_ep As Range
    Dim curr_test As Range
    Set curr_ep = Sheets(1).Range("episode" & r)
    Set curr_test = curr_ep.Range(curr_ep.Cells(n - 3, 1), curr_ep.Cells(n - 3, 11))
End Sub

enter image description here