Turn Excel range into VBA string

前端 未结 7 1848
野性不改
野性不改 2020-11-30 11:51

I would like to turn values in given range into VBA string where original cell values are separated by any chosen column delimiter and row delimiter. Delimiters could be one

7条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-30 12:19

    To optimize performance my function emulates a String Builder.

    Variables

    • Text: A very large string to hold the data
    • CELLLENGTH: A contant that determines the size of the BufferSize
    • BufferSize: The initial size of Text string
    • Data(): An Array derived from the source range

    As the rows and columns of the Data() array are iterated over the current element (Data(x, y)) value replaces a portion of the Text string. The text string is resized as needed. This reduces the number of concatenations immensely. The initial BufferSize is set pretty high. I got my best results, 0.8632813 Second(s), by reducing CELLLENGTH to 25.

    Download Sample Data from Sample-Videos.com

    Results

    Code

    Function getRangeText(Source As Range, Optional rowDelimiter As String = "@", Optional ColumnDelimiter As String = ",")
        Const CELLLENGTH = 255
        Dim Data()
        Dim text As String
        Dim BufferSize As Double, length As Double, x As Long, y As Long
        BufferSize = CELLLENGTH * Source.Cells.Count
        text = Space(BufferSize)
    
        Data = Source.Value
    
        For x = 1 To UBound(Data, 1)
            If x > 1 Then
                Mid(text, length + 1, Len(rowDelimiter)) = rowDelimiter
                length = length + Len(rowDelimiter)
            End If
    
            For y = 1 To UBound(Data, 2)
                If length + Len(Data(x, y)) + 2 > Len(text) Then text = text & Space(CDbl(BufferSize / 4))
                If y > 1 Then
                    Mid(text, length + 1, Len(ColumnDelimiter)) = ColumnDelimiter
                    length = length + Len(ColumnDelimiter))
                End If
    
                Mid(text, length + 1, Len(Data(x, y))) = Data(x, y)
                length = length + Len(Data(x, y))
            Next
        Next
    
        getRangeText = Left(text, length) & rowDelimiter
    End Function
    

    Test

    Sub TestGetRangeText()
        Dim s As String
        Dim Start: Start = Timer
    
        s = getRangeText(ActiveSheet.UsedRange)
    
        Debug.Print "Execution Time: "; Timer - Start; "Second(s)"
        Debug.Print "Rows: "; ActiveSheet.UsedRange.Rows.Count; "Columns: "; ActiveSheet.UsedRange.Columns.Count
        Debug.Print "Result Length: "; Format(Len(s), "#,###")
    End Sub
    

提交回复
热议问题