У меня есть скрипт vba, который должен копировать данные с одного листа на другой. Это происходит с помощью трех вложенных циклов. Выполнение кода при отладке кажется, что они работают отлично, но когда запускается скрипт vba, они, похоже, слишком рано останавливаются. В противном случае работает скрипт vba.Вложенные петли VBA, выходящие раньше
Я смотрел на это в течение нескольких часов и не мог на всю жизнь видеть, что заставило бы петли останавливаться рано. Я надеюсь, что решение - это что-то простое, что я пропустил, но у меня настоящая потеря, не в первый раз с тех пор, как я начал это.
Лист организована следующим образом:
Лист1, содержит данные, которые должны быть скопированы.
- Каждая строка содержит отдельный ответ, из которых имеются в тестовых данных
- Лист содержит девять блоков данных 55, названный Эпизод 1-9. Каждый эпизод содержит столбец, где целое число представляет начало, конец и интервал времени.
- В тестовых данных каждый эпизод идентичен, за исключением времени начала и окончания.
- Максимальное значение для EndTime 36
- тестовых данных в течение первых четырех Эпизод только блоков, так что Episode4 содержит EndTime = 36 для каждой строки
Sheet2, где данные должны идти - Первый столбец содержит каждый RespondentID, скопированный по 36 строкам. . Второй столбец содержит номера 1-36, представляя таким образом временной интервал для этого респондента. -11 Столбцы после этого содержат область, в которую помещаются данные, скопированные из листа 1 для этого респондента/времени. Эти 36x11 области названы «Response1-55» в тестовых данных
Логика сценария VBA выглядит следующим образом:
Счетчики: - п счетчик числа респондентов - г счетчик для числа эпизодов - i счетчик для строк в пределах копируемых ответов.
-> Для каждого ответа (начиная с п = 1 Респонденты)
-> Выберите первый эпизод (Начиная с R = 1 до 9)
---> Для каждого эпизода
--- > Прочтите начальные, конечные и временные интервалы
---> Начиная с i = Начать с i = Конец копировать соответствующие ячейки из n-й строки r-го эпизода
---> Скопировать эти ячейки в i-я строка текущего ответа на листе2
---> Когда вы достигнете EndTime текущего эпизода, перейдите к следующему (следующий 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 но с тех пор код немного изменился, и это другая проблема.
Еще раз спасибо огромное за любую помощь, которая может возникнуть из-за этого. Я смотрел на это часами и не вижу, где ошибка. Любое руководство вообще очень ценилось.
Вы можете пересмотреть всю конструкцию таблицы на каком-то этапе - используя именованные диапазоны, как вы делаете это к ошибкам и трудно отлаживать (как вы заметили). Excel большой и простой в использовании с табличными данными - вместо 9 отдельных диапазонов вы можете иметь один блок с дополнительным столбцом, содержащим номер эпизода, например. Это простое изменение значительно улучшит читаемость и код. – assylias
Спасибо за обратную связь еще раз. Лист фактически создается программой, поэтому некоторые из беспорядков, но я понимаю, что вы имеете в виду, чтобы компенсировать выбор, а не использовать диапазоны. Текущий метод настолько близок, но если я не могу заставить его работать полностью, я буду использовать предложенный подход. В этом случае я буду просить вас ответить на этот вопрос, чтобы я мог принять его. Еще раз спасибо за это. Очень признателен. – TornHair