Что действительно делает свойство range.Rows в Excel?

56

ОК, я заканчиваю проект надстройки для устаревшего приложения Excel-VBA, и я еще раз столкнулся с загадкой таинственного диапазона. Rows (?) и workheet.Rows.

Кто-нибудь знает, что эти свойства действительно делают и что они должны предоставить мне? (примечание: все это, вероятно, относится также к соответствующим *. Свойствам столбцов.)

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

   SET rng = wks.Rows(iStartRow, iEndRow)

Но я никогда не мог заставить это сделать, хотя Intellisense показывает два аргумента. Вместо этого я должен использовать одну из двух или трех других (очень глупых) методик.

Помощь очень бесполезна (как правило, для Office VBA), а поиск в Google для строк не очень полезен, независимо от того, сколько других терминов я добавляю к нему.

Единственными вещами, которые я смог использовать для этого, являются: 1) возвращает одну строку в виде диапазона (rng.Rows(i)) и 2) возвращает количество строк в диапазон ( rng.Rows.Count). Это оно? Нет ли в этом ничего хорошего?

Уточнение: Я знаю, что он возвращает диапазон и что есть другие способы получить ряд строк. То, что я прошу, - это то, что мы получаем от .Rows(), которые мы еще не получаем из .Cells() и .Range()? Две вещи, которые я знаю, - это 1) более простой способ вернуть диапазон одной строки и 2) способ подсчета количества строк в диапазоне.

Есть ли что-нибудь еще?

  • 3
    RBY - Я думаю, что это в значительной степени так. Это удобный способ манипулирования целой строкой листа / частью диапазона (очень полезно!) С помощью Count для загрузки. Наиболее полезно для циклов, когда вы пробегаете ряд строк (или столбцов в этом отношении).
  • 2
    Отличный вопрос ... кроме. Считай, мне интересно, для чего они были.
Показать ещё 4 комментария
Теги:
excel-vba
excel
ole-automation

9 ответов

45
Лучший ответ

Range.Rows и Range.Columns возвращают по существу тот же диапазон, за исключением того факта, что новый Range имеет флаг, который указывает, что он представляет строки или столбцы. Это необходимо для некоторых свойств Excel, таких как Range.Count и Range.Hidden, а также для некоторых методов, таких как Range.AutoFit():

  • Range.Rows.Count возвращает количество строк в диапазоне.
  • Range.Columns.Count возвращает количество столбцов в диапазоне.
  • Range.Rows.AutoFit() autofits строки в Range.
  • Range.Columns.AutoFit() автоподтверждает столбцы в Range.

Вы можете обнаружить, что Range.EntireRow и Range.EntireColumn полезны, хотя они все еще не совсем то, что вы ищете. Они возвращают все возможные столбцы для EntireRow и всех возможных строк для EntireColumn для представленного диапазона.

Я знаю это, потому что SpreadsheetGear для .NET поставляется с .NET API, которые очень похожи на API Excel. API SpreadsheetGear поставляется с несколькими сильно типизированными перегрузками для индексатора IRange, включая тот, который вы, вероятно, пожелаете Excel:

  • IRange this[int row1, int column1, int row2, int column2];

Отказ от ответственности: у меня есть SpreadsheetGear LLC

  • 2
    essentially the same Range... пропускает ценную часть этих свойств, которая заключается в том, что они предоставляют новый итератор для циклов For Each который проходит через Range ряд за строкой или столбец за столбцом. Смотрите ответ Нила для справки. Это очень эффективно в сочетании со специальными SpecialCells или другими прерывистыми диапазонами (например, из AutoFilter ). Конкретный пример: быстрое применение раскрашенной строки для видимых данных после AutoFilter когда у вас нет Table .
7

Range.Rows, Range.Columns и Range.Cells - это объекты Excel.Range, в соответствии с функциями VBA Type():

? TypeName (Selection.rows)
Ассортимент
Однако это не вся история: те возвращенные объекты являются расширенными типами, которые наследуют каждое свойство и метод из Excel:: Range - но .Columns и .Rows имеют специальное значение для... Каждый итератор и специальное свойство .Count, которое aren 't совершенно так же, как итератор родительского объекта Range и count.

Итак. Cells повторяется и учитывается как набор диапазонов с одной ячейкой, как и итератор по умолчанию родительского диапазона.

Но. Колонки повторяются и подсчитываются как набор вертикальных поддиапазонов, каждый из которых имеет ширину в один столбец;

... И .Rows повторяется и подсчитывается как набор горизонтальных поддиапазонов, каждый из которых имеет высоту в одну строку.

Самый простой способ понять это - пройти этот код и посмотреть, что выбрали:

Открытый Sub Test() 

Для каждого поддиапазона в ParentRange.Rows   SubRange.Select Следующий
Для каждого поддиапазона в ParentRange.Columns   SubRange.Select Следующий
Для каждого поддиапазона в ParentRange   SubRange.Select Следующий
End Sub
Наслаждаться. И попробуйте с помощью пары объединенных ячеек, чтобы увидеть, как могут быть нечетные объединенные диапазоны.
  • 4
    Это недостающая часть от всех ответов , которые говорят , « Rows и Columns являются одинаковыми , за исключением Count ». Возможность перебирать строки и столбцы диапазона без учета того, как был создан Range , очень мощная. Он обеспечивает очень чистый способ итерации ячеек, который избегает логики типа Cells(i,j) внутри циклов. Это также хорошо работает с прерывистыми диапазонами, которые могут возникнуть в определенных сценариях.
6

Ваши два примера - это единственные вещи, которые я когда-либо использовал для свойств Rows и Columns, но в теории вы могли бы сделать с ними что-нибудь, что можно сделать с помощью объекта Range.

Возвращаемый тип этих свойств сам является Range, поэтому вы можете делать такие вещи, как:

Dim myRange as Range
Set myRange = Sheet1.Range(Cells(2,2),Cells(8,8))
myRange.Rows(3).Select

который выберет третью строку в myRange (ячейки B4: H4 в Sheet1).

update: Чтобы сделать то, что вы хотите сделать, вы можете использовать:

Dim interestingRows as Range
Set interestingRows = Sheet1.Range(startRow & ":" & endRow)

update # 2: Или, чтобы получить подмножество строк из другого диапазона:

Dim someRange As Range
Dim interestingRows As Range

Set myRange = Sheet1.Range(Cells(2, 2), Cells(8, 8))

startRow = 3
endRow = 6

Set interestingRows = Range(myRange.Rows(startRow), myRange.Rows(endRow))
  • 0
    Я знал, что он вернул диапазон (упомянул об этом в моем исходном сообщении) и что есть другие способы получить диапазон строк (также упоминается). Что я спрашиваю, в частности, что мы получаем от .Rows (), что мы еще не получаем от .Cells () и .Range ()? Я уточню это в моем вопросе ...
  • 0
    Боюсь, это все. Свойства Rows и Columns - это просто быстрый способ получить доступ к объектам Range, в которых удобно установить отдельные строки (или отдельные столбцы) исходного диапазона. В этом нет больше магии, чем это.
Показать ещё 4 комментария
3

Поскольку результат .Rows помечен как состоящий из строк, вы можете "Для каждого" его обрабатывать каждую строку отдельно, например:

Function Attendance(rng As Range) As Long
Attendance = 0
For Each rRow In rng.Rows
    If WorksheetFunction.Sum(rRow) > 0 Then
        Attendance = Attendance + 1
    End If
Next
End Function

Я использую это для проверки посещаемости в любой из нескольких категорий (разные столбцы) для списка людей (разные строки).

(И, конечно же, вы можете использовать .Columns для выполнения "Для каждого" по столбцам в диапазоне.)

2

Я обнаружил, что использую range.Rows для его эффектов в методе Copy. Он копирует высоту строк из начала координат в пункт назначения, что является поведением, которое я хочу.

rngLastRecord.Rows.Copy Destination:=Sheets("Availability").Range("a" & insertRow)

Если бы я использовал rngLastRecord.Copy вместо rngLastRecord.Rows.Copy, высота строк была бы тем, что было там до копии.

2

Я не уверен, но я думаю, что вторым параметром является красная селедка.

Оба .Rows и .Columns берут два необязательных параметра: RowIndex и ColumnIndex. Попробуйте использовать ColumnIndex, например. Rows(ColumnIndex:=2) генерирует ошибку для обоих .Rows и .Columns.

Мое ощущение, что оно унаследовано в некотором смысле от свойства Cells(RowIndex,ColumnIndex), но подходит только первый параметр.

  • 5
    Чувства, не более чем чувства -1
  • 2
    @ Жан-Франсуа Корбетт - Иногда это единственные ответы, которые вы можете получить, и лучше иметь анекдоты людей, которые были в этой области, чем вообще ничего. Я, вероятно, не стал бы публиковать что-то подобное в эти дни (ответ 2 года !!) - это слишком неопрятно, и я абсолютно не могу постить что-то, что имеет мало надежды на голоса. Вопросы VBA вообще не зарабатывают много репутации. Но я бы категорически не согласился с вашим утверждением, что «ответы, основанные на чувствах, неправильны» просто потому, что это закрывает дискуссию по вопросам, на которые нет очевидных или простых ответов.
Показать ещё 1 комментарий
1

Я нашел, что это работает:

Rows(CStr(iVar1) & ":" & CStr(iVar2)).Select
  • 0
    AFAIK, это работает для .Cells тоже.
  • 1
    @RBarryYoung Rows Rows(Cstr(iVar1) & ":" & CStr(iVar2)) безусловно, не совпадает с Cells(Cstr(iVar1) & ":" & CStr(iVar2)) . Последнее приводит к ошибке несоответствия типов.
1

Возможно, это битка, но следующий код делает то, что вы, похоже, хотите сделать:

Set rng = wks.Range(wks.Rows(iStartRow), wks.Rows(iEndRow)).Rows
  • 0
    +1. Это способ сделать это.
  • 1
    Да, я знаю. Не тот вопрос, который я задал.
Показать ещё 2 комментария
0

Есть другой способ: возьмите это как пример

Dim sr As String    
sr = "6:10"
Rows(sr).Select

Все, что вам нужно сделать, это преобразовать переменные iStartRow, iEndRow в строку.

Ещё вопросы

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