Здравствуйте! Ребята, есть ли какой способ сортировки текста методом vba в начале которого прописана числовая нумерация (маркировка) в виде разделов и подразделов (данная маркировка присуща дорожным знакам, пример последовательности маркировки частично показан в примере).
Здравствуйте! Ребята, есть ли какой способ сортировки текста методом vba в начале которого прописана числовая нумерация (маркировка) в виде разделов и подразделов (данная маркировка присуща дорожным знакам, пример последовательности маркировки частично показан в примере).Сергей13
InExSu, по разному пробовал не получается, данная маркировка это по сути некое подобие подразделов которое формирует как последовательность расположения (и быстрого нахождения при ведении учета) в группах так и нормативное обозначение каждого знака, поэтому добавление нулей создаст путаницу.
InExSu, по разному пробовал не получается, данная маркировка это по сути некое подобие подразделов которое формирует как последовательность расположения (и быстрого нахождения при ведении учета) в группах так и нормативное обозначение каждого знака, поэтому добавление нулей создаст путаницу.Сергей13
Сообщение отредактировал Сергей13 - Суббота, 07.09.2019, 15:36
Function Len_Max( _ Optional s As String) _ As Long ' code test coverage ' потом будет искать макс длину строки для определения ' колва лидирующих нулей
Len_Max = 2
End Function
Function Prep_2_Sort_Natural( _ lLen As Long, _ lead As String, _ separ As String, _ s As String) _ As String ' code test coverage ' получаю строку вида 1.45.6 ' делаю из неё 01.45.06
Function Len_Max( _ Optional s As String) _ As Long ' code test coverage ' потом будет искать макс длину строки для определения ' колва лидирующих нулей
Len_Max = 2
End Function
Function Prep_2_Sort_Natural( _ lLen As Long, _ lead As String, _ separ As String, _ s As String) _ As String ' code test coverage ' получаю строку вида 1.45.6 ' делаю из неё 01.45.06
Sub Sorting() Dim arr() As Variant, s, maxLevel%, i, j, v, s0$, dic As Object, arr1 As Variant Set dic = CreateObject("scripting.dictionary") With ActiveSheet.UsedRange.Columns(1) ReDim arr(.Rows.Count - 1) For Each s In .Value j = 0: s0 = "'"
For Each v In Split(Split(s, "_")(0), ".") s0 = s0 & Application.Dec2Hex(Val(v), 4) j = j + 1 Next
If j > maxLevel Then maxLevel = j Else ShiftLeft s0, maxLevel - j End If
If Not IsArray(dic(maxLevel)) Then dic(maxLevel) = Array(i) Else arr1 = dic(maxLevel) ReDim Preserve arr1(UBound(arr1) + 1) arr1(UBound(arr1)) = i dic(maxLevel) = arr1 End If
arr(i) = Array(s0, s) i = i + 1 Next
For j = maxLevel - 1 To 1 Step -1 If IsArray(dic(j)) Then For Each i In dic(j) ShiftLeft arr(i)(0), maxLevel - j Next End If Next Quicksort arr, 0, UBound(arr)
.Value = Application.Index(arr, 0, 2) End With End Sub Private Sub ShiftLeft(ByRef s, n) s = s & Application.Rept("0000", n) End Sub
Private Sub Quicksort(vArray As Variant, arrLbound As Long, arrUbound As Long) 'Sorts a one-dimensional VBA array from smallest to largest 'using a very fast quicksort algorithm variant. Dim pivotVal As Variant Dim vSwap As Variant Dim tmpLow As Long Dim tmpHi As Long
While (tmpLow <= tmpHi) 'divide While (vArray(tmpLow)(0) < pivotVal And tmpLow < arrUbound) tmpLow = tmpLow + 1 Wend
While (pivotVal < vArray(tmpHi)(0) And tmpHi > arrLbound) tmpHi = tmpHi - 1 Wend
If (tmpLow <= tmpHi) Then vSwap = vArray(tmpLow) vArray(tmpLow) = vArray(tmpHi) vArray(tmpHi) = vSwap tmpLow = tmpLow + 1 tmpHi = tmpHi - 1 End If Wend
If (arrLbound < tmpHi) Then Quicksort vArray, arrLbound, tmpHi 'conquer If (tmpLow < arrUbound) Then Quicksort vArray, tmpLow, arrUbound 'conquer End Sub
[/vba]
вариант [vba]
Код
Option Explicit
Sub Sorting() Dim arr() As Variant, s, maxLevel%, i, j, v, s0$, dic As Object, arr1 As Variant Set dic = CreateObject("scripting.dictionary") With ActiveSheet.UsedRange.Columns(1) ReDim arr(.Rows.Count - 1) For Each s In .Value j = 0: s0 = "'"
For Each v In Split(Split(s, "_")(0), ".") s0 = s0 & Application.Dec2Hex(Val(v), 4) j = j + 1 Next
If j > maxLevel Then maxLevel = j Else ShiftLeft s0, maxLevel - j End If
If Not IsArray(dic(maxLevel)) Then dic(maxLevel) = Array(i) Else arr1 = dic(maxLevel) ReDim Preserve arr1(UBound(arr1) + 1) arr1(UBound(arr1)) = i dic(maxLevel) = arr1 End If
arr(i) = Array(s0, s) i = i + 1 Next
For j = maxLevel - 1 To 1 Step -1 If IsArray(dic(j)) Then For Each i In dic(j) ShiftLeft arr(i)(0), maxLevel - j Next End If Next Quicksort arr, 0, UBound(arr)
.Value = Application.Index(arr, 0, 2) End With End Sub Private Sub ShiftLeft(ByRef s, n) s = s & Application.Rept("0000", n) End Sub
Private Sub Quicksort(vArray As Variant, arrLbound As Long, arrUbound As Long) 'Sorts a one-dimensional VBA array from smallest to largest 'using a very fast quicksort algorithm variant. Dim pivotVal As Variant Dim vSwap As Variant Dim tmpLow As Long Dim tmpHi As Long
While (tmpLow <= tmpHi) 'divide While (vArray(tmpLow)(0) < pivotVal And tmpLow < arrUbound) tmpLow = tmpLow + 1 Wend
While (pivotVal < vArray(tmpHi)(0) And tmpHi > arrLbound) tmpHi = tmpHi - 1 Wend
If (tmpLow <= tmpHi) Then vSwap = vArray(tmpLow) vArray(tmpLow) = vArray(tmpHi) vArray(tmpHi) = vSwap tmpLow = tmpLow + 1 tmpHi = tmpHi - 1 End If Wend
If (arrLbound < tmpHi) Then Quicksort vArray, arrLbound, tmpHi 'conquer If (tmpLow < arrUbound) Then Quicksort vArray, tmpLow, arrUbound 'conquer End Sub