Страница 1 из 1

"Вложенные" Select'ы

Добавлено: 02 дек 2008, 15:00
Тихон
Интересный эффект обнаружился...
Вот очень надуманный пример вложенных циклов.

Код: Выделить всё

Sub Diap()
    Set SmenTime = Union(Range("D7 :D 48"), Range("D84 :D 104"), _
             Range("M7:M48"), Range("M84:M104"))
    SmenTime.Select
    For Each Cv In Selection
       Cv.Activate
       Rw = Cv.Row
       Cw = Cv.Column
       Range(Cells(6, 50), Cells(100, 50)).Select
       For Each Nn In Selection
          Nn.Activate
          Nr = Nn.Row
          Nc = Nn.Column
          Range(Cells(6, 52), Cells(100, 52)).Select
       Next
'       Selection.Delete (xlUp)
    Next
End Sub
Прикол в том, что, невзирая на создание нового диапазона в цикле For each... Next, выполнение цикла продолжается в установленном изначально порядке. Хотя выделение с диапазона SmenTime снимается... И с вновь созданным диапазоном можем делать что хотим, не касаясь SmenTime. Хоть создать новый диапазон при переборе его ячеек. А потом спокойно вернемся к внешнему циклу и перейдем к следующей ячейке внешнего (!) цикла по порядку.

Не понимаю - каким образом ДВА (и больше) Selection уживаются на одном листе?!
И сколько таких вложений можно образовать?

Спасибо за внимание.

Re: "Вложенные" Select'ы

Добавлено: 02 дек 2008, 16:21
EducatedFool
При запуске первого цикла строкой For Each Cv In Selection
Excel один раз считывает в память выделенный диапазон, после чего цикл начинает перебирать все ячейки в "считанном в память" диапазоне.
То есть к выделению на листе он больше ни разу не обращается.

Так что даже если сразу после строки For Each Cv In Selection поставить строку
[a1].select, то всё будет корректно работать.

Re: "Вложенные" Select'ы

Добавлено: 02 дек 2008, 16:44
Тихон
EducatedFool писал(а):...Так что даже если сразу после строки For Each Cv In Selection поставить строку
[a1].select, то всё будет корректно работать.

Спасибо.

Это где-нибудь документировано?

Re: "Вложенные" Select'ы

Добавлено: 02 дек 2008, 19:06
Naeel Maqsudov
Это нигде не документировано но вполне очевино. Вот другой пример:

Код: Выделить всё

Sub qwe()
j = 5
  For i = 1 To j
    MsgBox i
    j = 2
  Next
End Sub
Такой цикл выпонится 5 раз. Так как выражения Start, End и Step в оператора For вычисляются единожды при входе в цикл, и потом используются для вычисления счетчика на каждой итерации. Так оператор FOR работал во всех Бейсиках. И также он работает во многих других алгоритмических языках.

Теперь о Selection:
Help писал(а): Selection Property
SpecificsReturns the selected object in the active window, for an Application object, and a specified window, for a Windows object.

Remarks
The returned object type depends on the current selection (for example, if a cell is selected, this property returns a Range object). The Selection property returns Nothing if nothing is selected.
Будучи вычисленным единожды оно дает нам ссылку на экземпляр класса Range. который существует в неизменном виде пока работает цикл. А экземпляр класса Range предоставляет доступ к конкретному фрагменту рабочего листа.

Так что наблюдаемый эффект логичен, так должно быть, и слава богу, что это так :)

Re: "Вложенные" Select'ы

Добавлено: 03 дек 2008, 09:06
heisnod
Naeel Maqsudov писал(а):

Код: Выделить всё

Sub qwe()
j = 5
  For i = 1 To j
    MsgBox i
    j = 2
  Next
End Sub


Хочу добавить, что в паскале/дельфи такой код вызовет ошибку, так как это может привести к зацикливанию.