Вычисление буквы столбца заголовка
Вам потребуется добавить аргумент After
в метод Find
, указывающий на последнюю ячейку .Cells(.Cells.Count)
, чтобы начать поиск с первой ячейки .Cells(1)
.Но, как отметили chris neilsen в комментариях, это не причина, по которой ваш код потерпит неудачу, потому что он найдет Name
в конце поиска.
Поскольку вы не определили, что«не работает» на самом деле означает, и очень маловероятно, что вы ошиблись Name
в A1
, я бы предположил, что NameColumn
возвращает нежелательный результат (<>A
), означающий, что вы использовали Name
где-то ещев первой строке и вам действительно нужно начать поиск с первой ячейки .Cells(1)
.
Короткая версия
Sub FindAfterShort()
Dim NameColumn As String ' Name Column Letter
Dim ScoreColumn As String ' Score Column Letter
With Rows(1)
NameColumn = Split(.Find("Name", .Cells(.Cells.Count), xlValues, _
xlWhole).Address, "$")(1)
ScoreColumn = Split(.Find("Score", .Cells(.Cells.Count), xlValues, _
xlWhole).Address, "$")(1)
End With
Debug.Print "Column Letters '" & NameColumn & "' and '" & ScoreColumn & "'."
End Sub
Предпочтительная версия
Sub FindAfterPref()
Const cSheet As String = "Sheet1" ' Worksheet Name
Dim strName As String ' Name Column Letter
Dim strScore As String ' Score Column Letter
With ThisWorkbook.Worksheets(cSheet).Rows(1)
strName = Split(.Find("Name", .Cells(.Cells.Count), xlValues, _
xlWhole).Address, "$")(1)
strScore = Split(.Find("Score", .Cells(.Cells.Count), xlValues, _
xlWhole).Address, "$")(1)
End With
Debug.Print "Column Letters '" & strName & "' and '" & strScore & "'."
End Sub
A SmallЭтюд
Sub FindAfter()
Const cSheet As String = "Sheet1" ' Worksheet Name
Const cFR As Long = 2 ' First Row
' The column where the Last Row Number will be calculated.
Const cLRColumn As Variant = "A" ' Last-Row Column Letter/Number
Dim rngName As Range ' Name Column Range, Name Range
Dim rngScore As Range ' Score Column Range, Score Range
Dim lngName As Long ' Name Column Number
Dim lngScore As Long ' Score Column Number
Dim strName As String ' Name Column Letter
Dim strScore As String ' Score Column Letter
Dim lngLR As Long ' Last Row Number (Calculated in Last-Row Column)
With ThisWorkbook.Worksheets(cSheet).Rows(1)
' Find Method Arguments
' 2. After: If you want to start the search from the first cell, you
' have to set the After parameter to the last cell. If you
' have the matching data in the first cell and you set the
' parameter to the first cell (default), it will still be
' found, but a little later (not mili, but micro seconds
' later) so it could be omitted.
' 5. SearchOrder: Whenever a range is a one-row or a one-column range,
' this argument can be omitted. Since you're searching
' in a one-row range, "xlByRows" would have been the
' more 'correct' way in this case.
' 6. SearchDirection: This argument's parameter is by default "xlNext"
' and can therefore be omitted
' 7. MatchCase: This argument's parameter is by default "False". Since
' I don't see the reason why you would have headers with
' the same name, especially the ones you don't need
' before the ones you need, it is omitted. If you really
' need it, use "... xlWhole, , , True".
Set rngName = .Find("Name", .Cells(.Cells.Count), xlValues, xlWhole)
Set rngScore = .Find("Score", .Cells(.Cells.Count), xlValues, xlWhole)
' Address Arguments
' If the Address arguments are omitted, Range.Address returns the
' address as an absolute reference e.g. $A$1. When you split
' $A$1 you will get the following
' INDEX STRING
' 0 - Empty string ("").
' 1 A - Use this i.e. index 1 for the split array index.
' 2 1
If Not rngName Is Nothing Then ' When "Name" was found.
' Calculate Name Column Number.
lngName = rngName.Column
' Calculate Name Column Letter.
strName = Split(rngName.Address, "$")(1)
End If
If Not rngScore Is Nothing Then ' When "Score" was found.
' Calculate Score Column Number.
lngScore = rngScore.Column
' Calculate Score Column Letter.
strScore = Split(rngScore.Address, "$")(1)
End If
Debug.Print "Column Numbers '" & lngName & "' and '" & lngScore & "'."
Debug.Print "Column Letters '" & strName & "' and '" & strScore & "'."
Debug.Print "Name Column Header Address '" & rngName.Address & "'."
Debug.Print "Score Column Header Address '" & rngScore.Address & "'."
With .Parent ' instead of "ThisWorkbook.Worksheets(cSheet)".
'*******************************************************************
' This should demonstrate a case where you don't need the column
' letter (mostly you don't). You should use ".Cells", ".Range" is
' not an option.
'*******************************************************************
' Column Number (lngName)
' Last Row Number calculated using Cells and lngName.
If lngName <> 0 Then
' Calculate last row in Name Column.
lngLR = .Cells(.Rows.Count, lngName).End(xlUp).Row
' Create a reference to the range from First Row to Last Row in
' Name Column.
Set rngName = .Range(.Cells(cFR, lngName), _
.Cells(lngLR, lngName))
End If
'*******************************************************************
' This is the same as the previous and should demonstrate that
' when you already know the column letter, you have two choices:
' you can use ".Cells" or ".Range".
'*******************************************************************
' Column Letter (strName)
' Last Row Number calculated using Cells and strName.
If strName <> "" Then
' Calculate last row in Name Column.
lngLR = .Cells(.Rows.Count, strName).End(xlUp).Row
' Create a reference to the range First Row to Last Row in
' Name Column.
Set rngName = .Range(.Cells(cFR, strName), _
.Cells(lngLR, strName))
End If
' Last Row Number calculated using Range and strName.
If strName <> "" Then
' Calculate last row in Name Column.
lngLR = .Range(strName & .Rows.Count).End(xlUp).Row
' Create a reference to the range from First Row to Last Row in
' Name Column.
Set rngName = .Range(strName & cFR & ":" & strName & lngLR)
End If
'*******************************************************************
' Since the column letter is more user-friendly, the only use
' I can imagine where you might need it, is to inform the user e.g.
MsgBox "Column '" & strName & "' contains the names and column '" _
& strScore & "' contains the scores.", vbInformation, _
"User Information"
End With
Debug.Print "Last (used) Row in Name Column '" & lngLR & "'."
Debug.Print "Name Range Address '" & rngName.Address & "'."
Debug.Print "Column '" & strName & "' contains the Names and column'" _
& strScore & "' contains the scores."
End With
End Sub