JackeyOL
JackeyOL

Reputation: 321

Concat several columns using column names in Excel VBA

As shown in image_1, I have the raw data of a product as shown in Column B to Column F. I want to add column A, which concats the "Model", "Year", "Number" data into a string. I know I can achieve this simply by [a2] = "=concat(B2,D2,F2)", and then filldown. But the problem is that the raw file I receive every day is inconsistent in terms of the order of the columns. Therefore, I couldn't use a static line of code displayed above.

I can probably use a combination of for loop and if/else to test if the column name equal to "Model", "Year", "Number", and if yes, grab its column number...

However, I'm wondering if there's a more direct and elegant way of achieving this. Any thoughts?

Image_1

Upvotes: 0

Views: 1397

Answers (3)

chris neilsen
chris neilsen

Reputation: 53136

If you want to add the "Concat" column and formula without reordering the columns, you can do that with vba like this

Sub Demo()
    Dim ws As Worksheet
    Dim colModel As Variant
    Dim colYear As Variant
    Dim colNum As Variant
    Dim LastRow As Long
    
    Set ws = ActiveSheet ' or any means you choose
    
    LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    
    If ws.Cells(1, 1) <> "Concat" Then
        'Insert new column
        ws.Columns(1).Insert
        
        ' New column header
        ws.Cells(1, 1) = "Concat"
    End If
    
    ' get colum positions
    colModel = Application.Match("Model", ws.Rows(1), 0)
    colYear = Application.Match("Year", ws.Rows(1), 0)
    colNum = Application.Match("Number", ws.Rows(1), 0)
    
    ' Check if columns exist
    If IsError(colModel) Then
        MsgBox "Column ""Model"" not found", vbCritical + vbOKOnly, "Error"
        Exit Sub
    End If
    If IsError(colYear) Then
        MsgBox "Column ""Year"" not found", vbCritical + vbOKOnly, "Error"
        Exit Sub
    End If
    If IsError(colNum) Then
        MsgBox "Column ""Number"" not found", vbCritical + vbOKOnly, "Error"
        Exit Sub
    End If
    
    ' Insert Formula
    ws.Range(ws.Cells(2, 1), ws.Cells(LastRow, 1)).FormulaR1C1 = "=RC[" & colModel - 1 & "]&RC[" & colYear - 1 & "]&RC[" & colNum - 1 & "]"
    
End Sub

Alternatively, you could also use a formula in column A to find the column positions

In Excel365

=XLOOKUP("Model",$1:$1,2:2,,0)&XLOOKUP("Year",$1:$1,2:2,,0)&XLOOKUP("Number",$1:$1,2:2,,0)

For pre 365

=INDEX(2:2,MATCH("Model",$1:$1,0))&INDEX(2:2,MATCH("Year",$1:$1,0))&INDEX(2:2,MATCH("Number",$1:$1,0))

Upvotes: 0

Rob Kellock
Rob Kellock

Reputation: 11

If they are always the same columns, just the order changes then sort by column headings first before concatenating, that way they will always be in the same position.

If you have differing columns and the ones you are interested in are somewhere within it, then you could use the following formula: =HLOOKUP("Heading_Name","Data_Range",Row_No,FALSE) to extract each of the columns you are interested in. Concatenating the results of these would give you what you want and will work for any arrangement of columns and sizes of data providing you declare the range properly.

Upvotes: 0

Алексей Р
Алексей Р

Reputation: 7627

A simple approach based on sorting columns by header and merging data in columns with constant numbers (assuming constant number of columns but different order). If the number of columns is variable, this code will not work.

Sub concat()
    Dim rng As Range
    
    With ThisWorkbook.Worksheets(1)
        Set rng = .Range("A1").CurrentRegion
        ' columns sort
        With .Sort
            .SortFields.Clear
            .SortFields.Add2 Key:=rng.Rows(1)
            .SetRange rng
            .Orientation = xlLeftToRight
            .Apply
        End With
        Set rng = rng.Columns(1)
        rng.Insert  ' add cells at left for "Concat"
        Set rng = rng.Offset(0, -1)
        rng(1) = "Concat"   ' add header
        Intersect(rng, rng.Offset(1)).FormulaR1C1 = "=CONCAT(RC[2],RC[5],RC[3])"
    End With
End Sub

Before
enter image description here

After
enter image description here

Upvotes: 1

Related Questions