エクセルVBA 並び替え 色々なパターンの範囲選択に対応できるVBAコードを設計します。
空白行やセル結合時にも対応できる範囲選択を想定しています。
こんにちは じゅんぱ店長 (@junpa33) です。
VBAを使って、エクセルのセルデータの並び替えを行うツールを作成しています。
特定のデータシートの並び替えを行なうマクロツールではなく、出来るだけ多くのパターンのデータシートを並び替えることの出来るものを目指しています。
ですので、その分、利用者が選択するデータ範囲も、色んなパターンを想定する必要があります。
エクセルが標準で搭載している並び替えツールですと、残念ながらその多様性に対応することは出来ません。
今回作成している並び替えマクロツールでは、選択できる並び替え範囲をもっと柔軟に設定できるようにしていきます。
「途中に空白行が存在しても範囲指定を行なえる。」とか、「結合セルがあっても範囲指定できる。」を考えていきます。
並び替えマクロ 記事階層
- マクロツール使い方と無料ダウンロード
- マクロツール作成手順
- 並び替えマクロを作成するVBAコードの概要
- 条件設定ボタンとボックスを配置するユーザーフォームのデザイン
- UserFormに設置したコントロールのイベントコードを記述する
- 別シートにまたぐのは可能?並び替えのコード設計
- 条件入力用のユーザーフォーム 表示・非表示と値の保存
- セル範囲内の空白行や結合にも対応したSortオブジェクトVBA
- 複数列に自由にキーを設定するVBA。Sort条件設定のコード
- 複数の背景色キーを指定できるVBAコードの組み立て
- 種類の違うKeyの同時指定はどちらが優先?VBAでは記述順
- 共有できない問題も解決!ユーザー設定リストの外部ファイル導入法
- 複数条件をまとめるプロシージャーを作成する
- 結果の切り出し機能 必要範囲をコピーし別シートに張付け
- 簡単に並びを解除するリスタート機能。再実行も即可能になる
- 並び替えマクロツール作成の全コード集
- 並び替えマクロを作成するVBAコードの概要
- 実際に使ってみる
この記事番号は5番です。
コンテンツ
想定される並び替えの選択範囲を類型化する
利用者が使用すると想定される、並び替えの選択範囲を4つのパターンに分類しました。
この4つのパターンの選択は、エクセル並び替えマクロツール利用者に、ユーザーフォーム「ソートナビゲーター」で選択していただきます。
①並び替えのデータ範囲が、一つの塊になっている
エクセル標準の並び替えツールのパターンになります。
標準的に想定されているデータ並び替えのエリアです。
エクセル並び替えマクロツールでも、このエリア設定は自動検出されます。
連続したデータで繋がっている部分全てが選択されます。
②並び替え範囲の間に全くの空白行が存在する
空白行を無視する対策が必要です。
エクセル標準の並び替えツールだと、21行目の空白行で並び替え範囲検出が停止します。
エクセル並び替えマクロツールですと、空白行を超えて下のデータ塊も含めることが出来ます。
この赤枠のようなエリア設定が可能です。並び替え後の空白行は、並び替えエリアの最下段に移ります。
③空白行で上下を挟まれた、全体の中の一部のデータ範囲
選択範囲のデータはひと塊になるので、①パターンの応用的な範囲設定です。
データシートで、全体の中で空白行で挟まれた中のデータ塊を選択します。
赤枠のエリアを選択します。並び替えは赤枠エリアだけで、このエリアの上下のデータ塊は並び替えを行ないません。
④並び替えのデータ範囲は、より大きなデータ塊の一部分
選択範囲はイメージ的には、「全国版の何かのデータ集で、あるテーマ部分で、東京都の新宿区のその特定のテーマについてのデータだけを並び替えたい!」のような
このパターン④を使えば、セル結合データ表に対しても、並び替えが可能になるケースが増えるでしょう。
セル結合の何が並び替えを阻害しているのかというと・・・
並び替え範囲指定内(赤罫線枠内)にセルの結合部分があるからです。
このパターン④の「並び替え範囲部分指定」を利用すれば、セル結合を含まない部分の並び替えが可能になります。
パターン④並び替えの注意点
データ塊の一部分だけの並べ替えを行います。並び替えに際しては、範囲指定内でその内部に、デフォルトの並び順を復元できるデータ番号(数字の昇順)などがデータとして含まれている必要があります。
なので、赤枠内の並び替え後に、元の状態に復元できない場合は、データ全体の内容の信ぴょう性に影響を及ぼす可能性が大きいです。(データを壊すことになります。)
赤枠内のみ並び替えを行ないます。赤枠以外では並び替えの影響はありません。
並び替え後の、元並びへの復元機能
「リスタート実行」機能
エクセル並び替えマクロツールには、データの並び替え後にその状態を元に戻す機能を付けています。
ただし、その機能を正常に実行するためには、
必要条件として、並び替えをする元データが、A列にID番号やデータ番号があり昇順に並んでいる必要があります。
この条件を満たしていなければ、データを並び替え以前の状態に戻すことは不可能になります。
また、パターン④の選択時に、『 ” データを壊す可能性がある” 』という警告表示が表示されても実行した並び替えに対しては、この復元機能を利用することはできません。
範囲の選択パターンでマクロを設計 そのVBAコード
基本的に、並び替え範囲の設定はユーザーフォーム「ソートナビゲーター」に、マウスクリックで行います。キーボードからの手入力は基本的に行いません。
マクロツールの利用者が、並び替えを行なうエリア内のセルをマウスクリックで選択し、
プログラム側がCurrentRegionプロパティで、並び替え範囲を掌握します。(すべての範囲選択パターンに対してではないですが)
並び替え範囲の始点チェックのVBAコード
広大なエクセルシートで、並び替えマクロツールの利用者がマウスクリックで選択した1個のセルが、
本当に、その利用者が自分の意志でデータの並び替えをしようとしている、選択範囲の始点セルか?
なんて、こちらでは分かるはずもありません。
まさにそこは、「確かにそのセルを選択しました。」という、信じることでしかありません。
とは言うものの、最低限のエラーチェックは出来るようにVBAコードを組み立てておきます。
Functionプロシージャーを使用します。
メッセージボックスで始点セルの選択を促します。選択されなければプロシージャーを終了します。
ここでプロシージャーを終了しても、親のプロシージャーに戻ってVBAコードは実行され続けてしまいますので、親プロシージャーに戻すときにエラー終了の信号を付けて戻します。
親プロシージャーはそのエラー信号を受けて自身を終了させることになります。
利用者がマウスクリックした並び替え始点セルが、確かにデータエリア全体の中にあるかどうかをプログラムがチェックします。
先回紹介した「データシート把握」プロシージャーから取り出したRangeオブジェクト変数「ADRange」内に今回取り出したRangeオブジェクト変数「STRC」が含まれていればコード通過、含まれていなければエラー停止します。
内包するかどうかの判別はVBA関数の「Intersect」で判定しています。
'並び替えデータエリア把握
Function STRC() As Range
ErEnd = False
Set STRC = Nothing
On Error Resume Next
Set STRC = Application.InputBox("見出し行も含めて並び替え" & _
"ブロックで" & vbCrLf & "始点となるセルを指定して" & _
"ください。", Title:="始まりのセル指定", Type:=8)
If Not STRC Is Nothing Then
STRC.Activate
End If
If Err.Number > 0 Then
MsgBox "キャンセルされました。終了します。"
ErEnd = True
Exit Function
End If
On Error GoTo 0
STRCr = STRC.Row
STRCc = STRC.Column
If Application.Intersect(ADRange, STRC) Is Nothing Then
MsgBox "シートのデータ範囲外のセルを指定しました。" _
& vbCrLf & "再指定してください。", _
vbExclamation, "再指定"
ErEnd = True
Exit Function
End If
End Function
選択範囲パターン①のVBAコード
この選択範囲のパターンが一番シンプルなVBAコードになります。
先の「並び替えのデータエリアを把握」で取り出したRangeオブジェクト変数「STRC」を使って、それが含まれる範囲をCurrentRegionで取得します。
この取得した選択範囲のエリアをRangeオブジェクト変数「SortAreaA」に代入します。
Function SortAreaA() As Range
On Error Resume Next
Set SortAreaA = STRC.CurrentRegion
If ErEnd = True Then
MsgBox "この操作は、条件設定の不備により実行されません。"
Exit Function
End If
SortAreaA.Select
On Error GoTo 0
End Function
選択範囲パターン②のVBAコード
並び替えするデータの選択範囲の中に空白行がある場合です。
並び替え範囲の選択の指定方法は、
最上段のデータブロックの始点セルは既出の変数「ADRange」で押さえることが出来ていますので、並び替えデータブロックの最下段の終点セルを押さえることで可能になります。
利用者に、インプットボックスで最下段のデータブロックの中の一つのセルをクリックしてもらいます。
そのクリックされたセルが確かにデータエリア全体の中にあるかどうかをIntersect関数でチェックします。
CurrenRegionから最下段データブロックの終点セルを取得します。
始点セルから終点セルまでの並び替え範囲をRangeオブジェクト変数「SortAreaB」に代入します。
Function SortAreaB() As Range
Dim SortAreaAn, LDB, LDBR As Range
Dim LDBEr, LDBEc As Long
On Error Resume Next
Set LDB = Application.InputBox("並び替えする最後尾のデータ" & _
"ブロック内で、" & vbCrLf & "いずれかのセルをクリック" & _
"してください。" & vbCrLf & "セル位置に基づいて検索" & _
"エリアをセットします。" & vbCrLf & " " & vbCrLf & _
"セルを置き直しする場合は「キャンセル」を選択してくだ" & _
"さい。", Title:="最後尾データブロックの指定", Type:=8)
If Not LDB Is Nothing Then
LDB.Activate
End If
If Err.Number > 0 Then
MsgBox "キャンセルされました。終了します。"
ErEnd = True
Exit Function
End If
On Error GoTo 0
Set LDBR = LDB.CurrentRegion
LDBEr = LDBR.Row + LDBR.CurrentRegion.Rows.Count - 1
LDBEc = LDBR.Column + LDBR.CurrentRegion.Columns.Count - 1
If Application.Intersect(ADRange, LDBR) Is Nothing Then
MsgBox "シートのデータ範囲外のセルを指定しました。" _
& vbCrLf & "再指定してください。", _
vbExclamation, "再指定"
ErEnd = True
Exit Function
End If
Set SortAreaB = Range(Cells(ADRange.Row, ADRange.Column) _
, Cells(LDBEr, LDBEc))
SortAreaB.Select
End Function
選択範囲パターン③のVBAコード
上下を空白行で挟まれたエリアの並び替えの場合の想定です。
並び替えを行なう範囲の中のいずれかのセルを選択することでその並び替え範囲を特定します。
利用者に、インプットボックスで並び替えをするデータブロックの中の一つのセルをクリックしてもらいます。
そのクリックされたセルが確かにデータエリア全体の中にあるかどうかをIntersect関数でチェックします。
CurrenRegionから並び替え範囲を取得します。
その並び替え範囲をRangeオブジェクト変数「SortAreaC」に代入します。
Function SortAreaC() As Range
Dim LDB2, LDB2R As Range
On Error Resume Next
Set LDB2 = Application.InputBox("並び替えするデータ" & _
"ブロック内で、" & vbCrLf & "いずれかのセルをクリック" & _
"してください。" & vbCrLf & "セル位置に基づいて検索" & _
"エリアをセットします。" & vbCrLf & " " & vbCrLf & "セル" & _
"を置き直しする場合は「キャンセル」を選択してください。", _
Title:="データブロックの指定", Type:=8)
If Not LDB2 Is Nothing Then
LDB2.Activate
End If
If Err.Number > 0 Then
MsgBox "キャンセルされました。終了します。"
ErEnd = True
Exit Function
End If
On Error GoTo 0
Set LDB2R = LDB2.CurrentRegion
If Application.Intersect(ADRange, LDB2R) Is Nothing Then
MsgBox "シートのデータ範囲外のセルを指定しました。" _
& vbCrLf & "再指定してください。", vbExclamation, "再指定"
ErEnd = True
Exit Function
End If
Set SortAreaC = LDB2.CurrentRegion
SortAreaC.Select
End Function
選択範囲パターン④のVBAコード
利用者によって、この選択範囲パターンが選択されると、まず「並び替え範囲部分指定」プロシージャーが呼び出され、Rangeオブジェクト変数「InpAreaV」に並び替え範囲が代入されます。
その変数「InpAreaV」が、このFunctionプロシージャーによって「SortAreaD」という4番目の範囲指定の変数として格納されます。
並び替え範囲のRangeオブジェクト変数「InpAreaV」をRangeオブジェクト変数「SortAreaD」に代入します。
Function SortAreaD() As Range
If ErEnd = True Then Exit Function
Set SortAreaD = InpAreaV
End Function
ユーザーフォーム「ソートナビゲーター」の中の「部分範囲指定実行」ボタンが押されると、
並び替え範囲の部分指定のためのインプットボックスが表示されます。そしてマウス操作で範囲を指定します。
データエリアのデータの列幅と部分指定したデ^他の列幅が異なる場合は、警告表示があります。
インプットボックスで部分指定エリアを入力します。(マウスでの範囲指定が楽です)
「ソートナビゲーター」のテキストボックスにも範囲表示されます。
パターン④概念図のような、並び替え範囲部分指定の列幅がデータ本体の列幅と異なる場合は、
” データを壊す可能性がある” という警告を表示します。そのまま続行すれば、指定キーでその指定部分だけ並び替えが実行されることになります。
部分指定エリアが、データ全体の列幅と同じ場合は警告表示はされません。
また同時に、部分指定した並ぶ替え範囲を太い罫線で枠囲みを行い、罫線データを取得します。
Sub 並び替え範囲部分指定()
Dim ANS As Long
AreaVAlert = False
Set InpAreaV = Nothing
ソートナビゲーター.部分範囲指定表示.Value = ""
On Error Resume Next
Set InpAreaV = Application.InputBox("並び替え範囲を指定" & _
"してください。", Title:="並び替え範囲指定", Type:=8)
If Err.Number > 0 Then
MsgBox "キャンセルされました。終了します。"
ErEnd = True
Exit Sub
End If
ソートナビゲーター.部分範囲指定表示.Value = _
InpAreaV.Address(False, False)
On Error GoTo 0
With InpAreaV
If Not (Cells(.Row, .Column).CurrentRegion.Columns.Count _
= InpAreaV.Columns.Count And Cells(.Row, .Column) _
.CurrentRegion.Column = InpAreaV.Column) Then
AreaVAlert = True
ANS = MsgBox("このまま並び替えを行うとデータを壊す" & _
"可能性があります。" & vbCrLf & "続けますか?", _
vbYesNo + vbQuestion, "確認")
End If
If ANS = 7 Then
Exit Sub
End If
End With
Set Bodu = InpAreaV.Borders(xlEdgeTop)
Set Bodd = InpAreaV.Borders(xlEdgeBottom)
Set Bodl = InpAreaV.Borders(xlEdgeLeft)
Set Bodr = InpAreaV.Borders(xlEdgeRight)
BoduL = Bodu.LineStyle
BoduW = Bodu.Weight
BoddL = Bodd.LineStyle
BoddW = Bodd.Weight
BodlL = Bodl.LineStyle
BodlW = Bodl.Weight
BodrL = Bodr.LineStyle
BodrW = Bodr.Weight
InpAreaV.BorderAround LineStyle:=xlContinuous, Weight:=xlThick
End Sub
この選択範囲パターン④で変数「AreaVAlert」がTrueの時は、「リスタート実行」機能が実行されません。
並び替え範囲部分指定を行った時、その並び替え実行中に、どこを範囲指定しているかを明確にしておくための機能です。
選択範囲の外枠を太い罫線実線で囲みます。
メモリに部分指定範囲が保存されていれば、いつでも枠囲みする前の罫線状態に復元することが出来ます。
メモリに保存(変数値がリセットや上書きされていない状態)の間の操作が必要です。
Sub 並び替え範囲部分指定罫線消去()
If ErEnd = True Then Exit Sub
If InpAreaV Is Nothing Then
MsgBox "今回は消去する罫線がないか、または、手作業での" & _
"消去になります。"
Exit Sub
End If
InpAreaV.Select
With InpAreaV.Borders(xlEdgeTop)
If BoduL = -4142 Then
.LineStyle = xlLineStyleNone
Else
.LineStyle = BoduL
.Weight = BoduW
End If
End With
With InpAreaV.Borders(xlEdgeBottom)
If BoddL = -4142 Then
.LineStyle = xlLineStyleNone
Else
.LineStyle = BoddL
.Weight = BoddW
End If
End With
With InpAreaV.Borders(xlEdgeLeft)
If BodlL = -4142 Then
.LineStyle = xlLineStyleNone
Else
.LineStyle = BodlL
.Weight = BodlW
End If
End With
With InpAreaV.Borders(xlEdgeRight)
If BodrL = -4142 Then
.LineStyle = xlLineStyleNone
Else
.LineStyle = BodrL
.Weight = BodrW
End If
End With
End Sub
範囲選択に対応したマクロコードの設計 まとめ
並び替えの範囲選択を、大きく4つの範囲選択パターンに分類しました。
この4つのパターンで、ほぼ範囲選択は対応できると思います。
複合パターンがある場合は、パターン④の応用として対応します。
選択範囲をRangeオブジェクト変数に代入する時(Setステートメントを使用する時)に、選択範囲に不正があるとエラーストップが発生します。
エラー発生の頻度的にはよく発生する方だと思います。この時にエラーを処理するコードを必ず記述しておくことが必要ですので忘れないようにしましょう。
また、並び替え範囲の部分指定で設定した範囲を分かりやすくするための罫線での範囲枠は、結構有効利用できると思います。
エクセルVBAを独習するのに参考書は欠かせません。 参考書選びは自分に合った「相棒」にできるものを選んでいきたいです。
エクセルVBAの独習でおすすめ参考書を7冊選ぶ。良書との出会いは大切です今回の記事はここまでです。 最後までご覧いただき有難うございました。
アンケートでポイ活しよう!!
アンケートに答えれば答えるほど ”使える” ポイントがたまります。