Цикл каждой ячейки в диапазоне ячеек, когда дан объект Range

43

Скажем, у меня есть следующий код:

Sub TestRangeLoop()
    Dim rng As Range
    Set rng = Range("A1:A6")

    ''//Insert code to loop through rng here
End Sub

Я хочу иметь возможность выполнять итерацию через набор объектов Range для каждой ячейки, указанной в rng. Концептуально, я хотел бы сделать это так:

For Each rngCell As Range in rng
     ''//Do something with rngCell
Next

Я знаю, что могу решить эту проблему путем разбора rng.Address и создания объектов Range вручную, но я надеюсь, что существует более прямой способ, который не включает синтаксический анализ строк.

Теги:
excel-vba
excel

4 ответа

73
Лучший ответ
Sub LoopRange()

    Dim rCell As Range
    Dim rRng As Range

    Set rRng = Sheet1.Range("A1:A6")

    For Each rCell In rRng.Cells
        Debug.Print rCell.Address, rCell.Value
    Next rCell

End Sub
  • 1
    Это сработало отлично, но я удивлен, почему это сработало, поскольку Cells - просто объект Range . Фактически, я удалил .Cells из rRng в строке For Each и он все еще работал. Как насчет Range делает его похожим на коллекцию Range s? Большое спасибо за Вашу помощь!
  • 7
    dailydoseofexcel.com/archives/2004/07/07/the-strange-object В этом контексте свойство Cells является свойством по умолчанию, поэтому оно работает без него. В других контекстах свойство Value является свойством по умолчанию. Все объекты Range на самом деле являются объектами коллекции, которые содержат объекты Range - я думаю, до бесконечности. Range - явно странный объект, который нарушает парадигму коллекции объектов / объектов на каждом шагу. Но в большинстве случаев это просто работает. :)
Показать ещё 3 комментария
11

Вы можете использовать Range.Rows, Range.Columns или Range.Cells. Каждая из этих коллекций содержит объекты Range.

Здесь вы можете изменить пример Dick, чтобы работать с Rows:

Sub LoopRange()

    Dim rCell As Range
    Dim rRng As Range

    Set rRng = Sheet1.Range("A1:A6")

    For Each rCell In rRng.Rows
        Debug.Print rCell.Address, rCell.Value
    Next rCell

End Sub

И Columns:

Sub LoopRange()

    Dim rCell As Range
    Dim rRng As Range

    Set rRng = Sheet1.Range("A1:A6")

    For Each rCol In rRng.Columns
        For Each rCell In rCol.Rows
            Debug.Print rCell.Address, rCell.Value
        Next rCell
    Next rCol

End Sub
  • 0
    Как бы вы использовали эти свойства для создания цикла. Я играл со свойствами Range такими как те, что вы упомянули, и я не могу понять, как их использовать, чтобы дать мне необходимую информацию.
2

Чтобы сделать заметку о Дике, это правильно, но я бы не рекомендовал использовать цикл For Each. Для каждого создается временная ссылка на COM-ячейку за кулисами, к которым у вас нет доступа (что вам нужно, чтобы избавиться от нее).

Подробнее см. ниже:

Как правильно очистить объекты взаимодействия Excel?

Чтобы проиллюстрировать эту проблему, попробуйте пример для каждого примера, закройте приложение и посмотрите на Диспетчер задач. Вы должны увидеть, что экземпляр Excel по-прежнему работает (поскольку все объекты не были удалены должным образом).

Более чистый способ справиться с этим - запросить таблицу с помощью ADO:

http://technet.microsoft.com/en-us/library/ee692882.aspx

  • 0
    Я не думаю, что эти предупреждения относятся к этому вопросу, хотя. Бен использует VBA, предположительно в том же экземпляре Excel, что и диапазоны, с которыми он работает.
  • 2
    Я просто использую VBA. Я ценю слово предостережения, но это конкретное решение состоит в том, что я просто нуждаюсь в прохождении через несколько ячеек, чтобы создать какой-то SQL-код, чтобы я мог закончить -My-сценарий-и-двигаться с моей жизнью.
Показать ещё 1 комментарий
0

Я воскрешаю мертвых здесь, но потому, что диапазон можно определить как "A: A", используя a для каждого цикла, заканчивается потенциальным бесконечным циклом. Решение, насколько мне известно, заключается в использовании цикла Do Until.

Do Until Selection.Value = ""
  Rem Do things here...
Loop
  • 2
    Если вы не используете последнюю заполненную ячейку, смотрящую снизу вверх (например, .range(.cells(1, 1), .cells(.rows.count, 1).end(xlup)) ), используйте метод Intersect с полный столбец и свойство .UsedRange рабочего листа (например, Intersect(.columns(1), .usedrange) ) или, возможно, свойство Range.CurrentRegion (например, .cells(1, 1).currentregion.columns(1) ) достаточно эффективно ,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню