Vba 将分隔符添加到连接的列表中

Vba 将分隔符添加到连接的列表中,vba,excel,user-defined-functions,Vba,Excel,User Defined Functions,我发现这个自定义Excel函数: 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

我发现这个自定义Excel函数:

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 Range

    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

我想调整它,使其在每个单元格之间显示一个逗号,它组合起来创建一个列表。

它似乎已经使用可选的
分隔符
参数来实现这一点

就这样说吧:

=JOIN(A1:A100,",")

你发现UDF有两个问题:

  • 串联应使用“&”而不是“+”完成
  • 使用范围内的单元格比使用变体数组慢,并且只从VBA内部工作。每次调用Excel都会对性能产生轻微的影响,这可能会增加性能
  • 如果连接正确,则不需要对字符串进行转换
  • 应优化连接,以便先连接较小的部分,然后将其添加到结果中,否则将复制两次结果以执行每次连接
  • 名称不应为Join,因为VBA具有该名称的函数
  • 应该不需要检查分隔符的LEN,因为它是一个字符串。默认情况下,如果不存在,它将是LEN(0),您可以从LEN(结果)中减去0,而无需担心
  • 没什么大不了的,但检查不平等性的速度比>
这是我的版本。默认情况下,如果第二个参数为空(例如=concatenaterage(A1:A100),它将以“,”分隔每个单元格

函数连接符(ByVal单元格范围作为范围_
可选的ByVal分隔符作为字符串=“,”)作为字符串
暗淡单元格作为范围
将新闻字符串变暗为字符串
Dim vArray作为变体
我和我一样长,我和我一样长
vArray=单元格\范围值
对于i=1到UBound(vArray,1)
对于j=1到UBound(vArray,2)
如果Len(vArray(i,j))为0,那么
newString=newString&(分隔符和vArray(i,j))
如果结束
下一个
下一个
如果Len(newString)为0,则
newString=Right$(newString,(Len(newString)-Len(分隔符)))
如果结束
concatenaterage=newString
端函数

我不会将该函数命名为“Join”,因为已经有一个具有该名称的VBA函数,它在数组(但不是范围)上执行相同的任务。@Issun哪个更快:Right$(newString,(Len(newString)-Len(separator)))或类似于:Mid$(newString,Len(separator)+1)?我使用后者,因为代码较短,但我从未检查过速度。在当前计算机上,差异可能可以忽略不计,但Right()比Mid()快。
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