Мне нужен совет более опытных людей в некоторых ситуациях, с которыми я сталкиваюсь. У меня есть данные тестового образца в следующей таблице.
hello good day today
hello good day today
hello good day today
hello good day today
hello good day today
hello good day today
hello good day today
today
today
Я использовал 4 способа определения диапазона согласно следующему коду, а также последнюю ячейку методом FIND
.
Sub test()
Dim ws As Worksheet
Dim myRange As Range
Dim myRange1 As Range
Dim myRange2 As Range
Dim rLastCell As Range
Set ws = ThisWorkbook.ActiveSheet
With ws
Set myRange = .Range(.Cells(1, 1), .Range("A1").SpecialCells(xlCellTypeLastCell))
Debug.Print ws.Name, myRange.Address
'set range with used area
Set myRange1 = ws.UsedRange
Debug.Print ws.Name, myRange1.Address
'set range with currentegion
Set myRange2 = .Range("A1").CurrentRegion
Debug.Print ws.Name, myRange2.Address
' finding lastcell and then set range
Set rLastCell = ActiveSheet.Cells.Find(What:="*", After:=.Cells(1, 1), LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)
Debug.Print rLastCell.Address
End With
End Sub
Результаты Debug.Print
Book1 $A$1:$D$11
Book1 $A$1:$D$11
Book1 $A$1:$D$6
$D$11
Мой конкретный запрос заключается в том, что по методам UsedRange
, SpecialCells(xlCellTypeLastCell)
и FIND
я получаю одинаковые результаты. Хотя использование этих или других подходов зависит от конкретной ситуации, но, учитывая эту конкретную ситуацию с данными, оправдано предпочтение предпочтительного метода для конкретного метода.
РЕДАКТИРОВАТЬ:
Основываясь на комментариях @ VBasic2008 и отличной статье, на которую ссылается @ QHarr, я склонен принять определение диапазона в общих ситуациях, следуя методологии. Я хотел бы найти «Последнюю строку» и «Последний столбец» диапазона, использующего функцию «Последний», предложенную в Рон де Брюин Арикль . Диапазон будет установлен на основе значений якорной ячейки, последней строки и последнего столбца. Код следует за мной следующим образом.
Sub Range_Detrmine()
Dim ws As Worksheet
Dim LastRow As Long
Dim LastCol As Long
Dim rng As Range
Dim Frng As Range
Set ws = ThisWorkbook.ActiveSheet
With ws
' Use all cells on the sheet
Set rng = .Cells
' Find the last row
LastRow = Last(1, rng)
LastCol = Last(2, rng)
Set Frng = .Range(.Cells(1, 1), .Cells(LastRow, LastCol))
Debug.Print LastRow & ":"; LastCol
Debug.Print ws.Name, Frng.Address
End With
End Sub
Function Last(choice As Long, rng As Range)
'Ron de Bruin, 5 May 2008
' 1 = last row
' 2 = last column
' 3 = last cell
Dim lrw As Long
Dim lcol As Long
Select Case choice
Case 1:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
On Error Resume Next
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
On Error Resume Next
Last = rng.Parent.Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
Last = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
End Select
End Function
Я протестировал приведенный выше код для некоторых примеров ситуаций согласно приложенным снимкам. Я проверил правильность диапазона, определенного до удаления отформатированной строки и после удаления отформатированной строки. Также в случае применения фильтра он дает правильный диапазон, даже если флажки фильтра видны в строке заголовка в Column H


Debug.Print LastRow & ":"; LastCol
Debug.Print ws.Name, Frng.Address
Результаты до и после изменения диапазона:
17: 8
Sheet1 $A$1:$H$17
14: 7
Sheet2 $A$1:$G$14
Я хотел бы знать, есть ли некоторые предостережения в отношении этого подхода.