名前を得点順に並べる — データとキーの対応を守ろう

LWP | 名前を得点順に並べる―データとキーの対応を守ろう

名前を得点順に並べる―データとキーの対応を守ろう

TakiLibのsortSortedで、比較する値と返す値を分ける

ストーリー

これはTakiLib(滝Lib)を使うVBA記事です。名前を返したいシャケモンと、比較する値を確かめるアユさんが、名前と得点の対応を守って並べ替える方法を考えます。

参照した公開安定版はTakiLib 3.5.4。sortSortedはTakiLibの独自関数です。例は一対一に対応した同型の数値キーを使い、結果は現行ソースからの予測として示します。

1 名前と得点は対応するペア

返したい名前と、比較したい得点を対応させる。

図1|返したい名前と、比較したい得点を対応させる。

2 昇順と降順で名前も動く

比較する順序を決め、対応するデータを返す。

図2|比較する順序を決め、対応するデータを返す。

3 交換でも併合でもペアを守る

ソーターの手法が違っても、対応関係を維持する。

図3|ソーターの手法が違っても、対応関係を維持する。

4 入口の既定値は実装で確かめる

キー省略時とソーター省略時の動きを分けて確かめる。

図4|キー省略時とソーター省略時の動きを分けて確かめる。

5 3件と2件は並べる前に止める

件数の一致を呼出し前に検査し、黙った欠落を防ぐ。

図5|件数の一致を呼出し前に検査し、黙った欠落を防ぐ。

6 同点の順序まで必要ですか

安定性は名前だけで判断せず、実際の降順処理まで確かめる。

図6|安定性は名前だけで判断せず、実際の降順処理まで確かめる。

まとめ

並べ替えでは、比較するキーだけでなく、返したいデータとの対応を保ちます。名前A・B・Cに得点70・90・80が対応するなら、昇順でA,C,B、降順でB,C,Aです。件数・型・同点順序・変更範囲も含めてソーターを選びます。

今回の仕掛け

sortSortedは入力を配列へ変換し、選んだソーターへデータと基準列を渡します。キーを省略するとデータ自身が基準です。3.5.4の実行文が指定する既定ソーターはsortShaker。説明コメントにsortInsertionという旧記述が残るため、実装を照合して判断しました。

現行のsortShakerはキーを比較し、交換時にデータも一緒に動かします。sortMergeはデータとキーをペアにし、併合後にデータを取り出します。両者とも降順を昇順結果の全体反転で作るため、同点の元順序まで保証するとはいえません。

データ3件とキー2件の不一致は、呼出し前に検出します。sortSorted自身が全条件を検査するという保証ではありません。下位ソーターがError値を返す場合は、sortSortedが実行時エラーへ変えて伝えます。

今回の文字列・数値配列はソーター内部の配列コピーで処理されます。オブジェクトを含む入力の深いコピー、空入力、異なる下限や混在型まで、同じ条件として一般化しません。

今回のソースコードのサンプル

サンプルコード 名前を得点の昇順で返す

01

Public Sub DemoSortNames()

02

    Dim names As Variant, scores As Variant, sorted As Variant

03

    names = Array("A", "B", "C")

04

    scores = Array(70, 90, 80)

05

    If UBound(names) - LBound(names) <> UBound(scores) - LBound(scores) Then

06

        Err.Raise vbObjectError + 1, , "データとキーの件数が違います"

07

    End If

08

    sorted = sortSorted(names, scores, 1)

09

    Debug.Print Join(sorted, ",")

10

End Sub

関数の説明

sortSorted(a_seq, a_seq_base, a_order, a_sorter)は、返したいデータ、比較基準、順序、ソーター名を受けます。最後の三引数は省略可能です。順序は1が昇順、-1が降順で、既定ソーターはsortShakerです。

コードの説明

namesとscoresを同じ添字で対応させ、非空のArrayである本例では上下限の差から件数一致を確かめます。sortSortedへ順序1を渡し、戻った名前配列をJoinで表示します。汎用入力検査や空配列への対応を行うコードではありません。

入力・概要

公開安定版3.5.4の通常CP932版taki3lib.basを同じブックへ導入済みのWindowsデスクトップExcel VBAを前提に、別の標準モジュールへ貼り付ける例です。AI参照専用taki3libUTF8.basを導入元にしません。今回Excelでの実行は未実施です。

結果

予測される表示はA,C,Bです。第三引数を-1へ変えた場合はB,C,Aです。

読むポイント

名前を比較していないことと、キーの動きに名前を対応させていることを見てください。同点順序が業務条件なら、降順の反転や追加キーを含めて別途設計します。

sortSortedの実装へ戻る

公開安定版3.5.4の通常CP932版から取得した、直接呼び出す関数一段の読解用抜粋です。説明コメントと空行を省き、実行文を保持しています。依存関数はTakiLib本体にあります。導入済みの同名関数を再度貼り付ける必要はありません。

サンプルコード sortSortedの読解用ソース

01

Public Function sortSorted( _

02

                        a_seq, _

03

                        Optional a_seq_base, _

04

                        Optional ByVal a_order, _

05

                        Optional ByVal a_sorter)

06

    Call valueSetDefault(a_sorter, "sortShaker")

07

    If TK3_ASSERT Then Call langAssert(hasCStrAffinity(a_sorter), TK3_ERROR_ARGUMENT)

08

    Dim x_seq:

09

        x_seq = seqToArray(a_seq)

10

    Dim x_seq_base:

11

        If valueIsMissing(a_seq_base) Then

12

            x_seq_base = x_seq

13

        Else

14

            x_seq_base = seqToArray(a_seq_base)

15

        End If

16

    Dim xret:

17

        xret = langRun(a_sorter, x_seq, x_seq_base, a_order)

18

    If typeIsError(xret) Then

19

        Err.Raise CLng(xret)

20

    Else

21

        sortSorted = xret

22

    End If

23

End Function

コードの説明

valueSetDefaultは省略ソーターをsortShakerへ補います。seqToArrayで入力を配列化し、キー省略時はデータ自身を使います。langRunがソーターを呼び、typeIsErrorならErr.Raiseでエラーを伝え、それ以外では結果を返します。

読むポイント

件数一致の検査はこの関数にはありません。呼出し側の検査と下位ソーターの振る舞いを分けて読みます。

TakiLibの著作権・ライセンス

The MIT License

Copyright (c) 2021 Kazuhiro Yamanaka

Permission is hereby granted, free of charge, to any person obtaining a

copy of this software and associated documentation files (the

"Software"), to deal in the Software without restriction, including

without limitation the rights to use, copy, modify, merge, publish,

distribute, sublicense, and/or sell copies of the Software, and to

permit persons to whom the Software is furnished to do so, subject to

the following conditions:

The above copyright notice and this permission notice shall be

included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,

EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF

MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE

LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION

OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION

WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

出典メモ

元ネタ:[採用原稿 260907_データと並べ替えキーを分ける.md](<C:/LWP/記事制作/01_記事ネタ/archive/260907_データと並べ替えキーを分ける_記事229採用稿.md>)。2026年10月4日に原稿全文と追補を確認し、中心主題を選んで再構成しました。同名の旧稿がarchiveに存在するため、今回の採用稿は先頭日付と本文を保持し、記事229の識別子を付けて保管しています。会社・人物・業務データは創作・説明用です。

技術の仕様は原資料と一次資料に照合しました。サンプルと図の結果はソース・仕様・計算に基づく予測で、Excel実機の動作確認済みとはしていません。

TakiLib公開安定版3.5.4のsortSorted・sortShaker・sortMergeを照合しました。通常CP932版のSHA-256はF65975918E83FEF102A474FA07D322CEAD3EEB3A142521B2435E2D5E7214B55Aです。

Copyright © 2026 LWP 山中 一弘

本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。