通过一个函数识别两个不同的列

时间:2019-03-08 06:03:37

标签: excel vba

这是可以通过标题识别列的函数:

Function find_Col(header As String) As Range

    Dim aCell As Range, rng As Range
    Dim col As Long, lRow As Long
    Dim colName As String
    Dim y As Workbook
    Dim ws1 As Worksheet

    Set y = Workbooks("Template.xlsm")

    Set ws1 = y.Sheets("Results")

    With ws1

        Set aCell = Cells.Find(what:=header, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)

        col = aCell.Column
        colName = Split(.Cells(, col).Address, "$")(1)

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

        Set myCol = Range(colName & "2")

        'This is your range
        Set find_Col = Range(myCol.Address & ":" & colName & lRow)

        find_Col.Select

    End With

End Function

然后我在子程序中调用该函数:

Sub myCol_Find()

    find_Col ("Product")

End Sub

上面的方法工作正常,但是我面临的问题是,如果我要搜索的列几乎是空白,不包括标题,那么我的函数将只选择标题下的前两行。同样,第二个问题是,它也选择了最后一行之后的行。因此,如果标题下的第一行是B3,而最后一行是B10,则会选择B3:B11

因此,我认为先确定其中有数据的列(我知道它将始终有数据),然后使用此列查找数据的最后一行,也许会更好。最后使用我需要选择的实际列。

所以我首先通过更改此行进行了测试:

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

对此:

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

这会根据在A列中找到的总行选择我搜索的列中的所有单元格。

然后,我想而不是专门为列命名,而是应用“查找”列以找到“列A”的相同逻辑。所以我有这个:

Function find_Col(header As String) As Range

    Dim aCell As Range, rng As Range, def_Header As Range
    Dim col As Long, lRow As Long, defCol As Long
    Dim colName As String, defColName As String
    Dim y As Workbook
    Dim ws1 As Worksheet

    Set y = Workbooks("Template.xlsm")

    Set ws1 = y.Sheets("Results")

    With ws1

        Set def_Header = Cells.Find(what:="ID", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)

        defCol = def_Header.Column
        defColName = Split(.Cells(, def_Col).Address, "$")(1)

        Set aCell = Cells.Find(what:=header, LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)

        col = aCell.Column
        colName = Split(.Cells(, col).Address, "$")(1)

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

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

        Set myCol = Range(colName & "2")

        'This is your range
        Set find_Col = Range(myCol.Address & ":" & colName & lRow)

        find_Col.Select

    End With

End Function

添加了其他代码:

Dim def_Header As Range
Dim defCol As Long
Dim defColName As String

Set def_Header = Cells.Find(what:="KW_ID", LookIn:=xlValues, lookat:=xlWhole, MatchCase:=False, SearchFormat:=False)

defCol = def_Header.Column
defColName = Split(.Cells(, defCol).Address, "$")(1)

并对此进行了更改:

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

对此:

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

现在,我在一行中遇到错误:

defCol = def_Header.Column

错误:

  

未设置With块变量的对象变量

我不太清楚问题出在哪里,因为以前在定义aCell时没有给我这个错误。

所以目前,我面临两个问题:

  1. 选择正在选择一个多余的单元格
  2. 我不知道为什么会收到上述错误

1 个答案:

答案 0 :(得分:2)

这应该有效:

EDIT:已更新,以处理发现标题但没有数据的情况

Function find_Col(header As String) As Range

    Dim aCell As Range, bCell As Range, rng As Range

    With Workbooks("Template.xlsm").Sheets("Results")

        Set aCell = .Cells.Find(what:=header, LookIn:=xlValues, lookat:=xlWhole, _
                                 MatchCase:=False, SearchFormat:=False)

        If Not aCell Is Nothing Then
            Set aCell = aCell.Offset(1, 0)
            Set bCell = .Cells(.Rows.Count, aCell.Column).End(xlUp)
            If bCell.Row > aCell.Row Then
                Set rng = .Range(aCell, bCell)  'column has some content
            Else
                Set rng = aCell 'or nothing?     'column has no content...
            End If
        End If      
    End With

    Set find_col = rng
End Function