【问题标题】:Custom Function using a Sheet name as a parameter使用工作表名称作为参数的自定义函数
【发布时间】:2012-11-04 04:12:27
【问题描述】:

我有这样的功能:

Function GetLastRowOnSheet(ByVal SheetName As Worksheet) As Long
    On Error Resume Next
    GetLastRowOnSheet = SheetName.Cells.Find(what:="*", after:=SheetName.Cells(1),     searchorder:=xlByRows, searchdirection:=xlPrevious).Row
    On Error GoTo 0
End Function

假设我有一个名为“Sheet1”的工作表,在我的 excel 工作表中,我希望能够说 =GetLastRowOnSheet('Sheet1') 或使用 命名范围

我可以在 vba 中使用上面的函数以及包含此函数的子例程或函数轻松地做到这一点:

Dim Sheet1 As Worksheet
Dim LastRow as Long
Set Sheet1 = ThisWorkbook.Sheets("Sheet1")
LastRow = GetLastRowOnSheet(Sheet1)

' last row then returns the last filled in cell on the sheet

想法?

【问题讨论】:

    标签: vba excel excel-2007 excel-formula excel-2010


    【解决方案1】:

    您需要改用此代码:

    Function GetLastRowOnSheet(ByVal SheetName As String) As Long
        Dim wks As Worksheet
    
        On Error Resume Next
        Set wks = ActiveWorkbook.Worksheets(SheetName)
        GetLastRowOnSheet = wks.Cells.Find(what:="*", after:=wks.Cells(1), searchorder:=xlByRows, searchdirection:=xlPrevious).Row
        On Error GoTo 0
    End Function
    

    我不是 100% 确定,但现在,我非常怀疑是否可以将 Worksheet-Object 作为 Worksheet-Function-Parameter 传递。这就是我改用字符串的原因。

    因为您使用的是Resume Next,所以您不需要检查工作表是否确实存在,但如果不存在,您就必须这样做。

    您现在可以轻松地使用 NAMED-Range,只要它引用 Worksheet-Name。

    编辑

    好的,找到了一种更好的方法来执行此操作,因为动态获取工作表名称作为此工作表函数的输入会很痛苦。没有内置函数可以直接执行此操作 - 至少我找不到。 Cell("address") 将是最接近的。

    Function GetLastRowOnSheet(ByVal SheetName As Range) As Long    
        On Error Resume Next
        With SheetName.Worksheet
          GetLastRowOnSheet = .Cells.Find(what:="*", after:=.Cells(1), searchorder:=xlByRows, searchdirection:=xlPrevious).Row
        end with
        On Error GoTo 0
    End Function
    

    现在您可以使用GetLastRowOnSheet(SheetXY!A1)GetLastRowOnSheet(NAMEDRANGE),这非常简单,并且已经对错误输入提供了一些保护。

    要将它与 VBA 一起使用,您可以像这样使用它:

    Dim LastRow as Long
    LastRow = GetLastRowOnSheet(ThisWorkbook.Sheets("Sheet1").Cells)
    

    【讨论】:

    • 不错的更新,我遇到的唯一另一件事是页面重新计算后公式没有重置......不知道为什么会这样
    • 这是因为,如果您使用SheetYX!A1,那么在您更改 A1 之前,excel 不会知道发生了变化。所以使用SheetXY!A:IV 它应该对任何变化做出反应。
    • 您可以使用其 CodeName 访问它,而不是使用硬编码字符串来引用工作表。因此ThisWorkbook.Sheets("Sheet1").Cells 可能只是Sheet1.Cells,也是硬编码的,但阅读和理解要快得多。
    【解决方案2】:

    您需要使用 Variant 类型而不是 Worksheet。为我工作。

    Function GetLastRowOnSheet(SheetName As Variant) As Long
        On Error Resume Next
        GetLastRowOnSheet = SheetName.Cells.Find(what:="*", after:=SheetName.Cells(1),     searchorder:=xlByRows, searchdirection:=xlPrevious).Row
        On Error GoTo 0
    End Function
    

    【讨论】:

      【解决方案3】:

      工作表 NAME 不是工作表 OBJECT。

      要在有工作表名称时引用工作表对象,可以使用 ThisWorkbook.Sheets(SheetName) 其中 SheetName 是函数参数,并且是字符串类型,而不是工作表类型。

      现在对于一个范围来说,它会有点困难,因为命名范围可以是全局(整个工作簿)级别或本地(仅包含工作表)级别。

      因此,您必须检查这两种可能性,或者更喜欢其中一种(所以首先在本地检查,如果它不存在,则在全局范围内继续),或者允许用户表达他们的偏好或在用户拥有的地方设置第二个参数指定。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-16
        • 2019-03-31
        • 1970-01-01
        • 1970-01-01
        • 2019-01-10
        • 2019-03-11
        相关资源
        最近更新 更多