获得实际使用范围

时间:2011-09-14 21:09:30

标签: excel vba excel-vba

我有一个带有按钮的Excel工作表。

当我调用usedRange()函数时,它返回的范围包括按钮部分。

无论如何,我可以获得包含数据的实际使用范围吗?

9 个答案:

答案 0 :(得分:32)

什么样的按钮,表单控件和ActiveX控件都不应该影响使用的范围。

一个已知问题是excel不能很好地跟踪使用范围。通过VBA对使用范围的任何引用都会将值重置为当前使用的范围。所以尝试运行这个子程序:

Sub ResetUsedRng()
    Application.ActiveSheet.UsedRange 
End Sub 

如果不这样你可能会有一些格式悬而​​未决。尝试清除/删除最后一行之后的所有单元格。

关于上述内容,请参阅:

Excel Developer Tip

查找上次使用过的单元格的另一种方法:

    Dim rLastCell As Range

    Set rLastCell = ActiveSheet.Cells.Find(What:="*", After:=.Cells(1, 1), LookIn:=xlFormulas, LookAt:= _
    xlPart, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False)

更改搜索方向以查找第一个使用过的单元格。

答案 1 :(得分:20)

Readify做了一个非常完整的答案。但是,我想添加End语句,您可以使用:

在列中的空白之前找到最后使用过的单元格:

Sub LastCellBeforeBlankInColumn()
Range("A1").End(xldown).Select
End Sub

找到列中最后一个使用过的单元格:

Sub LastCellInColumn()
Range("A" & Rows.Count).End(xlup).Select
End Sub

在行中的空白之前找到最后一个单元格:

Sub LastCellBeforeBlankInRow()
Range("A1").End(xlToRight).Select
End Sub

找到行中最后一个使用过的单元格:

Sub LastCellInRow()
Range("IV1").End(xlToLeft).Select
End Sub

有关详细信息,请参阅here(并解释xlCellTypeLastCell不可靠的原因。)

答案 2 :(得分:5)

这是一对函数,用于根据Reafidy上面的解决方案返回工作表的最后一行和第一行。

    Function LastRow(ws As Object) As Long

        Dim rLastCell As Object
        On Error GoTo ErrHan
        Set rLastCell = ws.Cells.Find("*", ws.Cells(1, 1), , , xlByRows, _
                                      xlPrevious)
        LastRow = rLastCell.Row

    ErrExit:
        Exit Function

    ErrHan:
        MsgBox "Error " & Err.Number & ": " & Err.Description, _
               vbExclamation, "LastRow()"
        Resume ErrExit

    End Function

    Function LastCol(ws As Object) As Long

        Dim rLastCell As Object
        On Error GoTo ErrHan
        Set rLastCell = ws.Cells.Find("*", ws.Cells(1, 1), , , xlByColumns, _
                                      xlPrevious)
        LastCol = rLastCell.Column

    ErrExit:
        Exit Function

    ErrHan:
        MsgBox "Error " & Err.Number & ": " & Err.Description, _
               vbExclamation, "LastRow()"
        Resume ErrExit

    End Function

答案 3 :(得分:3)

Public Sub FindTrueUsedRange(RowLast As Long, ColLast As Long)
    Application.EnableEvents = False
    Application.ScreenUpdating = False
    RowLast = 0
    ColLast = 0
    ActiveSheet.UsedRange.Select
    Cells(1, 1).Activate
    Selection.End(xlDown).Select
    Selection.End(xlDown).Select
    On Error GoTo -1: On Error GoTo Quit
    Cells.Find(What:="*", LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Activate
    On Error GoTo -1: On Error GoTo 0
    RowLast = Selection.Row
    Cells(1, 1).Activate
    Selection.End(xlToRight).Select
    Selection.End(xlToRight).Select
    Cells.Find(What:="*", LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Activate
    ColLast = Selection.Column
Quit:
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    On Error GoTo -1: On Error GoTo 0
End Sub

答案 4 :(得分:3)

此功能将实际使用的范围返回到右下限。如果工作表为空,则返回“ Nothing”。

'2020-01-26
Function fUsedRange() As Range
Dim lngLastRow As Long
Dim lngLastCol As Long
Dim rngLastCell As Range
    On Error Resume Next
    Set rngLastCell = ActiveSheet.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious)
    If rngLastCell Is Nothing Then  'look for data backwards in rows
        Set fUsedRange = Nothing
        Exit Function
    Else
        lngLastRow = rngLastCell.Row
    End If
    Set rngLastCell = ActiveSheet.Cells.Find("*", searchorder:=xlByColumns, searchdirection:=xlPrevious)
    If rngLastCell Is Nothing Then  'look for data backwards in columns
        Set fUsedRange = Nothing
        Exit Function
    Else
        lngLastCol = rngLastCell.Column
    End If
    Set fUsedRange = ActiveSheet.Range(Cells(1, 1), Cells(lngLastRow, lngLastCol))  'set up range
End Function

答案 5 :(得分:0)

我使用以下vba代码确定工作表的整个已用行范围,然后缩短列的选定范围:

    Set rUsedRowRange = Selection.Worksheet.UsedRange.Columns( _
    Selection.Column - Selection.Worksheet.UsedRange.Column + 1)

另一种方式也是如此:

    Set rUsedColumnRange = Selection.Worksheet.UsedRange.Rows( _
    Selection.Row - Selection.Worksheet.UsedRange.Row + 1)

答案 6 :(得分:0)

此功能给出了使用范围的所有4个限制:

Function FindUsedRangeLimits()
    Set Sheet = ActiveSheet
    Sheet.UsedRange.Select

    ' Display the range's rows and columns.
    row_min = Sheet.UsedRange.Row
    row_max = row_min + Sheet.UsedRange.Rows.Count - 1
    col_min = Sheet.UsedRange.Column
    col_max = col_min + Sheet.UsedRange.Columns.Count - 1

    MsgBox "Rows " & row_min & " - " & row_max & vbCrLf & _
           "Columns: " & col_min & " - " & col_max
    LastCellBeforeBlankInColumn = True
End Function

答案 7 :(得分:0)

Excel 2013上的计时相当慢,使用范围大到百万行:

26ms Cells.Find xlPrevious方法(如上所述)

0.4ms Sheet.UsedRange(只需调用它)

0.14毫秒Counta二进制搜索+ 0.4毫秒用于启动搜索的范围(12个CountA调用)

因此,如果担心的话,Find xlPrevious非常慢。

CountA二进制搜索方法是首先执行“已用范围”。然后将范围切成两半,看看下半部分是否有任何非空单元格,然后根据需要再次减半。正确是很难的。

答案 8 :(得分:0)

这是另一个。它查找第一个和最后一个非空单元格,并且构建范围在这些范围内。这也处理您的数据不是矩形并且不是从 A1 开始的情况。此外,它还处理合并的单元格,当从宏执行时 .Find 跳过,在工作表上的 .Cells 上使用。

Function getUsedRange(ByRef sheet As Worksheet) As Range
' finds used range by looking for non empty cells
' works around bug in .Find that skips merged cells
' by starting at with the UsedRange (that may be too big)

' credit to https://contexturesblog.com/archives/2012/03/01/select-actual-used-range-in-excel-sheet/
' for the .Find commands

Dim excelsUsedRange As Range
Dim lastRow As Long
Dim lastCol As Long
Dim lastCell As Range
Dim firstRow As Long
Dim firstCol As Long
Dim firstCell As Range

Set excelsUsedRange = ActiveSheet.UsedRange

lastRow = excelsUsedRange.Find(What:="*", _
                               LookIn:=xlValues, SearchOrder:=xlRows, _
                               SearchDirection:=xlPrevious).Row
lastCol = excelsUsedRange.Find(What:="*", _
                               LookIn:=xlValues, SearchOrder:=xlByColumns, _
                               SearchDirection:=xlPrevious).Column
Set lastCell = sheet.Cells(lastRow, lastCol)

firstRow = excelsUsedRange.Find(What:="*", After:=lastCell, _
                                LookIn:=xlValues, SearchOrder:=xlRows, _
                                SearchDirection:=xlNext).Row
firstCol = excelsUsedRange.Find(What:="*", After:=lastCell, _
                                LookIn:=xlValues, SearchOrder:=xlByColumns, _
                                SearchDirection:=xlNext).Row
Set firstCell = sheet.Cells(firstRow, firstCol)
Set getUsedRange = sheet.Range(firstCell, lastCell)
End Function