Home » excel » vba – Excel: Concatenate last non empty cells in a column

# vba – Excel: Concatenate last non empty cells in a column

Posted by: admin May 14, 2020 Leave a comment

Questions:

Since my previous post was closed, but the problem remains, I’ll rephrase it here. I’ve came up with the following:

``````Function JoinLastInColIfEmpty(range_ As Range, delim_ As String)
Dim cell As Range, result As String, current As String

For Each cell In range_
current = LastNonEmptyInCol(cell)
If current <> "" Then
result = result & current & delim_
End If
Next

If Not IsEmpty(result) Then
result = Left(result, Len(result) - Len(delim_))
End If

JoinLastInColIfEmpty = result
End Function

Function LastNonEmptyInCol(cell_ As Range)
Dim tmp As Range
tmp = cell_ '<< The problem occurs here
Do Until Not IsEmpty(tmp) Or tmp.Row = 1
tmp = tmp.Offset(-1, 0)
Loop
LastNonEmptyInCol = tmp.Value
End Function
``````

The problem is that the function never ends, so my questions are:

• What is wrong with my script?
• What should I do to solve my problem?
How to&Answers:

To answer your direct question, there are a couple of errors in `LastNonEmptyInCol`

``````Function LastNonEmptyInCol(cell_ As Range)
On Error Resume Next
Dim tmp As Range
Set tmp = cell_ '<< The problem occurs here  ' <<<<< use Set
Do Until Not IsEmpty(tmp) Or tmp.Row = 1     ' <<<<< use tmp not cell_
Set tmp = tmp.Offset(-1, 0)              ' <<<<< use Set
Loop
LastNonEmptyInCol = tmp.Value
End Function
``````

That said, I think it is a very inefficient solution, and does not quite solve your stated problem

results will be

``````    A  |  B  |  C  |  D  | Concat
-----+-----+-----+-----+---------
1  |  2  |  X  |  5  | 12X5
|     |  f  |  3  | 12f3
|  5  |  R  |  12 | 15R12
Z  |  3  |  T  |     | Z3T12
|  G  |     |     | ZGT12
``````

Here’s another version which might be better

``````Function MyJoinLastInColIfEmpty(range_ As Range, delim_ As String)
Dim vData As Variant
Dim cl As Range
Dim i As Long
Dim result As Variant

vData = range_

For i = 1 To UBound(vData, 2)
If vData(1, i) = "" Then
Set cl = range_.Cells(1, i).End(xlUp)
If cl <> "" Then
vData(1, i) = cl.Value
End If
Else
Exit For
End If
Next
For i = 1 To UBound(vData, 2)
result = result & vData(1, i) & delim_
Next

MyJoinLastInColIfEmpty = Left(result, Len(result) - Len(delim_))
End Function
``````

### Answer：

I did not really try to understand the whole thing, but since tmp is an (range) object, you must use
`Set tmp = ....`

### Answer：

With help rows/columns this can be achieved with formulas:

-Placed in cell `F1` array entered (`Ctrl+Shift+Enter`) then scrolled to however many cells you have:

``````{=INDEX(A\$1:A1,MAX(IF(ISBLANK(A\$1:A1),0,ROW(A\$1:A1))))}
``````

-Placed in cell `K1`, refers to first cell in `F1`, no need for array here.

``````=IF(ISBLANK(A1),IF(SUM(NOT(ISBLANK(INDEX(\$A1:A1,0)))+0)>0,"",F1),F1)
``````

-Placed wherever you want the results. `MCONCAT` is a UDF function found in a free Add-in written in C++, `CONCATENATE` is Excel’s built in formula.

`=MConCat(K1:N1)` or `=CONCATENATE(K1,L1,M1,N1)`

My personal preference would be the VBA way though. I’m sure someone smarter than me could come up with some better formulas.