前回書いた基礎編の続きです。実際に、業務アプリを書く場合を例に説明していきます。
ロット番号をMATCHする。
前提として、金属加工業で丸鋼からNC旋盤で部品を作成し、工程はロットで管理しているとします。
ロットは、年(4桁)ー機械番号(2桁)ー連番(3桁)とし、Excelのテーブルでデータを管理しています。
テーブル T1_ が検索先、テーブル T2_ を検索元、
ロット番号は、各テーブルの左端に、呼び出される関数はT2_の見出しが
LIの列にあるとし、列全体に関数 =MLOT(T1_,T2_) で埋められています。
Function MLOT(R1, R2)
MLOT = MP(R1, R2, 3, 3, 0, 0)
End Function
前回定義した、関数MPを使うと簡単ですね。返り値は、検索先データの行数です。行数がわかれば、
検索先からデータを持ってくるには、隣のセルあたりに 関数 =DI(T1_[製品名],[@LI])
とかすれば呼び出せるわけです。
3テーブルを使用し同じキーのデータを検索して集める。
実は、1行のテーブルはコントロールレコードとして使用できます。
テーブル T1_を検索先、テーブルT2_を検索キーを含むコントロールレコード、
テーブル T3_を検索結果が入るものとします。T1_,T2の左端は、製造番号(4桁)が入っています。T3_[L]に関数 =MPC(T1_,T2_,T3,1,1) で埋めます。
Function MPC(R1, R2, R3, Optional L = 2, Optional P = 1, Optional M1 = 0, Optional M2 = 1, Optional M3 = 0, Optional S = "") ' MATCH PAIR CHAIN
On Error Resume Next
M3 = IFZS(M3, MM(R3))
M1 = IFC(M3 = 1, M1, DI(R3, M3 - 1))
S = MP(R1, R2, L, P, M1, M2)
MPC = S
End Function
T3_[L]には、検索先の同じ製造番号の行数が表示されます。
後は、T3_[製品名] に関数 =DI(T1_[製品名],[@L])を埋めていくなどして
データを引っ張っていきます。
同一列で同じキーのデータを検索する。
上ではテーブルを3つ使いましたが、同一列の場合に、列下の同一キーデータの場合はどうでしょう。簡単ですね。
Function MD(R, Optional L = 0, Optional P = 1, Optional M1 = 0, Optional M2 = 0, Optional S = "")
On Error Resume Next
Dim V: V = MV(R, M2, L, P)
M1 = M2
S = MLOOP(R, R, M1, M2, L, P, V)
MD = IFC(S = M2, "", S)
End Function
小技1 連続した列のデータを取ってきて縦に並べる。
T1_は、検索先のテーブルで、T2_ にデータを受けます。
列[A]に関数 =DIJ(T1_[[D]:[K]],[A],3) を埋めると、取ってきたデータが
縦に並びます。
Function DIJ(R1, R2, I)
DIJ = DI(R1, I, MM(R2))
End Function
小技2 Rangeを配列に格納して返す。
Function AR(R, Optional M = 0, Optional N = 0, Optional S = "")
On Error Resume Next
M = IFZS(M, MM(R))
N = IFZS(N, R.Rows.Count)
ReDim S(1 To N): Dim J: For J = 1 To N: S(J) = DI(R, M, J): Next J
AR = S
End Function
Function AC(R, Optional N = 0, Optional M = 0, Optional S = "")
On Error Resume Next
M = IFZS(M, R.Columns.Count)
N = IFZS(N, NN(R))
ReDim S(1 To M): Dim I: For I = 1 To M: S(J) = DI(R, I, N): Next I
AC = S
End Function
小技3 配列振分サブルーチン
配列からデータを複数の変数に割り当てます。
日報データを作成するときに使った技で、テーブル列の追加、変更に対応できて便利です。
CALL DD(AR(R,N),年,機械,連番,製品番号,製品名)
という風に使用します。
Sub DD(AA, ParamArray AP())
Dim J: For J = 0 To UBound(AP)
AP(J) = AA(J + 1)
Next J
End Sub
最後に
訂正依頼ありがとうございました。
VSCODE からコピーしてペッタンしているのですがまだ慣れていません。
VBA は、普通でない使い方をすると、結構バグがあるようです。
Offset,Resize を誤って使うとハングまたはファイルを壊すし、
テーブルは、Rangeではなく ListObjects らしいのに、Rangeで扱えてしまうとか、
引数で as Range を付けるとエラーになるとか、
場合によって関数IFCがエラーになるのでIF文を使わざるを得ないとか、
再計算の実行順序が保証されてないのに関数 MPC が正しく動作するとか、
いろいろと謎があります。
簡単な実験をするには、Excelは最適なので楽しいです。
テーブルと構造的参照は、新しく入った概念なので、安定するには時間がかかるのでしょう。
VBA も継ぎ接ぎされているので、M言語がユーザ定義関数として使えればいいのでしょうかね。
次はM言語について書く予定です。
ではでは。