下部のコードを使用して、列をアルファベット順、数値順、および次のアルファベット文字と句読文字(AB00017C)で並べ替えています。私が取り組んでいる単列シートでの生活は良いです。データが列Aにある限り、すべてが見栄えがします。
複数の列があるシートに移動すると、それは単純に醜いです!
この種の機能を実現するのに2日かかりました。列Aの右側に3つのヘルパー列を挿入し、列Aのセル値を3つの新しい列にスライスして、正しい順序で並べ替えます。最後に、3つのヘルパー列を削除します。
テスト用の簡単なコマンドボタンにコードを添付しました。フォーラムによってすべてのコメントが削除されて申し訳ありません。
このサブルーチンが非常に役立つ列CGに出て行くシートがあります。
今、頭が痛いので、自分を隅に追いやったと思います。どうやって抜け出すのかわかりません。
どんな洞察も暖かく歓迎されます、CraigMc
以下はいくつかのデータです
sku post_title
AB00017a Lixit, Glass Water Bottle, 32 oz.
AB00017 Lixit, Glass Water Bottle, 16 oz.
AB00016z Hookbill Legume Blend with Peantus, 32 lbs.
AB00016-b Bonito Loco Pretty Crazy Nut Blend, 32 lbs.
AB00016 Madagascar Delite, 64 oz.
AB00017c Nutmeats and Fruit, 32 lbs.
AB00017g Nutmeats and Fruit, 25 oz.
コードは次のとおりです。
Private Sub CommandButton1_Click()
Dim intLoops As Integer
Dim lngNumeric As Long
Dim lngLastRow As Long
Dim rngRows As Range
Dim rngcell As Range
Dim strAlpha As String
Dim strPrefix As String
Dim strSuffix As String
'-----------------------------
strPrefix = "True"
strSuffix = "False"
'-----------------------------
Columns("B:D").Insert Shift:=xlToRight 'Insert 3 temporary columns to the Right of Column A.
lngLastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, Left("A1", 1)).End(xlUp).Row
Set rngRows = Range("A2", Range("A" & Rows.Count).End(xlUp)) 'Separates Alpha to Next Column, Numeric to the following column
For Each rngcell In rngRows
intLoops = Len(rngcell) 'Works on one character at at time.
For intLoops = 1 To intLoops 'Read each character in the cell
If strPrefix = "True" Then
If Not IsNumeric(Mid(rngcell, intLoops, 1)) Then 'This is the PREFIX
strAlpha = strAlpha & Mid(rngcell, intLoops, 1)
If IsNumeric(Mid(rngcell, intLoops + 1, 1)) Then 'Is the next character Aphabetic, Yes this is the SUFFIX coming up.
strPrefix = "False" 'Next Charater is the Suffix
End If
Else
lngNumeric = lngNumeric & Mid(rngcell, intLoops, 1) 'No it is the number in the middle
End If
Else 'This is the Suffix
If IsNumeric(Mid(rngcell, intLoops, 1)) And strSuffix = "False" Then
lngNumeric = lngNumeric & Mid(rngcell, intLoops, 1) 'No it is the number in the middle
If (Mid(rngcell, intLoops + 1, 1)) = "-" Then 'Onceyou hit a non-numeric character stay in the suffix.
strSuffix = "True" 'Ensures that all that follows the center number stays in the Suffix.
End If
Else
alpSuffix = alpSuffix & Mid(rngcell, intLoops, 1) 'Character SUFFIX
End If
End If
Next intLoops
rngcell.Offset(, 1) = strAlpha
rngcell.Offset(, 2) = lngNumeric
rngcell.Offset(, 3) = alpSuffix & " "
strAlpha = vbNullString
lngNumeric = 0
alpSuffix = vbNullString
strPrefix = "True"
strSuffix = "False"
Next rngcell
Set rngRows = rngRows.Resize(rngRows.Rows.Count, 4)
rngRows.Sort key1:=rngRows.Range(Cells(1, 3), Cells(rngRows.Rows.Count, 3)), order1:=xlAscending, _
key2:=rngRows.Range(Cells(1, 2), Cells(rngRows.Rows.Count, 2)), order2:=xlAscending, Header:=xlGuess
lngLastRow = ActiveSheet.Cells(ActiveSheet.Rows.Count, Left("A2", 1)).End(xlUp).Row
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add Range("B1"), xlSortOnValues, xlAscending
ActiveSheet.Sort.SortFields.Add Range("C1"), xlSortOnValues, xlAscending
ActiveSheet.Sort.SortFields.Add Range("D1"), xlSortOnValues, xlAscending
With ActiveSheet.Sort
.SetRange Range("A1").CurrentRegion
.Header = xlYes
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Columns("B:D").Delete Shift:=xlToLeft 'Delete the 3 temporary columns to the Right of Column A.
End Sub
ありがとう!
範囲の問題を修正するためにいくつかの変更を加えましたが、文字列の解析はうまく機能しました
私の変更:
ほとんどの変数の名前をもう少し直感的に変更しました
シートオブジェクトとの相互作用を減らす
アルゴリズムを使用して文字列を解析する
一度、メモリからシートにデータを戻します
シート上のすべてのデータに並べ替えを適用する(並べ替え領域が適切に設定されていなかった)
。
これが更新されたコードです。新しいモジュールに配置してください
Option Explicit
'Place the code in a new module (from the menu: Insert -> Module)
Private Const START_COL As Byte = 1
Public Sub SortSheet(ByVal wsName As String, _
Optional ByVal sortCol As Long = 1, _
Optional ByVal row1 As Long = 2)
Dim wb As Workbook: Dim ws As Worksheet
Dim lRow As Long: Dim lCol As Long
Dim thisRow As Long: Dim thisStr As String
Dim lastCell As Range
Dim sortRng As Range: Dim sortKey1 As Range
Dim sortKey2 As Range: Dim sortKey3 As Range
Dim memArr1Col As Variant 'column with strings (in memory)
Dim memArr3Col As Variant 'helper columns, for sorting (in memory)
Dim char As Long: Dim strLen As Long
Dim preBol As Boolean: Dim sufBol As Boolean
Dim midNum As String
Dim preStr As String: Dim sufStr As String
'---------------------------------------
preBol = True
sufBol = False
'---------------------------------------
With Application
.ScreenUpdating = False
Set wb = .ActiveWorkbook
End With
Set ws = Sheets(wsName)
Set lastCell = GetMaxCell(ws.UsedRange)
lRow = lastCell.Row
lCol = lastCell.Column
If row1 <= lRow Then
With ws 'set mem arrays: sort col, and helpers
memArr1Col = .Range(.Cells(row1, sortCol), .Cells(lRow, sortCol))
memArr3Col = .Range(.Cells(row1, lCol + 1), .Cells(lRow, lCol + 3))
End With
For thisRow = row1 - 1 To lRow - 1 'parse each cell in sort column
If Not IsEmpty(memArr1Col(thisRow, 1)) And _
Not IsNull(memArr1Col(thisRow, 1)) And _
Len(memArr1Col(thisRow, 1)) > 0 Then
thisStr = memArr1Col(thisRow, 1)
strLen = Len(thisStr)
For char = 1 To strLen 'parse each string
If preBol = True Then
If Not IsNumeric(Mid(thisStr, char, 1)) Then
preStr = preStr & Mid(thisStr, char, 1)
preBol = Not IsNumeric(Mid(thisStr, char + 1, 1))
Else
midNum = midNum & Mid(thisStr, char, 1)
End If
Else
If IsNumeric(Mid(thisStr, char, 1)) And sufBol = False Then
midNum = midNum & Mid(thisStr, char, 1)
sufBol = (Mid(thisStr, char + 1, 1)) = "-"
Else
sufStr = sufStr & Mid(thisStr, char, 1)
End If
End If
Next 'Next character in the string
memArr3Col(thisRow, 1) = preStr
memArr3Col(thisRow, 2) = midNum
memArr3Col(thisRow, 3) = sufStr & " "
preBol = True
sufBol = False
midNum = vbNullString
preStr = vbNullString
sufStr = vbNullString
End If
Next 'Next Row
With ws
'place helper column values from memory to current worksheet
.Range(.Cells(row1, lCol + 1), .Cells(lRow, lCol + 3)) = memArr3Col
'set sort range - all data on this sheet plus the last 3 helper columns
Set sortRng = .Range(.Cells(row1, START_COL), .Cells(lRow, lCol + 3))
'set sort keys to helper columns
Set sortKey1 = .Range(.Cells(row1, lCol + 1), .Cells(lRow, lCol + 1))
Set sortKey2 = .Range(.Cells(row1, lCol + 2), .Cells(lRow, lCol + 2))
Set sortKey3 = .Range(.Cells(row1, lCol + 3), .Cells(lRow, lCol + 3))
End With
With ws
With .Sort 'apply the sort
With .SortFields
.Clear
.Add sortKey1, xlSortOnValues, xlAscending
.Add sortKey2, xlSortOnValues, xlAscending
.Add sortKey3, xlSortOnValues, xlAscending
End With
.SetRange sortRng
.Header = xlYes
.Orientation = xlTopToBottom
.Apply
End With
.Range( _
.Cells(row1, lCol + 1), _
.Cells(lRow, lCol + 3)).EntireColumn.Delete 'delete helper cols
.Activate
.Cells(1, 1).Activate
End With
End If
Application.ScreenUpdating = True
End Sub
。
この関数を同じ(新しい)モジュールに配置します
Public Function GetMaxCell(Optional ByRef rng As Range = Nothing) As Range
'Returns the last cell of range with data, or A1 if Worksheet is empty
Const NONEMPTY As String = "*"
Dim lRow As Range, lCol As Range
If rng Is Nothing Then Set rng = Application.ActiveWorkbook.ActiveSheet.UsedRange
If WorksheetFunction.CountA(rng) = 0 Then
Set GetMaxCell = rng.Parent.Cells(1, 1)
Else
With rng
Set lRow = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByRows)
If Not lRow Is Nothing Then
Set lCol = .Cells.Find(What:=NONEMPTY, LookIn:=xlFormulas, _
After:=.Cells(1, 1), _
SearchDirection:=xlPrevious, _
SearchOrder:=xlByColumns)
Set GetMaxCell = .Parent.Cells(lRow.Row, lCol.Column)
End If
End With
End If
End Function
。
次のように、任意のSheetモジュールからmain関数を呼び出すことができます。
Option Explicit
Private Sub CommandButton1_Click()
SortSheet wsName:="Master of Masters"
End Sub
またはこのように(デフォルトのパラメータを上書きするため)
Option Explicit
Private Sub CommandButton1_Click()
SortSheet wsName:="Master of Masters", sortCol:=1, row1:=2
End Sub
。
ソートキーを変更するには、それに応じて次の3行を変更します。
これはPreFixでソートされます(最初のヘルパー列、次に2番目、次に3番目):
Set sortKey1 = .Range(.Cells(row1, lCol + 1), .Cells(lRow, lCol + 1)) 'PreFix: "AB"
Set sortKey2 = .Range(.Cells(row1, lCol + 2), .Cells(lRow, lCol + 2)) 'Middle ID
Set sortKey3 = .Range(.Cells(row1, lCol + 3), .Cells(lRow, lCol + 3)) 'PostFix
ミドルID番号(2番目のヘルパー列、1番目、3番目)で並べ替えるには:
Set sortKey1 = .Range(.Cells(row1, lCol + 2), .Cells(lRow, lCol + 2)) 'Middle ID
Set sortKey2 = .Range(.Cells(row1, lCol + 1), .Cells(lRow, lCol + 1)) 'PreFix: "AB"
Set sortKey3 = .Range(.Cells(row1, lCol + 3), .Cells(lRow, lCol + 3)) 'PostFix
PostFixで並べ替えるには(3番目のヘルパー列、次に2番目、次に3番目):
Set sortKey1 = .Range(.Cells(row1, lCol + 3), .Cells(lRow, lCol + 3)) 'PostFix
Set sortKey2 = .Range(.Cells(row1, lCol + 2), .Cells(lRow, lCol + 2)) 'Middle ID
Set sortKey3 = .Range(.Cells(row1, lCol + 1), .Cells(lRow, lCol + 1)) 'PreFix: "AB"
。
私はあなたが提供したデータでそれをテストしました。結果は次のとおりです。
。
。
並べ替え中-3つのヘルパー列の文字列を解析した結果を示します
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加