Изменить / Преамбула
Извините , не прочитал, что вы хотите использовать Текстовые поля и собирать данные один за другим вместо применения процедуры ко всему диапазону данных.
Тем не менее я не удаляю следующий код, так как некоторые читатели могут счесть мой подход полезным или хотят изучить довольно неизвестное использование функции Application.Match()
:)
Найти все столбцы заголовка с помощью одного Match()
Этот (поздний) подход предполагает использование данных из двух столбцов диапазон (идентификатор заголовка и подключенное значение).
Демонстрируется способ поиска всех существующих столбцов заголовка путем выполнения single Application.Match()
в ►one вкладке ~> см. Шаг [3]
.
Дополнительная функция: Если в существующих заголовках не найдены идентификаторы, массив ItemCols
получает элементы Error; шаг [4]
проверяет возможные элементы ошибок, добавляя эти значения в последний столбец.
В других шагах используются справочные функции , как указано ниже.
[1]
getDataRange()
получает данные диапазона, назначая их массиву вариантных данных [2]
HeaderSheet()
получает заголовки как "плоский" массив на основе 1 и устанавливает целевой лист [3]
см. объяснение выше [4]
nxtRow()
получает следующую свободную строку в целевом листе перед записью в найденный столбец
Пример вызова
Sub AddDataToHeaderColumn()
'[1] get range data assigning them to variant data array
Dim rng As Range, data
Set rng = getDataRange(Sheet1, data) ' << change to data sheet's Code(Name)
'[2] get headers as 1-based "flat" array
Dim targetSheet As Worksheet, headers
Set targetSheet = HeaderSheet(Sheet2, headers)
'[3] match header column numbers (writing results to array ItemCols as one liner)
Dim ids: ids = Application.Transpose(Application.Index(data, 0, 1))
Dim ItemCols: ItemCols = Application.Match(ids, Array(headers), 0)
'[4] write data to found column number col
Dim i As Long, col As Long
For i = 1 To UBound(ItemCols)
'a) get column number (or get last header column if not found)
col = IIf(IsError(ItemCols(i)), UBound(headers), ItemCols(i))
'b) write to target cells in found columns
targetSheet.Cells(nxtRow(targetSheet, col), col) = data(i, 2)
Next i
End Sub
Функции справки
Я перевел части основной процедуры в некоторые вызовы функций для лучшей читабельности и, по возможности, помощи пользователям, продемонстрировав некоторые неявные ByRef
аргументы, такие как [ByRef
] mySheet
или передавая пустой массив, такой как data
или headers
.
'[1]
Function getDataRange(mySheet As Worksheet, data) As Range
'Purpose: assign current column A:B values to referenced data array
'Note: edit/corrected assumed data range in columns A:B
With mySheet
Set getDataRange = .Range("A2:B" & .Cells(.Rows.Count, "B").End(xlUp).Row)
data = getDataRange ' assign range data to referenced data array
End With
End Function
'[2]
Function HeaderSheet(mySheet As Worksheet, headers) As Worksheet
'Purpose: assign titles to referenced headers array and return worksheet reference
'Note: assumes titles in row 1
With mySheet
Dim lastCol As Long: lastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
headers = Application.Transpose(Application.Transpose(.Range("A1").Resize(1, lastCol)))
End With
Set HeaderSheet = mySheet
End Function
'[4]
Function nxtRow(mySheet As Worksheet, ByVal currCol As Long) As Long
'Purpose: get next empty row in currently found header column
With mySheet
nxtRow = .Cells(.Rows.Count, currCol).End(xlUp).Row + 1
End With
End Function