Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel VBA嵌套循环提前退出_Excel_Nested Loops_Vba - Fatal编程技术网

Excel VBA嵌套循环提前退出

Excel VBA嵌套循环提前退出,excel,nested-loops,vba,Excel,Nested Loops,Vba,我有一个vba脚本,它应该将数据从一个工作表复制到另一个工作表。它通过三个嵌套的for循环实现。在调试这些脚本时逐步执行代码似乎工作得很好,但在运行vba脚本时,它们似乎停止得太早。否则vba脚本将正常工作 我已经盯着这个看了好几个小时了,我一辈子都看不到是什么原因导致循环提前停止。我希望解决办法是我错过的简单的事情,但我真的很茫然,这不是我开始做这件事以来的第一次 该表的组织结构如下: 图纸1,包含要复制的数据 每行包含一个单独的响应,测试数据中有55个响应 该表包含九个数据块,命名为第1-

我有一个vba脚本,它应该将数据从一个工作表复制到另一个工作表。它通过三个嵌套的for循环实现。在调试这些脚本时逐步执行代码似乎工作得很好,但在运行vba脚本时,它们似乎停止得太早。否则vba脚本将正常工作

我已经盯着这个看了好几个小时了,我一辈子都看不到是什么原因导致循环提前停止。我希望解决办法是我错过的简单的事情,但我真的很茫然,这不是我开始做这件事以来的第一次

该表的组织结构如下:

图纸1,包含要复制的数据

  • 每行包含一个单独的响应,测试数据中有55个响应
  • 该表包含九个数据块,命名为第1-9集。每集包含一列,其中一个整数表示开始、结束和间隔时间
  • 在测试数据中,除开始/结束时间外,每个事件都是相同的
  • EndTime的最大值为36
  • 测试数据仅覆盖前四个情节块,因此第四幕每行包含EndTime=36
表2,数据的去向 -第一列包含在36行上复制的每个响应ID -第二列包含数字1-36,因此表示受访者的时间段 -之后的11列包含放置从sheet1复制的该响应者/时间数据的区域。这些36x11区域在测试数据中命名为“Response1-55”

vba脚本的逻辑如下所示:

计数器: -n受访者人数计数器 -r集数计数器 -我计数器中的行被复制到

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

在调试中,代码似乎正是这样做的

但是,当我在测试表上运行vba脚本时,它仅适用于第1集和第2集。第三集和第四集的数据没有被复制。没有复制任何内容,复制的数据在各个方面都是正确的。任何时候都没有错误消息

如果有人能提出为什么会发生这种情况,我会为他们建造一座真正的教堂。答案也可以添加到这里:它还没有VBA部分

此处有测试表的链接:

代码的相关部分在这里

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
Sub-PopulateMedia()
Application.ScreenUpdating=False
'计算原始工作表中响应行的总数
Dim响应长度为,n为整数,i为整数,r为整数
回答=(表(“表1”).UsedRange.Rows.Count-3)在测试表中等于55
“对于每个响应。。。
对于n=1的响应
i=1'重置新响应的i
暗电流响应范围
Set curr_resp=Sheets(2)。范围(“响应”&n)”定义包含所有响应数据的范围
对于r=1到9'的每一集。。。
Dim curr_ep As Range“定义包含所有响应的事件数据的范围
设置当前页数=页数(1).范围(“插曲”&r)
Dim TIME As Integer、Etime As Integer、Itime As Integer’变量包含开始时间、结束时间和间隔时间
时间=当前单元格(n,1)
时间=当前单元格(n,17)
Itime=当前单元格(n,19)
对于每个时间段,i=时间到(时间+时间)“。。。
如果我可以的话,我会将此作为评论发布,但这太长了。因此,这是一个查询/潜在的解决方案

我认为你的参考范围是问题所在

下面的代码是您代码的精简版本

curr_ep
是一个命名的情节范围1。它的范围地址为
$Y$4:$AQ$58

当您在
变量中循环时,您正在使用此语法设置一个范围
a=curr\u ep.Range(curr\u ep.Cells(n-3,1),curr\u ep.Cells(n-3,11))

这相当于
a=当前范围(“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

您可能希望在某个阶段重新考虑电子表格的整个设计-使用命名范围的方式很容易出错,并且很难调试(正如您所注意到的!)。Excel非常好,并且易于使用表格数据——例如,你可以有一个块,其中包含一个包含剧集编号的附加列,而不是9个单独的范围。这个简单的更改将显著提高可读性和代码。再次感谢您的反馈。这张表实际上是由一个程序生成的,因此有些混乱,但我明白你所说的偏移选择而不是使用范围的意思。目前的方法非常接近,但如果我不能让它完全工作,我将使用建议的方法。在这种情况下,我会问你把它作为一个答案,这样我就可以接受它。再次感谢您调查此事。非常感谢。如果您不知道如何逐行循环代码,例如,获取上面的黄色条,则应遵循此处有关分析宏的建议()。基本上,如果在“下一个n”上引入一个断点,则可以在以下情况下评估各种变量/组件: