首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >VBA排序二维数组(按字母顺序排列的文本值)-优化

VBA排序二维数组(按字母顺序排列的文本值)-优化
EN

Stack Overflow用户
提问于 2017-04-22 02:22:04
回答 1查看 1.4K关注 0票数 0

要接收在Excel中按字母顺序排列数据的数组,我总是使用如下所示:

代码语言:javascript
运行
复制
With ThisWorkbook.Worksheets("data")
    LastRow = .Cells.Find(what:="*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
    .Range("a2:b" & LastRow).Sort key1:=.Range("a1"), order1:=xlAscending
    vData = .Range("a2:b" & LastRow)
End With

如果我使用不同的排序参数多次运行排序,我可以有最多3个排序条件,这是一个无限的数目。

问题是这需要时间。最糟糕的情况是,由于代码中的操作,我接收到了一个数组,我必须首先将数组粘贴到工作表中,然后排序。有几十万行,需要几秒钟。

我使用了对QuickSort算法的修改来对数字进行排序,但我设想按字母顺序排序文本需要“StrComp”,从我的经验来看,这是比较耗时的。

您见过或是否认为有可能创建一个VBA二维数组字母排序算法(甚至可以是一个条件列),它的执行速度将比Range.Sort (或粘贴大型数组+排序)更快?如果是,如何比较字符串?

EN

Stack Overflow用户

回答已采纳

发布于 2017-04-22 09:11:51

您可以尝试使用ADODB库中的方法,只需对您的数据执行一个SELECT查询,其中您可以对数据中的文本列执行ORDER BY,这样就不需要编写自定义排序函数了。

使用这种方法,您可以缩放到任意数量的文本列,而不必担心自定义函数将如何处理多列文本数据。

样本数据和输出:

以上代码示例-请按照注释进行操作。

代码语言:javascript
运行
复制
Option Explicit

Sub SortDataBy2TextColumnsWithADO()

    Dim rngInput As Range
    Dim rngOutput As Range
    Dim strWbName As String
    Dim strConnection As String
    Dim objConnection As ADODB.Connection
    Dim strRangeReference As String
    Dim strSql As String
    Dim objRecordSet As ADODB.Recordset
    Dim varSortedData As Variant
    Dim wsf As WorksheetFunction

    ' set input range - includes header
    Set rngInput = ThisWorkbook.Worksheets("Sheet1").Range("A1:C19")

    ' set output range - just the first cell
    Set rngOutput = ThisWorkbook.Worksheets("Sheet1").Range("E1")

    ' copy the headers over
    rngOutput.Resize(1, 3).Value = rngInput.Rows(1).Value

    ' connection string for ACE OLEDB provider
    strWbName = ThisWorkbook.FullName
    strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
        "Data Source=" & strWbName & ";" & _
        "Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"

    ' make the connection to current workbook (better saved the workbook first)
    Set objConnection = New ADODB.Connection
    objConnection.Open strConnection

    ' get range reference as a string suitable for sql query
    strRangeReference = "[" & rngInput.Parent.Name & "$" & rngInput.Address(False, False) & "]"
    ' get the data ordered by text columns (1 and 2) and values (3)
    strSql = "select * from " & strRangeReference & " order by 1, 2, 3"

    ' populate the recordset
    Set objRecordSet = New ADODB.Recordset
    objRecordSet.Open strSql, objConnection

    ' get the sorted data to the variant
    varSortedData = objRecordSet.GetRows

    ' need to transpose the sorted data
    varSortedData = WorksheetFunction.Transpose(varSortedData)

    ' output the transposed sorted data to target range
    rngOutput.Offset(1, 0).Resize(UBound(varSortedData, 1), UBound(varSortedData, 2)).Value = varSortedData

    ' clean up
    objRecordSet.Close
    Set objRecordSet = Nothing
    objConnection.Close
    Set objConnection = Nothing

End Sub

请注意以下事项:

  • 我在未保存的工作簿上发现了错误--所以可能比您至少保存一次工作簿要好。
  • 需要将已排序的数据转换为输出范围-请参阅herehere
票数 4
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43554542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档