Поведение во время выполнения в циклах For Each
описано в разделе 5.4.2.4 спецификации языка VBA.
Для массивов:
- Если объявленный тип массива Object , тогда > Set назначается первому элементу
в массиве. В противном случае
Пусть присваивается первому элементу в массиве.
- После установки выполняется <оператор-блок>. Если присутствует <вложенный оператор>, он выполняется.
- После того как <оператор-блок> и, если он есть, <вложенный-для-оператора> завершил выполнение, <связанное-переменное-выражение> будет присвоено следующему элементу в массиве (или назначено для набора) если это массив объектов). Если и только если в массиве больше нет элементов, выполнение <для каждого оператора> немедленно завершается. В противном случае <оператор-блок> выполняется снова, после чего следует <вложенный_статист>, если он присутствует, и этот шаг повторяется.
Для других перечислимых типов (в вашем случае Workbook.Worksheets
) это поведение во время выполнения:
- Значение данных должно быть ссылкой на объект для внешнего объекта, который поддерживает перечисление, определяемое реализацией
интерфейс. является либо назначенным, либо
Набор назначается первому элементу в в
в зависимости от реализации.
- После установки выполняется <оператор-блок>. Если присутствует <вложенный оператор>, он выполняется.
- Когда <оператор-блок> и, если он есть, <вложенный-для-оператора> завершил выполнение, <привязанное-переменное-выражение> назначается для следующего элемента в в реализации- определенным образом. Если в больше нет элементов, выполнение <для каждого оператора> немедленно завершается. В противном случае <оператор-блок> выполняется снова, после чего следует <вложенный-для-оператора>, если он присутствует, и этот шаг повторяется.
В вашем случае все сводится к тому, что неявный вызов генерируется компилятором, который выполняет следующее присваивание при входе в цикл в первый раз и для каждой итерации. Это будет что-то похожее на это после компиляции (на самом деле это немного сложнее, чем проверка Nothing
):
Set ws = ActiveWorkbook.Worksheets.[_NewEnum]
Do While ws Is Not Nothing
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.NumberFormat = "#,##0"
.Interior.ColorIndex = 36
.Font.Bold = True
End With
Set ws = ActiveWorkbook.Worksheets.[_NewEnum]
Loop
Обратите внимание, что именно поэтому вы не должны изменять содержимое коллекции во время итерации по ней - следующий элемент извлекается путем вызова [_NewEnum]
. Это означает, что элементы, возвращаемые базовой коллекцией, «выдаются» по одному за раз, поэтому изменение содержимого коллекции внутри цикла будет либо влиять на то, какие элементы возвращаются, либо потенциально может вызвать ошибку (поведение [_NewEnum]
зависит от реализации).