2014-10-01 3 views
0

Короткая версия вопроса:обходе `Cells` в` Range`

Код здесь

Dim rng As Range 
Set rng = Selection 
Set rng = rng.Columns(1) 
For Each cl In rng 
    cl.Select ' <-- Break #2 

дает мне это в ближайшем окне, когда выбор A1:B37

? rng.address(External:=True) 
[Book2]Sheet1!$A$1:$A$37 

? cl.Address(External:=True) 
[Book2]Sheet1!$A$1:$A$37 

Кто-нибудь может помочь мне понять, почему cl -> A1:A37 вместо cl -> A1? Обратите внимание, что я представляю себе код перезаписи, чтобы получить ожидаемые результаты. Но я хотел бы знать, в чем проблема, и, вероятно, узнать что-то новое. Вот о чем идет речь.


Длинная версия вопроса (как первоначально размещен):

У меня есть подпрограмма, которая работает на выбранный (прямоугольный) Диапазон rng. Ниже приведен код полезности. Он разветвляется в зависимости от числа ncols столбцов rng.

Когда ncols=1, он перебирает каждую ячейку cl в rng, выбирая cl и выполнение некоторых действий. Когда исходный выбор A1:A37, это работает нормально, как показано на выходе в ближайшем окне сразу после входа в цикл в Перерыв # 1 (см код ниже)

? rng.address(External:=True) 
[Book2]Sheet1!$A$1:$A$37 

? cl.Address(External:=True) 
[Book2]Sheet1!$A$1 

Когда ncols<>1, я хочу петля через каждую ячейку cl в первый столбецrng, делая то же, что и раньше. Теперь, когда начинает отбор A1:B37, это не работает, как показано на выходе в ближайшем окне на Перерыв # 2

? rng.address(External:=True) 
[Book2]Sheet1!$A$1:$A$37 

? cl.Address(External:=True) 
[Book2]Sheet1!$A$1:$A$37 

Любой человек может помочь мне понять, почему здесь cl -> A1:A37 вместо cl -> A1 (как в Перерыв № 1)? Обратите внимание, что я представляю себе код перезаписи, чтобы получить ожидаемые результаты. Но я хотел бы знать, в чем проблема, и, вероятно, узнать что-то новое. Вот о чем идет речь.

Dim rng As Range 
Set rng = Selection 
Dim ncols As Long 
ncols = rng.Columns.Count 
Dim cl As Range 
' 1- If only one column is selected, ... 
If (ncols = 1) Then 
    For Each cl In rng 
    cl.Select ' <-- Break #1 
    ... 
    Next cl 
' 2- If more than one column is selected, ... 
Else 
    Set rng = rng.Columns(1) 
    For Each cl In rng 
    cl.Select ' <-- Break #2 
    Dim rng2 As Range 
    Set rng2 = Range(cl, cl.Offset(0, ncols - 1)) 
    rng2.Select 
    ... 
    Next cl 
End If 

ответ

1

У меня не было возможности проверить свой код, но пока вы можете быть просто страдает от недостатка в явной форме: cl является Range, так это Column и и Area и любой другой вид объект диапазона. Вы можете использовать итератор диапазона, например cl: For each cl in Rng.Rows или ...in rng.Columns, или в ...rng.Cells и т. Д.

Другими словами, в то время как вы можете ожидать cl быть клеток диапазон, который не может быть в случае, если вы сделаете это явно, как:

For each cl in rng.Cells 

Или, так как вы определяете его как один столбец, это было бы эквивалентно:

For Each cl in rng.Rows 

(технически, cl представляет собой строки диапазон в этом rng , но поскольку это один диапазон столбцов, каждая «строка» также является отдельной ячейкой).

Ваш код может acutally быть довольно обтекаемый:

Sub f() 

    Dim rng As Range 
    Dim cl As Range 
    Dim rng2 As Range 

    Set rng = Range(Selection.Address).Resize(, 1) 
    ncols = Range(Selection.Address).Columns.Count 

    For Each cl In rng.Cells 
     cl.Select ' <-- Break #2 

     If nCols > 1 Then 
      Set rng2 = Range(cl, cl.Offset(0, ncols - 1)) 
      rng2.Select 
      '... 
     End If 
    Next cl 

End Sub 
+0

На месте (как обычно). Я не знал, что есть разные 'Type' of Range. На самом деле, помощь Excel для свойства Range.Cells * меня сбивает с толку: «Возвращает объект Range, который представляет ячейки в указанном диапазоне». Мне кажется, что он должен вернуть тот же объект, что и вызывающий ... –

+0

Как распознать объект 'rng' из' rng.Cells', путем тестирования (т. Е. Без проверки кода)? –

+0

нет необходимости разграничивать разницу между 'rng' и' rng.Cells', но, включив '.Cells', вы явно указываете тип итерации, которую хотите реализовать. Эти два объекта должны быть одинаковыми, так как «rng» и «rng.Cells» представляют собой всю область. Но, говоря «Для каждого cl в rng.Cells», вы указываете *, как вы хотите итерации. –

Смежные вопросы