2022/08/01

ListObjectの並べ替え

ListObjectについて、下記のようなシリーズで説明しています。
 ・ListObjectの作成と概要
 ・ListObjectの並べ替え  ←今回
 ・ListObjectの絞り込み
 ・ListObjectの絞り込みの解除
 ・ListObjectの絞り込みデータの配列化
 ・ListObjectのデータ追加
 ・ListObjectのデータ変更
 ・ListObjectのデータ削除

今回は、「ListObjectオブジェクト」の並べ替えについて説明します。

1.手動でのテーブルの並べ替え

まず手動で並べ替えをする手順を確認します。
通常は図1のように、並べ替え(ソート)をしたい列をセル選択し、リボンの「ホーム」タブ→「編集」グループ→「並べ替えとフィルター」をクリックすることで表示される「昇順」「降順」を選択クリックします。
単純な並べ替え操作
図1


また、図2のようにテーブルの列先頭にある「フィルターボタン(下三角形)フィルターボタン(通常)」をクリックすることで、同様の「昇順」「降順」が実行できます。
単純な並べ替え操作
図2


並べ替えをした列のフィルターボタンは、昇順の場合には「フィルターボタン(昇順)」と上矢印付きのボタンとなり、降順の場合には「フィルターボタン(降順)」と下矢印付きのボタンとなります。
また絞り込みと併行して並べ替えを行っている時には、昇順の場合は「フィルターボタン(昇順+絞り込み)」となり、降順の場合は「フィルターボタン(降順+絞り込み)」となります。

但し並べ替えには「昇順」「降順」の選択だけでなく、図3のようにオプションとしていくつかの選択肢が存在します。詳細はマクロの説明の中で説明していきます。
詳細な並べ替え操作
図3


2.マクロでのテーブルの並べ替え

まず「テーブルを並べ替えるプロシージャ」を示し、その中で各行の機能を説明していきます。
図4は、引数に「操作するテーブル」「操作する列」「昇順または降順」を指定して呼び出すことにより、テーブルを並べ替えるものです。
  1. '========== ⇩(1) テーブルの並べ替え ============
  2. Sub TableSort(T As ListObject, col As Variant, S As Long)
  3.  '// T :操作対象のListObjectオブジェクト
  4.  '// col:並べ替え列。列名(文字列)でも列位置(整数)でもOK
  5.  '// S :並べ替え順。昇順=1(xlAscending),降順=2(xlDescending)
  6.  With T.Sort
  7.   With .SortFields
  8.    .Clear
  9.    .Add key:=T.ListColumns(col).Range, _
  10.       SortOn:=xlSortOnValues, _
  11.       Order:=S, _
  12.       CustomOrder:="", _
  13.       DataOption:=xlSortNormal
  14.   End With
  15.   .Header = xlYes
  16.   .MatchCase = False
  17.   .Orientation = xlTopToBottom
  18.   .SortMethod = xlPinYin
  19.   .Apply
  20.  End With
  21. End Sub
図4


まず今回の引数は以下の3つとしました。
 第一引数(T) :操作対象のListObjectオブジェクト
 第二引数(col):並べ替え列。列名(文字列)でも列位置(整数)でもOKです
 第三引数(S) :並べ替え順。昇順=1(xlAscending),降順=2(xlDescending)。数値でも定数でもOKです。
この3つを指定して、テーブルの並べ替えを行うプロシージャです。他にも設定可能なプロパティはありますが、図4では「既定値」を設定しています。必要ならば引数に設定したり、プロシージャ内のプロパティ値を変更して下さい。

06行目「With T.Sort」では、並べ替えの対象を設定しています。今回の並べ替えの対象は、第一引数で得たListObjectオブジェクトです。
06行目の最後の「Sort」はオブジェクトです。このSortオブジェクトには設定可能なプロパティが、図5のように5つあります。
Sortの設定可能プロパティ
プロパティ内容
Header先頭行を見出しとするか
MatchCase大文字小文字の区別
Orientation並べ替えの方向
SortFields並べ替えのキー値など
SortMethodふりがなを使うか
図5


2ー1.SortFieldsプロパティ

「SortFields」を07行目「With .SortFields」で囲まれた08~13行目で設定します。
SortFieldsは、手動で言うところの「並べ替えレベル」に相当する条件データです。「並べ替えレベル」は、図6の様にテーブル内のどこかのセルを選択し、「データ」タブ→「並べ替えとフィルター」グループ→「並べ替え」ボタンをクリックした時に表示される「並べ替え」ダイアログ上に表示されます。
並べ替えの対象と並べ替えレベル
図6



まず08行目「.Clear」メソッドで「並べ替えレベル」を初期化します。図6の並べ替えダイアログ上の条件データを全て消去する形です。以前実行した並べ替えの条件をクリアしておかないと、狙いの通りの並べ替えが出来ないので必須です。
なお、並び替えを解除するには、このClearメソッドを実行させます。

次に09~13行目の「.Add」メソッドで、新たな並べ替えレベルを作成します。Addには以下のパラメータを指定します。
Sort.Addのパラメータ
名前内容
KeyRange並べ替えの列(必須)
SortOnVariant並べ替えのキー
OrderVariant並べ替え順序
CustomOrderVariantユーザー指定の並べ替え順序
DataOptionVariantデータオプション
図7


2-1-1.Keyパラメータ
「Key」パラメータは必須項目で、今回はプロシージャが引数で受け取った「ListObject(T)」の「並べ替え列(col)」を指定しますので「key:=T.ListColumns(col).Range」となります。

colは「列名(文字列)」または「列位置(整数)」を想定しています。例えば「"Title"」または「2」が来るわけですが、ListColumns(col)に代入すると「ListColumns("Title")」「ListColumns(2)」となり、どちらも成立することになります。
どちらでも成立させるために、引数colのデータ型はVariant型にしていますが、「どちらかに固定したい」のであれば、String型・Long型(Integer型でも問題はなさそう)に引数型を変更して下さい。

2-1-2.SortOnパラメータ
「SortOn」は、図6の並べ替えダイアログでは中央の「並べ替えのキー」に対応します。「キー」という言葉が使われているので「Key」との区別が分かりにくいのですが、指定する値は図8のようになり「セルのどの情報を使って並べ替えをするか」を指示することになります。通常は「値(xlSortOnValues)」で良さそうです。
今回も「SortOn:=xlSortOnValues」を設定していますが、既定値ですので省略も可です。
SortOn
定数内容
xlSortOnValues0値(既定値)
xlSortOnCellColor1セルの色
xlSortOnFontColor2フォントの色
xlSortOnIcon3アイコン
図8


2-1-3.Orderパラメータ
「Order」では並べ替え順序を設定します。図6の並べ替えダイアログでは右側の「順序」に対応します。値としては、図9の定数・値を設定します。今回は「第三引数(S)で指定された順序」にするため、「Order:=S」としています。逆に言うと、図9の値を第三引数に指定することになります。
Order
定数内容
xlAscending1昇順で並べ替え(既定値)
xlDescending2降順で並べ替え
図9


2-1-4.CustomOrderパラメータ
「CustomOrder」は、ユーザー指定の並べ替え順序です。指定の方法は2種類あるようです。
まず1つは「CustomOrder:="道,エデンの東,タイムマシン"」のように、カンマ区切りの文字列で指定する方法です。
例えば、図10のテーブルの2列目(Title列)に対して「CustomOrder:="道,エデンの東,タイムマシン"」を設定し昇順で並べ替えると、図10の右側のように「道,エデンの東,タイムマシン」が優先されて並び替わります。
CustomOrder指定で、優先をつけられる
図10


リストに無い項目は、通常の並べ替えルールに従って並び変わります。なおこの文字列には、「*(アスタリスク)」や「?(クエスチョンマーク)」のワイルドカードは使えないようで、「"道"が含まれているもの」みたいな並べ替えは出来ないようです。
また、文字列は1つだけでもOKなので、常に先頭に表示したいデータなどがある場合には、活用できるかもしれません。

なお「カンマ区切りの文字列を指定」としましたが、「CustomOrder:="3,5,7"」みたいに数値をカンマで区切った文字列を指定して数値列(図10で言えば1列目)を並べ替えると、「3」「5」「7」が上にきます。
注意点として、図10は「昇順」なので指定したものが上に来ますが、「降順」で並べ替えをすると逆に「下側から」並びます。

もう1つは「CustomOrder:=5」のように数値を直接指定する方法です。これは「ユーザー設定リスト(図11)」のリスト番号を指定したことになります。
ユーザー設定リストのデータをCustomOrderで使う
図11


「ユーザー設定リスト」は、Excelリボンの「ファイル」タブ→「オプション」→「詳細設定」→「全般」→「ユーザー設定リストの編集」をクリックする事で表示されます。また、図6で表示される並べ替えダイアログの「順序」列のドロップダウンからも表示できます(図12)。
ユーザー設定リストの選択
図12


「ユーザー設定リストの一番上は「新しいリスト」となっており、実データはその下からとなっていますが、これが1番になるようです。図11で言えば、5番を選択(CustomOrder:=5)すれば、「CustomOrder:="日,月,火,水,木,金,土"」としたことになります。

プロシージャ内(図4の12行目)では「CustomOrder:=""」としていますが、これは「ユーザー指定=無し」という意味になります。「CustomOrder:=0」も「ユーザー設定リストのゼロ番=ユーザー指定無し」と判断してくれるようです。

2-1-5.DataOptionパラメータ
「DataOption」は、テキストを並べ替える方法を指定します。図13の定数・値を設定します。
このパラメータは、手動(図3)ではどうやって設定するのか分かりませんでした。
DataOption
定数内容
xlSortNormal0数値とテキストを別々に並べ替え(既定値)
xlSortTextAsNumbers1テキストを数値データとして並べ替え
図13


「xlSortTextAsNumbers」は「文字列を数字として」扱いますので、例えば「文字列にした数値(先頭にアポストロフィを付いたもの)」が1から10まで並んでいるテーブルでは、「文字列を数値」にしますので、ちゃんと「1から10の順序」で並びます。
一方「xlSortNormal」を指定した場合には「文字列にした数値」は文字列ですので、まず先頭文字列で判断し「1,10,2,3,4,5,6,7,8,9」という順序で並べます。
数値を文字列として入力してある場合や、数値と文字列が混在している場合は「DataOption:=xlSortTextAsNumbers」の方が分かり易く並ぶかもしれません。

ここまででSortField(図6の1つのキーに対する並べ替え分)への設定が完了です。複数の条件を設定(例えば1列目を第一優先でソートし、2列目を第二優先ソートする等)するには、更にAddメソッドを実行する事になります。

2-2.Headerプロパティ

Headerプロパティは図5の表の通り「先頭行を見出しとして使用するかどうか」のプロパティで、図14の定数・値を設定します。図4の15行目では「.Header = xlYes」と設定しています。

Header
定数内容
xlGuess0Excel が自動的に設定
xlYes1見出しとして使用(テーブルの場合の既定値)
xlNo2見出しとして使用しない(既定値)
図14


Headerに設定する値は、通常のRangeオブジェクトのSortの場合は「xlNo」が既定値になるのですが、ListObjectの場合には「xlYes」が既定値となり、xlNoは選択できません。これは、手動で並べ替えを行う際にも、図15のように「先頭行をデータの見出しとして使用する」のチェックを外すことができないことからも分かります。
並べ替えオプションの設定
図15


実際に「Header = xlNo」を設定すると実行時エラーとなります(xlGuessは使えるようです)。
逆に「Header = xlYes」が既定値ですから設定しなくてもOKですが、「マクロ記録」で取得した並べ替えのコードには、このHeaderと後で紹介するOrientationだけは記録されるようです。

2-3.MatchCaseプロパティ

「MatchCase」は、大文字と小文字を区別するか否かの設定です。設定値は図16の値で、既定値は「大文字と小文字を区別しない」です。
MatchCase
定数内容
-True大文字と小文字を区別する
-False大文字と小文字を区別しない(既定値)
図16


手動では、図15の並べ替えオプションのダイアログ一番上の「大文字と小文字を区別する」のチェックボックスで操作する事になります。

2-4.Orientationプロパティ

「Orientation」は、並べ替えの方向の設定です。設定値は図17の定数・値です。
Orientation
定数内容
xlSortColumns(又はxlTopToBottom)1行単位で並べ替え(既定値)
xlSortRows(又はxlLeftToRight)2列単位で並べ替え
図17


このOrientationも、図15のオプション「方向」のところで分かる様に「列単位(xlSortRows(又はxlLeftToRight))」は選択できず、指定してしまうとエラーが発生します。よって、指定できるのは「行単位」のみです。
マクロ記録では「.Orientation = xlTopToBottom」とコード化されます。

2-5.SortMethodプロパティ

「SortMethod」は、日本語を「ふりがなで並べるか、文字コードで並べるか」の設定です。設定値は図18の2種です。
SortMethod
定数内容
xlPinYin1日本語をふりがなで並べる(既定値)
xlStroke2日本語を文字コードで並べる
図18


例えば、漢字で「青」「赤」「秋」は、「あお」「あか」「あき」と「訓読みで入力する」と「訓読みのふりがな」が振られます(関数PHONETICを使用して確認)。
一方、文字コードは図19のように「訓読みの順番とは異なる」ことが分かります。これは文字コードは音読みの順番で振っているためのようです(全てがこの理論で並ぶ訳では無いようです)。
漢字訓読み音読み文字コード(SJIS)
あお ①セイ ②0x90c2 ②
あか ②セキ ③0x90d4 ③
あき ③シュウ ①0x8f48 ①
図19


ですので、訓読みで漢字を入力している場合に「SortMethod = xlPinYin」で並べ替えれば「青」→「赤」→「秋」の順番で並びますし、「SortMethod = xlStroke」で並べ替えれば「秋」→「青」→「赤」の順番で並びます。

但し「青」「赤」「秋」という漢字を「セイ」「セキ」「シュウ」とタイプして入力した場合には、「SortMethod = xlPinYin」で並べ替えても「秋」→「青」→「赤」の順番で並ぶのです。これは関数PHONETICで得られるふりがなが「セイ」「セキ」「シュウ」となっている事からも頷けます。
また「マクロ側からセルに文字を入力する(=セル値に漢字を設定する)」と、ふりがな(関数PHONETIC)の戻り値が「漢字そのもの」になってしまいます(=ふりがなが無い?)。この状態で「SortMethod = xlPinYin」で並べ替えを行っても「文字コードの順番で並ぶ」結果となります。つまり「音読みで入力した」事になるようです。

以上のように「xlPinYin」は、「どのように入力された漢字か」で順番が変わってきてしまうので、注意が必要です。特に「フォームで入力した文字列をマクロを使ってテーブルに書き込む」ような場合は、「xlPinYin」の設定が活かされない事になるようです。

以上で、Sortオブジェクトに対するプロパティの設定は完了です。

2-6.Applyメソッド

設定が出来たところで20行目のSortオブジェクト「Applyメソッド」で並べ替えを実行します。

2-7.簡易版 並べ替えプロシージャ

以上のように、並べ替え(Sort)は色々な設定が出来ますが、「ほとんど既定の設定でOK」という場合は、図20のような短いコードとなります。昇順か降順かだけが指定できるものです。
  1. '========== ⇩(2) テーブルの並べ替え簡略版 ============
  2. Public Sub TableSort2(T As ListObject, col As Variant, S As Long)
  3.  With T.Sort
  4.   .SortFields.Clear
  5.   .SortFields.Add key:=T.ListColumns(col).Range, Order:=S
  6.   .Apply
  7.  End With
  8. End Sub
図20


アプリ実例

DVD等の内容・保管場所等管理システム
ToDoリストで個人タスク管理
会社番号検索システム