Home » excel » vba – How to create an excel function that outputs the content of a range of cells

vba – How to create an excel function that outputs the content of a range of cells

Posted by: admin April 23, 2020 Leave a comment

Questions:

I am trying to create an excel function that concatenates the text contained within a range of cells C4:K9.

Although the code below concatenates the text within the range of cells, I am not successful in inserting a carriage return (vbCrLF) between each row. So when I type the function in the cell I wish to see the output value, I want it to be contents of C4:K4, carriage return, C5:K5, carriage return, and so forth until C9:K9 all in one cell.

Function Join(rng As Range, delimiter As String) As String
Dim cell As Range, rowIndex As Long
 For rowIndex = 1 To rng.Rows.Count
   For Each cell in rng(cells(rowIndex,3), cells(rowIndex,11))
    Join = Join & cell.Text & delimiter
   Next cell
   Join = Left(Join, Len(Join) - Len(delimiter)) & vbCrLF
 Next rowIndex
End Function

Does anybody have any ideas as to how to make this function work?

How to&Answers:

As you want to loop over each cell in a row, you can do it by this: For Each cell In rng.Rows(rowIndex).Cells.

To show multiple lines within a cell, you need vbLf as last character of each line (and “Wrap Text” as cell format).

Function Join(rng As Range, delimiter As String) As String
    Dim cell As Range, rowIndex As Long
    For rowIndex = 1 To rng.Rows.Count
        For Each cell In rng.Rows(rowIndex).Cells
            Join = Join & cell.Text & delimiter
        Next cell
        Join = Left(Join, Len(Join) - Len(delimiter)) & vbLf
    Next rowIndex
End Function

One last hint: Please try to avoid internal VBA names (Join, RowIndex) for your own function names or variables.

Answer:

I’ve changed the For Each cell line of your code to make it work:

Function Join(rng As Range, delimiter As String) As String
Dim cell As Range, rowIndex As Long
 For rowIndex = 1 To rng.Rows.Count
   For Each cell In Range(rng(rowIndex, 1), rng(rowIndex, rng.Columns.Count))
    Join = Join & cell.Text & delimiter
   Next cell
   Join = Left(Join, Len(Join) - Len(delimiter)) & vbCrLf
 Next rowIndex
End Function

To understand the difference… I started with your line:

For Each cell in rng(cells(rowIndex,3), cells(rowIndex,11))

-The problem is we’re using a fresh Range – it’s a subset of rng but it’s fresh, so:

For Each cell In Range(rng(rowIndex, 1), rng(rowIndex, 9))

-That works fine, but then to make it more dynamic I swapped the 9 for a column count:

For Each cell In Range(rng(rowIndex, 1), rng(rowIndex, rng.Columns.Count))

Answer:

You have misaddressed the source cells with rowIndex = 1. Try this:

Function Join(rng As Range, delimiter As String) As String
    Dim cell As Range, rowIndex As Long, colIndex As Long

    For rowIndex = rng.Row To rng.Row + rng.Rows.Count - 1
        For colIndex = rng.Column To rng.Column + rng.Columns.Count - 1
            Join = Join & Cells(rowIndex, colIndex).Text & delimiter
        Next
        Join = Left(Join, Len(Join) - Len(delimiter)) & vbCrLf
    Next rowIndex
    Join = Left(Join, Len(Join) - 1)  ' cut terminal crlf
End Function