Excel VBA UDF for concatenating is giving an Error

2019-07-25 03:27发布

问题:

I'm trying to write a User Defined Function (UDF) in Excel that will take the values in a range of cells, and concatenate them in a certain way. Specifically, I want to concatenate them in a way that the resulting string could be pasted into a SQL "in" function - i.e. if I have a range in Excel that contains:

apples
oranges
pears

I want the UDF to result in 'apples', 'oranges', 'pears'

(i.e. no comma after the last value).

This is my code - it compiles OK in the VBA window, but when I use it in a worksheet I just get ERROR. Any thoughts much appreciated - I'm a bit of a newbie at writing VBA. And apologies for the vague question; I'm just at a loss to see which bit is causing the trouble.

Function ConcatenateforSQL(ConcatenateRange As Range) As Variant     



    Dim i As Long

    Dim strResult1 As String
    Dim strResult2 As String

    Dim Separator1 As String
    Dim Separator2 As String


    Separator1 = "'"  'hopefully the quotes act as escape characters
    Separator2 = "',"



    On Error GoTo ErrHandler



    For i = 1 To CriteriaRange.Count - 1                                              'all but the last one
              strResult1 = strResult1 & Separator1 & ConcatenateRange.Cells(i).Value & Separator2

    Next i


    'next, sort out the last example in the string

    For i = CriteriaRange.Count - 0 To CriteriaRange.Count + 0

      strResult2 = strResult1 & Separator1 & ConcatenateRange.Cells(i).Value & Separator1

    Next i


    ConcatenateforSQL = strResult2  

    Exit Function

ErrHandler:
    ConcatenateforSQL = CVErr(xlErrValue)
End Function

回答1:

I prefer the JOIN array approach.

Option Explicit

Function ConcatenateforSQL(ConcatenateRange As Range) As Variant
    On Error GoTo ErrHandler

    Dim r As Long, c As Long
    Dim vVAL As Variant, vVALS As Variant

    ReDim vVAL(1 To 1)
    vVALS = ConcatenateRange.Value2

    For r = LBound(vVALS, 1) To UBound(vVALS, 1)
        For c = LBound(vVALS, 2) To UBound(vVALS, 2)
            'Debug.Print vVALS(r, c)
            ReDim Preserve vVAL(1 To (r * c))
            vVAL(r * c) = vVALS(r, c)
        Next c
    Next r

    ConcatenateforSQL = Chr(39) & Join(vVAL, "','") & Chr(39)
    Exit Function

ErrHandler:
    ConcatenateforSQL = CVErr(xlErrValue)
End Function


回答2:

This works for me (feel free to add in your error traps etc):

Function ConcatenateforSQL(ConcatenateRange As Range) As Variant
Dim csql As String
csql = ""
For Each cl In ConcatenateRange
    If Len(cl) > 0 Then
        If csql <> "" Then csql = csql & ","
        csql = csql & "'" & cl.Value & "'"
    End If
Next
ConcatenateforSQL = csql
End Function


回答3:

A slightly different approach which allows you to specify the comma delimiter (it will be a comma if you don't specify). One could add a further argument for the other one.

Function ConcatenateforSQL(ConcatenateRange As Range, Optional sSep As String = ",") As Variant

Dim i As Long

Dim strResult As String

On Error GoTo ErrHandler

For i = 1 To ConcatenateRange.Count
    strResult = strResult & sSep & "'" & ConcatenateRange.Cells(i).Value & "'"
Next i

ConcatenateforSQL = Mid(strResult, Len(sSep) + 1)

Exit Function

ErrHandler:
ConcatenateforSQL = CVErr(xlErrValue)

End Function