行列の交差する値をVBAで取得する、の別解②
昨日は料金表の中から、いくつかの条件に合致する料金を抽出する関数を作成してみた。
infoment.hatenablog.com
すると、ことりちゅんさんから、次のようなコメントをいただいた。
DictはStatic変数で良いかな。
・・・すみません、Static変数って、何ですか?
調べてみると、こちらで紹介されていた。
thom.hateblo.jp
(いつも、ありがとうございます)。
それにしても、何だこれは。何て便利なんだ。今までは、
- モジュール変数またはパブリック変数で辞書を宣言しておく。
- 辞書の中身が無い時だけ、辞書を作成する。
という手法を採っていた。方式としては変わらないが、Static変数で宣言することにより、作成した辞書の中身は保持されるようだ。
ついでに、料金表の範囲と条件の数も引数にした結果がこちら。
標準モジュール
Option Explicit ' 価格表用の辞書(連想配列) Function GetPlanDict(target_range As Range, _ label_r As Long, _ label_c As Long) As Dictionary Dim Dict As Dictionary Set Dict = New Dictionary Dim myKey As String Dim rSeq As Variant Dim cSeq As Variant Dim r As Long Dim c As Long ' 各値段に関する条件を、一旦配列に格納する。 For r = label_c + 1 To target_range.Rows.Count For c = label_r + 1 To target_range.Columns.Count ' 列の条件を配列に格納。 rSeq = target_range.Cells(r, 1).Resize(, label_c) ' 行の条件を配列に格納。 cSeq = target_range.Cells(1, c).Resize(label_r) ' 二次元配列を強制的に一次元配列に変換。 rSeq = WorksheetFunction.Transpose(rSeq) rSeq = WorksheetFunction.Transpose(rSeq) cSeq = WorksheetFunction.Transpose(cSeq) ' 配列内の文字を結合し、辞書用のキーとする。 myKey = Join(rSeq, vbNullString) & Join(cSeq, vbNullString) ' キーに対し、値段をアイテムとして登録する。 Dict(myKey) = target_range.Cells(r, c).Value Next Next Set GetPlanDict = Dict End Function ' 価格取得用ユーザー定義関数 Public Function 料金(支店 As String, _ 商品 As String, _ 年度 As String, _ プラン As String, _ 料金表の範囲 As Range, _ 行の条件数 As Long, _ 列の条件数 As Long) As Variant Static Dict As Dictionary If Dict Is Nothing Then Set Dict = GetPlanDict(料金表の範囲, 行の条件数, 列の条件数) End If Dim myKey As String myKey = 支店 & 商品 & 年度 & プラン If Dict.Exists(myKey) Then 料金 = Dict(myKey) Else 料金 = "指定エラー" End If End Function
汎用性が高まった分に釣り合わぬほどに、分り難さが激増してしまった(反省)。
参考まで。