スピルと新関数の練習(XLOOKUP関数、LET関数、VBAまで)
2019年Office365に追加された革新的な機能としてスピルがあります。
スピルとともに強力な新関数が登場しました。
その中でも特に使用頻度が高いと思われるXLOOKUP関数の練習をかねて、問題を作成しました。
まずは、VLOOKUP関数、INDEX関数、MATCH関数
これらの関数を個別にスピルで確認し、組み合わせて数式を完成させます。
そこから、XLOOKUP関数+OFFSET関数の組み合わせへ書き換えていきます。
そして今回は、さらに、VBAによるユーザー定義関数の作成までやります。
今は必要ないとしても、後学のためにも是非お読みになることをお勧めします。
スピルとXLOOKUP関数の練習問題
※以下のデータの内容については深く考えないでください(笑)
※縦は最大100行まで入っている事とします。
「材料」シートの1行目で「酢豚」を探します。
D1に「酢豚」があるので、D列とE列が「酢豚」作成に必要な材料とグラム数になります。
材料として、
「酢」20gと「豚」80gが必要なことが分かります。
「カロリー」シートの列で「酢」と「豚」を探し、B列からkcal/100gを取得します。
「酢」は50(kcal/100g)、「豚」は700(kcal/100g)
「酢豚」のkcalは、
20/100*50 + 80/100*700 = 750kcal
これを導き出す数式を「メニュー」シートのB2セルに入れます。
従来の関数+スピルで数式を作る
以下では、B1セルに入れる数式を作成します。
作成する数式に使う関数のひとつひとつを、その横のE列より右にいれてスピルで確認して行きます。
=MATCH(A1,材料!$1:$1,0)
=INDEX(材料!$2:$100,,MATCH(A1,材料!$1:$1,0))
配列を材料!$2:$100としているので、データの入っていないセルは0と出力されます。
今回のサンプルであれば、1行目から指定して材料!$1:$100としても構いません。
行番号を省略しているので配列の全行が取得されます。
スピルしているという事は、複数の値(配列またはセル範囲)が返されているという事です。
=INDEX(材料!$2:$100,,MATCH(A1,材料!$1:$1,0)+1)
INDEX関数の第3引数(列番号)に指定しています。
行番号を省略しているので配列の全行が取得されます。
=VLOOKUP(INDEX(材料!$2:$100,,MATCH(A1,材料!$1:$1,0)),カロリー!A:B,2,0)
「カロリー」シートのA:Bの2列目を取得しています。
カロリーは(kcal/100g)なのでグラムは100で割ります。
④カロリーが#N/Aのエラー値が含まれています。
そこで、IFERROR関数でこれを回避します。
=SUM(
IFERROR(
VLOOKUP(INDEX(材料!$1:$100,,MATCH(A2,材料!$1:$1,0)),カロリー!A:B,2,0)
* INDEX(材料!$1:$100,, MATCH(A2,材料!$1:$1,0)+1)/100,
0))
このB1セルの数式をB2セル以降にコピーすれば完成です。
掛け算の結果を合計する専用の関数としてとSUMPRODUCT関数があります。
SUM(A*B) → SUMPRODUCT(A,B)
=SUMPRODUCT(
IFERROR(VLOOKUP(INDEX(材料!$2:$100,,MATCH(A1,材料!$1:$1,0)),カロリー!A:B,2,0),0),
IFERROR(INDEX(材料!$2:$100,, MATCH(A1,材料!$1:$1,0)+1)/100,0)
)
今回の場合は、IFERRORはカロリーを取得するVLOOKUPの方にだけ指定すれば良いですが、
このような場合は、今後の修正等を考えて両方に指定しておいた方が良いでしょう。
縦にスピルさせることはできません
材料、グラム、カロリーを縦の配列で取得したいので、その入力値を縦のセル範囲(配列)で指定することができません。
今回の場合は、横のセル範囲(配列)を指定しても2次元配列作成が上手く動作しません。
XLOOKUP関数に書き換える
VLOOKUP関数
これらをXLOOKUP関数に書き換えます。
これをXLOOKUPに書き換えます。
=XLOOKUP(A1,材料!$1:$1,材料!$2:$100,0)
これをXLOOKUPに書き換えます。
=OFFSET(XLOOKUP(A1,材料!$1:$1,材料!$2:$100,0),0,1)
これをXLOOKUPに書き換えます。
=XLOOKUP(XLOOKUP(A1,材料!$1:$1,材料!$2:$100,0),カロリー!A:A,カロリー!B:B,0)
=SUM(
IFERROR(
VLOOKUP(INDEX(材料!$2:$100,,MATCH(A2,材料!$1:$1,0)),カロリー!A:B,2,0)
* INDEX(材料!$2:$100,, MATCH(A2,材料!$1:$1,0)+1)/100,
0)
)
これをXLOOKUP関数とOFFSET関数で書き直しました。
=SUM(
IFERROR(
XLOOKUP(XLOOKUP(A1,材料!$1:$1,材料!$2:$100,0),カロリー!A:A,カロリー!B:B,0)
* OFFSET(XLOOKUP(A1,材料!$1:$1,材料!$2:$100,0),0,1)/100,
0)
)
これもSUMPRODUCT関数に書き直すことができますが、先と同じなので省略します。
LET関数に書き換える
これで作成した数式をLET関数で書き換えます。
=SUM(
IFERROR(
XLOOKUP(XLOOKUP(A1,材料!$1:$1,材料!$2:$100,0),カロリー!A:A,カロリー!B:B,0)
* OFFSET(XLOOKUP(A1,材料!$1:$1,材料!$2:$100,0),0,1)/100,
0)
)
数式1つ1つに名前を付けていき、付けた名前を使って次の数式を作っていきます。
=LET(名前1,値1,名前2,値2,[名前3,値3,...],計算式)
=LET(
メニュー,A1,
材料,XLOOKUP(メニュー,材料!$1:$1,材料!$2:$100,0),
グラム,OFFSET(材料,0,1),
カロリー,XLOOKUP(材料,カロリー!A:A,カロリー!B:B,0),
SUM(IFERROR(グラム/100*カロリー,0))
)
VBAでユーザー定義関数を作成
Function kcal(メニュー範囲, 材料範囲, カロリー範囲)
Dim メニュー
メニュー = メニュー範囲.Value
Dim rtn()
If Not IsArray(メニュー) Then
ReDim メニュー(1 To 1, 1 To 1)
メニュー(1, 1) = メニュー範囲
End If
ReDim rtn(LBound(メニュー) To UBound(メニュー))
Dim 材料, グラム, カロリー
Dim i1, i2
For i1 = LBound(メニュー) To UBound(メニュー)
On Error Resume Next
rtn(i1) = 0
i2 = WorksheetFunction.Match(メニュー(i1, 1), 材料範囲.Resize(1), 0)
If Not Err Then
材料 = 材料範囲.Columns(i2)
グラム = 材料範囲.Columns(i2 + 1)
For i2 = LBound(材料) + 1 To UBound(材料)
On Error Resume Next
カロリー = WorksheetFunction.VLookup(材料(i2, 1), カロリー範囲, 2, 0)
If Not Err Then
rtn(i1) = rtn(i1) + グラム(i2, 1) / 100 * カロリー
End If
Next
End If
Next
kcal = WorksheetFunction.Transpose(rtn)
End Function
LET関数の数式と見比べてみてください。
非常に似ていることがわかると思います。(似せてVBAを書いたのではありますが)
VBAのセル範囲を取得する2次元配列とFor…Nextを理解すれば読めるVBAコードです。
=kcal(A1:A3,材料!1:100,カロリー!A:B)
ここまで入力して、
Shift + F3
このショートカットで数式パレットが表示されます。
スピルと新関数の練習のまとめ
↓
VLOOKUP関数+INDEX関数+MATCH関数で作成
↓
XLOOKUP関数+OFFSET関数に書き換え
↓
LET関数に書き換え
↓
VBAでユーザー定義関数の作成
同じテーマ「エクセル入門」の記事
XLOOKUP関数(VLOOKUP関数を拡張した新関数)
XMATCH関数(MATCH関数を拡張した新関数)
LET関数(数式で変数を使う)
スピルと新関数の練習(XLOOKUP関数、LET関数、VBAまで)
スピルとは:スピル基礎から応用までの問題集
スピルとは:スピル入門の問題と解説
スピルとは:旧関数でスピルを使う問題と解説
スピルとは:スピルの新関数を使う問題と解説
スピルとは:ここまでの総合演習問題と解説
LAMBDA以降の新関数について
LAMBDA関数(カスタム関数の作成)
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.繰り返し処理(For Next)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.条件分岐(Select Case)|VBA入門
10.ブック・シートの選択(Select,Activate)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。