开发者

Add delimiter to concatenated list

开发者 https://www.devze.com 2023-03-31 08:45 出处:网络
I found this custom Excel Function: Function Join(source As Range, Optional delimiter As String) As String

I found this custom Excel Function:

Function Join(source As Range, Optional delimiter As String) As String
'
' Join Macro
' Joins (concatenates) the values from an arbitrary range of cells,
' with an optional delimiter.
'

'optimized for strings
'   check len is faster than checking for ""
'   string Mid$ is faster than variant Mid
'   nested ifs allows for short-circuit + is faster than &

    Dim sResult As String
    Dim oCell As R开发者_StackOverflow中文版ange

    For Each oCell In source.Cells
        If Len(oCell.Value) > 0 Then
            sResult = sResult + CStr(oCell.Value) + delimiter
        End If
     Next

    If Len(sResult) > 0 Then
        If Len(delimiter) > 0 Then
            sResult = Mid$(sResult, 1, Len(sResult) - Len(delimiter))
        End If
    End If

    Join = sResult
End Function

I would like to tweak it to show a comma between each cell it combines to create a list.


There are a couple things wrong with that UDF you found:

  • Concatenation should be done with "&" not "+".
  • Working with cells in a range is slower than a variant array and working purely from inside VBA. Each call to Excel produces a small hit in performance that could add up.
  • The casting to string is unnessesary if the concatenation was done properly.
  • Concatenation should be optimized so that the smaller parts are joined first, then added to the result, otherwise the result is copied twice to do each concatenation.
  • Name should not be Join since VBA has a function of that name.
  • There should be no need to check for LEN of delimiter since it's a string. By default it will be LEN(0) if not existing and you can subtract 0 from the len(result) without any worry.
  • Not a big deal but checking for inequality <> is slightly faster than >.

Here's my version. By default it will seperate each cell by ", " if you leave the second argument empty (ex. =ConcatenateRange(A1:A100)

Function ConcatenateRange(ByVal cell_range As range, _
                    Optional ByVal seperator As String = ", ") As String

Dim cell As range
Dim newString As String
Dim vArray As Variant
Dim i As Long, j As Long

vArray = cell_range.Value

For i = 1 To UBound(vArray, 1)
    For j = 1 To UBound(vArray, 2)
        If Len(vArray(i, j)) <> 0 Then
            newString = newString & (seperator & vArray(i, j))
        End If
    Next
Next

If Len(newString) <> 0 Then
    newString = Right$(newString, (Len(newString) - Len(seperator)))
End If

ConcatenateRange = newString

End Function


It looks like it already does this with the optional delimiter parameter.

Just call it like this:

=JOIN(A1:A100,",")
0

精彩评论

暂无评论...
验证码 换一张
取 消