Что действительно делает свойство range.Rows в Excel? - PullRequest
59 голосов
/ 24 июня 2009

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

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

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

   SET rng = wks.Rows(iStartRow, iEndRow)

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

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

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

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

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

Ответы [ 9 ]

52 голосов
/ 24 июня 2009

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

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

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

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

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

Отказ от ответственности: я владею SpreadsheetGear LLC

9 голосов
/ 30 апреля 2014

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

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

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

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

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

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

Public Sub Test() 
Dim SubRange As Range Dim ParentRange As Range
Set ParentRange = ActiveSheet.Range("B2:E5")

For Each SubRange In ParentRange.Cells SubRange.Select Next
For Each SubRange In ParentRange.Rows SubRange.Select Next
For Each SubRange In ParentRange.Columns SubRange.Select Next
For Each SubRange In ParentRange SubRange.Select Next
End Sub
Наслаждаться. И попробуйте сделать это с парой слитых ячеек, просто чтобы увидеть, каким может быть нечетный объединенный диапазон.
7 голосов
/ 24 июня 2009

Ваши два примера - единственные вещи, для которых я когда-либо использовал свойства 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 на листе 1).

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

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

обновление # 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))
3 голосов
/ 07 марта 2014

Поскольку результат .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 голосов
/ 29 июня 2011

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

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

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

2 голосов
/ 24 июня 2009

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

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

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

1 голос
/ 16 сентября 2012

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

Rows(CStr(iVar1) & ":" & CStr(iVar2)).Select
1 голос
/ 12 марта 2010

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

Set rng = wks.Range(wks.Rows(iStartRow), wks.Rows(iEndRow)).Rows
0 голосов
/ 24 декабря 2010

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

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

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

...