【问题标题】:VBA - Using Current Selection As Range ObjectVBA - 使用当前选择作为范围对象
【发布时间】:2019-02-20 18:02:45
【问题描述】:

我在下面有这个函数,它执行以下操作:

  1. 采用两个参数(标题名称、所需功能)。
  2. 标题名称参数用于查找标题,随后用于标识该列直到最后一行的范围。
  3. Function Needed 参数用于在 select 语句中切换所需的任何其他步骤。
  4. 在大多数语句的末尾,我执行Range.Select 然后退出我的函数并选择一个范围。

代码如下:

Function find_Header(header As String, fType As String)
    Dim aCell As Range, rng As Range
    Dim col As Long, lRow As Long
    Dim colName As String

    With ActiveSheet
        Set aCell = .Range("B2:J2").Find(What:=header, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False)

        'If Found
        If Not aCell Is Nothing Then
            col = aCell.Column
            colName = Split(.Cells(, col).Address, "$")(1)

            lRow = Range(colName & .Rows.count).End(xlUp).Row + 1

            Set myCol = Range(colName & "2")

            Select Case fType
                Case "Copy"
                    'This is your range
                    Set rng = Range(myCol.Address & ":" & colName & lRow).Offset(1, 0)

                    rng.Select
            End Select

        'If not found
        Else
            MsgBox "Column Not Found"
        End If
    End With

End Function

当我试图清理我的代码时,我遇到了一个我有专门硬编码范围的部分,我正在尝试使用我的函数,但是,我现在处于无法正确使用此功能,因为我无法将范围“传递”回 sub,而且我似乎无法选择 sub 所需的范围对象。

下面是 sub 中的内容:

Sub Copy_Failed()
    Dim xRg As Range, xCell As Range
    Dim i As Long, J As Long, count As Long
    Dim fType As String, colName As String
    Dim y As Workbook
    Dim ws1 As Worksheet, ws2 As Worksheet

    myarray = Array("Defect", "System", "Script")
    myEnv = Array("SIT", "UAT")
    myDefects = Array("New", "Existing")

    i = Worksheets("Run Results").UsedRange.Rows.count
    J = Worksheets("Failed").UsedRange.Rows.count

    Set y = Workbooks("Template.xlsm")

    Set ws1 = y.Sheets("Failed")
    Set ws2 = y.Sheets("Run Results")

    count = 3

    If J = 1 Then

        If Application.WorksheetFunction.CountA(ws1.UsedRange) = 0 Then J = 0

    End If

    ws2.Activate

    fType = "Copy"
    colName = "Status"

    Call find_Header(colName, fType)
End Sub

在我使用这个函数之前,代码是这样的:

lngLastRow = Cells(Rows.count, "B").End(xlUp).Row

Set xRg = ws2.Range("E3:E" & lngLastRow & i)

现在这两行是在函数中执行的,所以我在 sub 中不需要它。我尝试了以下方法:

Set rngMyRange = Selection

Set rngMyRange = ActiveSheet.Range(Selection.Address)

Set xRg = ws2.Range(rngMyRange  & i)

但我得到了错误:

类型不匹配

所以我在想:

  1. 在函数中选择范围,然后在子中使用它——但是如何?
  2. 弄清楚如何将实际范围对象从我的函数传递给子

虽然第二个选项需要对我的代码进行一些额外的更改,但我认为这是更好的选择。

【问题讨论】:

  • 函数应该返回一些东西,一个数字,一个范围,一个字符串等。你只是选择一个单元格,选择永远不会好。返回一个范围对象,然后您可以在其他代码中引用它。
  • @SJR 谢谢你的回复。我已经尝试在上面的 sub 中调用该函数,然后让函数看起来像这样 'find_Header(header As String, fType As String) As Range' 然后回到 sub 我的行看起来像这样 'Set xRg = find_Header & i)' 但我收到错误“Arguments not Optional”。
  • 函数 find_Header(header As String, fType As String) 作为 Range 并在函数末尾添加 find_Header = rng

标签: excel vba


【解决方案1】:

好的,这里有一个插图,你可以明白我的意思。如果您在 B2:J2 某处放置“一个”,它将选择范围。我在这里只使用 Select 以便您可以看到它标识的范围。 (免责声明:我不完全理解您在做什么,并且不确定您是否需要所有这些代码来实现您想要的。)

函数现在返回一个范围变量,并分配给r。运行程序x

Sub x()

Dim r As Range

Set r = Range("a1", find_Header("one", "Copy"))
r.Select

End Sub

Function find_Header(header As String, fType As String) As Range

Dim aCell As Range, rng As Range
Dim col As Long, lRow As Long
Dim colName As String

With ActiveSheet
    Set aCell = .Range("B2:J2").Find(What:=header, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False, SearchFormat:=False)
    'If Found
    If Not aCell Is Nothing Then
        col = aCell.Column
        colName = Split(.Cells(, col).Address, "$")(1)
        lRow = Range(colName & .Rows.Count).End(xlUp).Row + 1
        Set myCol = Range(colName & "2")
        Select Case fType
            Case "Copy"
                'This is your range
                Set find_Header = Range(myCol.Address & ":" & colName & lRow).Offset(1, 0)
            End Select
    'If not found
    Else
        Set find_Header = Nothing
    End If

End With

End Function

【讨论】:

  • 啊,进步了!! :) 所以我现在面临的问题是它选择从单元格 A1 开始直到正确列的最后一个单元格的范围。例如,我只需要使用 D 列,单元格 D3:D30,但现在我得到 A1:D30
  • 要添加到这个,使用它的下一行 {Set xRg = ws2.Range(rngMyRange & i)} 我得到一个错误“类型不匹配”
  • 那只是因为我在Set r = Range("a1", find_Header("one", "Copy"))这一行中指定了A1。 D3:D30 是 Find_Header 返回的范围吗?
  • OK 所以你可以在你的主程序中直接引用find_Header("one", "Copy"),例如find_Header("one", "Copy").select,因为函数返回那个范围对象。
  • 谢谢。我会检查的:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2014-12-17
  • 1970-01-01
相关资源
最近更新 更多