要接收在Excel中按字母顺序排列数据的数组,我总是使用如下所示:
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
(或粘贴大型数组+排序)更快?如果是,如何比较字符串?
发布于 2017-04-22 09:11:51
您可以尝试使用ADODB
库中的方法,只需对您的数据执行一个SELECT
查询,其中您可以对数据中的文本列执行ORDER BY
,这样就不需要编写自定义排序函数了。
使用这种方法,您可以缩放到任意数量的文本列,而不必担心自定义函数将如何处理多列文本数据。
样本数据和输出:
以上代码示例-请按照注释进行操作。
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
请注意以下事项:
https://stackoverflow.com/questions/43554542
复制相似问题