Excel 使用不同工作簿的通用函数过程

Excel 使用不同工作簿的通用函数过程,excel,function,procedure,vba,Excel,Function,Procedure,Vba,我正在尝试更好的编码实践和使用泛型函数。 我正在使用主文件中的几个工作簿。 例如,如果我想得到最后一行,我将使用下面的代码行 LastRow=Range("A" & Rows.Count).End(xlUp).Row 要使用函数检索值,我构建函数: -职能1 Function GetLastRow() As Integer GetLastRow = Range("A" & Rows.Count).End(xlUp).Row End Function 现在,从我的subma

我正在尝试更好的编码实践和使用泛型函数。
我正在使用主文件中的几个工作簿。 例如,如果我想得到最后一行,我将使用下面的代码行

LastRow=Range("A" & Rows.Count).End(xlUp).Row 
要使用函数检索值,我构建函数:

-职能1

Function GetLastRow() As Integer
GetLastRow = Range("A" & Rows.Count).End(xlUp).Row
End Function 
现在,从我的
submain()
中,我想对不同的工作簿或工作表使用
GetLastRow()
。我认为在调用我的函数之前激活工作簿不是一件好事

然后,我是否应将工作簿名称和工作表编号每次传输到我的函数,并将我的函数更改为:

-职能2

Function GetLastRowIn(sWb As String, iWs As Integer) As Integer
GetLastRowIn = Workbooks(sWb).Worksheets(iWs).Range("A" & Rows.Count).End(xlUp).Row
End Function
或者是否有更好/更简单的方法来传输工作簿和工作表,在其中我希望应用函数,同时保持函数1中没有参数


谢谢你的回答

要使函数更通用,可以考虑一些灵活性,
但也会对函数调用施加一些规则


通用功能

Option Explicit

Public Function GetLastRow(ByRef ws As Worksheet, Optional ByVal fromCol As Long = 1) As Long
    Dim invalidWS As Boolean, lastRow As Long

    If Not ws Is Nothing Then   'check 1st param

        On Error Resume Next    'check that ws reference is valid (delted WS invalidates ws)
            invalidWS = Len(ws.Name) > 0
            invalidWS = Err.Number <> 0  'No error if Err.Number = 0
        On Error GoTo 0

        If Not invalidWS Then
            If fromCol > 0 And fromCol <= ws.Columns.Count Then 'validate 2nd param
                lastRow = ws.Cells(ws.Rows.Count, fromCol).End(xlUp).Row
                'check if WS.fromCol is empty
                If lastRow = 1 And Len(ws.Cells(1, fromCol)) = 0 Then lastRow = 0
            End If
        End If
    End If
    GetLastRow = lastRow
End Function

  • 始终使用
    选项Explicit
    ,以允许编译器捕获变量名中的拼写错误
  • 验证所有输入
    • 函数调用可能不包含有效的工作表或列号
  • 允许通过代码名、WS-Index或WS-Name(字符串)指定工作表
  • 通过对第二个参数使用Optional,允许使用默认列ID
  • 强制调用以仅发送工作表对象作为第一个参数
    • 如果接受字符串,则需要首先检查工作表(“无效”)是否存在
  • 按索引强制调用请求列
    • 如果允许列ID中包含字符串,则需要检查字符串是否介于“A”和“XFD”之间
      • 字符串长度介于1和3之间,也不允许使用“XYZ”之类的字符串
      • 这需要一个单独的函数来检查字符串中的每个字母
      • 如果MS决定增加最大列数,字符串还可能带来更多维护
  • 使函数只用于一个目的(就像您所做的那样)-以后不要包含其他功能
  • 该函数应该是自包含的
    • 能够检测和处理所有可能的错误和意外输入
    • 并生成最通用和可用的输出
  • 通过在此特定函数中返回0,期望有效数字的调用将在第0行出错
    • 因此,即使工作表为空,您也可能希望将其更改为返回1
      • 并在呼叫返回后检查顶部单元格是否为空
请注意:

主文件中的多个工作簿

  • 工作簿是一个文件
  • 工作表是文件中的选项卡(一个文件可以包含多个工作表/选项卡)
  • 对所有对象始终保持显式
    • Range(“A”&Rows.Count).End(xlUp).Row
      隐式使用
      ActiveWorkbook.ActiveSheet
    • 转换为
      ActiveWorkbook.ActiveSheet.Range(“A”&Rows.Count).End(xlUp).Row
    • 如果您需要使用多个工作簿和工作表,请完全限定您的呼叫
      • `工作簿(“Book1”)。工作表(“Sheet3”)。范围(“A”和行数。计数)。结束(xlUp)。行
      • `工作簿(“Book2”)。工作表(“Sheet2”)。范围(“A”和行数。计数)。结束(xlUp)。行
    • 因此Excel可以访问您需要使用的确切对象
如果使用完全引用,则代码不依赖于活动对象 -如果用户激活了不同的工作簿或工作表,代码将继续工作,不会出现错误

希望这有帮助


注:当使用行变量时,始终将它们声明为
Long
以便能够处理大于32767的整数最大值-当前Excel的最大行数为1048576行(将来该最大行数可能会增加得更高)

为了使函数更通用,您可以考虑一些灵活性,
但也会对函数调用施加一些规则


通用功能

Option Explicit

Public Function GetLastRow(ByRef ws As Worksheet, Optional ByVal fromCol As Long = 1) As Long
    Dim invalidWS As Boolean, lastRow As Long

    If Not ws Is Nothing Then   'check 1st param

        On Error Resume Next    'check that ws reference is valid (delted WS invalidates ws)
            invalidWS = Len(ws.Name) > 0
            invalidWS = Err.Number <> 0  'No error if Err.Number = 0
        On Error GoTo 0

        If Not invalidWS Then
            If fromCol > 0 And fromCol <= ws.Columns.Count Then 'validate 2nd param
                lastRow = ws.Cells(ws.Rows.Count, fromCol).End(xlUp).Row
                'check if WS.fromCol is empty
                If lastRow = 1 And Len(ws.Cells(1, fromCol)) = 0 Then lastRow = 0
            End If
        End If
    End If
    GetLastRow = lastRow
End Function

  • 始终使用
    选项Explicit
    ,以允许编译器捕获变量名中的拼写错误
  • 验证所有输入
    • 函数调用可能不包含有效的工作表或列号
  • 允许通过代码名、WS-Index或WS-Name(字符串)指定工作表
  • 通过对第二个参数使用Optional,允许使用默认列ID
  • 强制调用以仅发送工作表对象作为第一个参数
    • 如果接受字符串,则需要首先检查工作表(“无效”)是否存在
  • 按索引强制调用请求列
    • 如果允许列ID中包含字符串,则需要检查字符串是否介于“A”和“XFD”之间
      • 字符串长度介于1和3之间,也不允许使用“XYZ”之类的字符串
      • 这需要一个单独的函数来检查字符串中的每个字母
      • 如果MS决定增加最大列数,字符串还可能带来更多维护
  • 使函数只用于一个目的(就像您所做的那样)-以后不要包含其他功能
  • 该函数应该是自包含的
    • 能够检测和处理所有可能的错误和意外输入
    • 并生成最通用和可用的输出
  • 通过在此特定函数中返回0,期望有效数字的调用将在第0行出错
    • 因此,即使工作表为空,您也可能希望将其更改为返回1
      • 并在呼叫返回后检查顶部单元格是否为空
请注意:

主文件中的多个工作簿

  • 工作簿是一个文件
  • 工作表是文件中的选项卡(一个文件可以包含多个工作表/选项卡)
  • 对所有对象始终保持显式
    • 范围(“A”&