Googleスプレッドシート プルダウンリスト活用術 4(テーブル + 数式で連動プルダウン)
前回の続きのGAS回ではなく、話は変わりますがプルダウンリスト シリーズを書きたいと思います。
プルダウンリストも 番外編の「複数選択プルダウン」を入れると 今回で5本目。というわけでマガジンにまとめました。
前回のnoteは Googleスプレッドシートの画像を保存する方法の完全版ってことで、セル上画像、セル内画像を一括保存するテクニックについてまとめました。
テーブル機能 + 数式 で連動プルダウンを実現しよう!
今回のゴールは Googleスプレッドシートではなかなか難しい連動プルダウンの作成です。
基本の2段階止まりではなく 3段階以上のプルダウンを簡単に作る方法を紹介します。
連動プルダウンってなに?って人は、先に プルダウンシリーズの第2回「連動プルダウンの基本」をお読みください。
とりあえず作りたいのは ↓こんなやつです。
「あれ?3連プルダウンって プルダウンシリーズの第3回でやってなかったっけ?」と気づいた奇特な人は、相当な読者ですね。ありがとうございます。
3連プルダウン作成方法は 「Googleスプレッドシート プルダウンリスト活用術3 (連動プルダウン応用)」の回で一度紹介しています。
これは プルダウンを操作するシートに個別の作業領域を作らず、1つのマスタと1つの式で実現する3連以上に拡張可能な連動プルダウンで、自分としては割と気に入ってるんですが、
・式や設定が複雑でややこしすぎる(つまり面倒!)
・複数のシートで連動プルダウンを実現するのが難しい
・同時に複数人が操作するケースに対応できない
という欠点がありました。
これらを解消するのが、今回紹介する 「テーブル機能 + 数式」で実現する連動プルダウンです。
以前の方法に比べるとぐっと簡単で、1つのマスタと1つの式があれば 連動プルダウンが実現できますし、そのシートをコピーして利用することも可能です。
ただし、プルダウンリストと同じ行に 選択肢として参照させる為の作業領域が必要となります。
列を非表示とすれば問題ないと思いますが、どうしても同じシート内に作業領域を作れない!(作りたくない!)という場合は、対応できませんのでご了承ください。
それでは作り方を見ていきましょう!
Step1. 選択肢のマスタテーブルを作る
第3回の時と同じマスタを使って3連プルダウンを作ってみましょう。
まずは元になるマスタテーブルを作ります。
これは上の画像のようなリスト形式とする必要があります。
サンプルデータはコチラ ↓ (コピペして利用)
項目1 項目2 項目3
肉類 豚肉 ポークソテー
肉類 豚肉 トンカツ
肉類 豚肉 しょうが焼き
肉類 鶏肉 チキンソテー
肉類 鶏肉 唐揚げ
肉類 鶏肉 チキンカツ
肉類 牛肉 すき焼き
肉類 牛肉 しゃぶしゃぶ
肉類 牛肉 ステーキ
野菜 キャベツ 千切り
野菜 キャベツ ロールキャベツ
野菜 キャベツ 野菜炒め
野菜 ニンジン グラッセ
野菜 ニンジン シリシリ
野菜 ニンジン ナムル
野菜 タマネギ スープ
野菜 タマネギ マリネ
野菜 ジャガイモ 肉じゃが
野菜 ジャガイモ じゃがバター
野菜 ジャガイモ ポテトフライ
果物 リンゴ アップルパイ
果物 リンゴ リンゴジャム
果物 バナナ クレープ
果物 バナナ スムージー
果物 ミカン ジュース
果物 ミカン ゼリー
果物 イチゴ イチゴジャム
果物 イチゴ 大福
果物 イチゴ ショートケーキ
このデータを Googleスプレッドシートの新機能 で テーブル化
テーブル名は「マスタ」としておきましょう。
テーブルにする利点はデータ範囲を テーブル名で呼び出せる(参照できる)ことです。
見出しを除くデータ部分を丸ごと呼び出したい場合は
こんな式で実現できます。シート名を気にする必要がないので便利ですね。
テーブル機能について詳しく知りたい方は、noteにまとめていますのでそちらも参考にしてください。
Step2. 別シートで1段目のプルダウンを作る
次に別シートにプルダウンを用意しましょう。
1行目を見出し行として、2行名以降のA~C列をプルダウン用、1列あけて E列から右側を作業領域とします。
まずは A2(項目1のプルダウン)用の 選択肢を E2から横に出力したいんですが、マスタ というテーブル名を使ってどのような式を組めばよいでしょうか?
簡単ですが、これをお題でいってみましょう。
Q1. マスタの項目1(1列目)のデータを プルダウン用の選択肢として横方向に並べて出力したい
テーブルは構造化参照が出来るのが利点で、項目1(1列目)のデータは
こういう記述で取得もできるんですが、これだと見出しが違うケースで面倒なんでこの「見出し名」を使う書き方は使わないものとします。
E2にはどんな式をいれれば良いでしょうか?考えてみましょう!
↓↓↓
回答は以下
↓↓↓
A1. マスタの項目1(1列目)のデータを プルダウン用の選択肢として横方向に並べて出力する式
回答です。
マスタから 1列目を INDEX関数で取得して、それをUNIQUE関数で重複排除。最後にTOROW関数で横1行データに変換する。
これは簡単ですね。
Googleスプレッドシートの場合は、マスタ全体を出力する場合は ARRAYFORMULAを付ける必要があるんですが、INDEX関数にはARRAYFORMULAと同じ効果があるので省略することができます。
また、Googleスプレッドシートのプルダウンは 自動で重複排除してくれるんですが、無駄に横に長い作業領域になってしまうことを避ける為に、UNIQUE関数で重複を排除して出力しています。
ここまでは 縦1列データなんで、最後に横にする為に TOROWを使います。
ケースによって 出力範囲が変わってくるので、プルダウンの範囲は横のお尻を決めない書き方
E2:2
としておきましょう。
1段目のプルダウンが出来ました。
Step3. 項目1で選択した値で項目2のプルダウンを生成する
続いて 1段目の選択で絞り込んだ項目2の選択肢を作業領域に表示させます。
ただ、ここで注意すべきは そのまま上の画像のように 項目2の選択肢を出力してしまうと、項目1で選択した「野菜」がプルダウン用作業領域にない為、
このようにエラー表示が出てしまいます。
無視してもいいんですが、せっかく今回は改良版なんで エラーを回避する為に
このように 項目1が空欄ではない(選択された)場合は、項目2の前(左)に項目1で選択した値を付けて出力するようにします。
【Point1】プルダウン範囲内 は 範囲の頭にイコールを付けて設定すると相対参照になる
ここで項目1、項目2のプルダウンを一気に設定する際
範囲を =E2:2 と頭に = を付けるのがポイントです。
単純にイコールを付けずに E2:2と設定してしまうと
「完了」で保存すると 自動で E2:2 で設定した範囲は 絶対参照の
=$E$2:$2
と置き換えられてしまいます。
これでは行も列も固定されてしまっているので、
このようにどのプルダウンも 同じ E2:2の選択肢が表示されてしまいます。
ここを =E2:2と プルダウン範囲を 相対参照にすることで
作業領域を行ごとに選択肢範囲として読み込み、かつ 項目1の時は E列から、項目2の時は一つズレてF列から と範囲を相対的にズラして 見てくれます。
これによって、項目1で選択した「野菜」という選択肢は 項目2のプルダウンには表示されない仕様となります。
これで範囲指定は一発でいけますね。
Q2. 項目1で選択した値を左に連結してマスタを絞り込んだ項目2を横に並べたい
それでは肝心の E2 に入れる式を考えましょう。
A2が空欄だった時は、 =TOROW(UNIQUE(INDEX(マスタ,,1)))
でマスタの項目1を選択肢として表示し、
A2が空白ではない場合は、A2の値と マスタの項目1をA2の値で絞り込んだ 項目2をユニークにした値を横に並べたい。
どんな式を作ればよいでしょうか?範囲として式内で使えるのは テーブル名のマスタ、そして A2 のみとします。
考えてみましょう!
↓↓↓
回答は以下
↓↓↓
A2. 項目1で選択した値を左に連結してマスタを絞り込んだ項目2を横に並べたい
回答です。
これは幾つか式の書き方があるので回答の一例と思ってください。
まず、A2セルの連結は置いといて、先にIFの分岐処理を考えましょう。
A2セルが空白なら 項目1、A2セルが 空白ではない(プルダウンが選択されている)なら、マスタの項目1をA2の値で絞り込んだ 項目2を ユニークにして横並びに表示したい。
という分岐なので、「ユニークにして横並びに表示」はどちらのパターンでも必要な共通の処理です。というわけで IFは
TOROW(UNIQUE(IF(A2="",
このように TOROWとUNIQUEの中に書いちゃいましょう。
空白だった時はマスタの1列目を返せばよいので、INDEX(マスタ,,1) ですね。
空白ではない時(画像の場合だと「野菜」を選択した時)は、マスタの項目1がA2と一致するという条件で絞り込んだ時の 項目2を出力したいので、FILTER関数の出番です。
FILTER(INDEX(マスタ,,2),INDEX(マスタ,,1)=A2)
この FILTER関数の中にIFを入れちゃう書き方もありますが、処理が重くなるのでここでは避けています。
まずはここまで出来ました。
最後に A2の連結ですが、ここはIF内での連結、TOROWで空白除去してから連結、中カッコではなく HSTACKを使う方法など色々方法はあります。
回答だと { , } で横に連結してから 最後に TOROWとしています。
=TOROW({A2,TOROW(UNIQUE(IF(… )},1)
この一番外側の TOROWは第2引数を1に指定した 空白を除去して左に詰める為の TOROWだと考えてください。
とりあえずは2段階プルダウンができました。
Step4. 3段階プルダウンを考える
ここから一気に難しくなります。
3段階目のプルダウンを連動させるにあたり、以下を考える必要があります。
・今、何段階目までプルダウンが選択されているのか?
これをなるべくシンプルに考える為に プルダウン範囲の行 A2:C2を見て、値の入ったセルが幾つあるか? で判定することにしましょう。
※「必ずプルダウンは 左から順に選択する」という運用上の条件を必要とします。
これだったら COUNTA関数で簡単に取得できますね。
ここから 汎用性を高めるためにLET関数を使っていきましょう。
LETを使って
このように置きます。
そうすると 仮に 項目2まで選択された状態の時 c は 2 となり、次は項目3のプルダウンを選ぶことになるので、FILTERで絞り込んで結果として出力する列は マスタの項目3の列、つまり
INDEX(m,,c+1) となります。これを col とおきます。
素材の下準備が出来てきました。(料理に似ています)
次にIF関数の分岐を考えます。2段階の時は IF(A2="", としましたが、多段階で考えた場合は
まだ何も選択されていない状態の時は c つまり COUNTA(pr) は 0となるので、これは 真偽値だと FALSEになります。
この時、プルダウンの選択肢となるのは マスタの項目1の列です。
つまり、Q2の回答の式にあてはめると cが1以上の時(TRUE)は FILTERの式で絞り込んだ col を 返し、cが 0の時(FALSE)は、そのまま colを返す
その結果をUNIQUEしてTOROW。最後に pr と横連結して空白除去。
こんな式を作れば良さそうですね!
では、この「なんかの条件式」部分をかんがえてみましょう。
Q3. 項目1、項目2で絞り込んだマスタの項目3を重複排除して横方向に並べたい
=LET(
pr,A2:C2,m,マスタ,c,COUNTA(pr),col,INDEX(m,,c+1),
TOROW(UNIQUE(
IF(c,
FILTER(
col,
【条件式】
),
col
)
))
)
連動プルダウンを実現する式の「条件式」の部分を考えてみましょう!というお題です。
挑戦してみましょう!
↓↓↓
回答は以下
↓↓↓
A3. 項目1、項目2で絞り込んだマスタの項目3を重複排除して横方向に並べる式
回答です。
=LET(
pr,A2:C2,m,マスタ,c,COUNTA(pr),col,INDEX(m,,c+1),
TOROW(UNIQUE(
IF(c,
FILTER(
col,
BYROW(CHOOSECOLS(pr=m,SEQUENCE(c)),LAMBDA(r,AND(r)))
),
col
)
))
)
条件式部分は
こんな式で実現できます。(他の書き方もあります)
まずFILTER内の式なのでARRYAFORMLAと同じ効果があり、配列処理が可能です。
pr=m の部分は
このように列単位で prとmが一致したらTRUEを返す式となっています。
ここで列1、列2の両方がTRUEとなっている 部分、つまり 野菜 > ニンジン となっている部分の 列3を取り出せばよいわけです。
そうすると 必要なのは列1、列2だけで 列3は不要ですね。
なので、
CHOOSECOLS(pr=m,SEQUENCE(c))
CHOOSECOLS関数とSEQUENCE関数で 1列目、2列目だけを取り出します。
ほんとはExcelみたいにTAKE関数があるといいんですが。。
cは prの空白でないセルの数なので、上の場合は2となります。
SEQUENCE(2) は {1:2} となるので、これを CHOOSECOLSの第2引数とすることで、pr=m の結果配列の1列目と2列目だけを抽出できます。
あとはこれを 行毎に見て 全てTRUEの行だけTRUEとなる1列の配列を作ればいいので、BYROWで行毎に AND関数とすればよいです。
この式 が回答の 「条件式」です。あとはFILTER関数と組み合わせて
とすることで、項目1が 野菜、項目2が ニンジン と一致する項目3だけを取得できました。
FILTERの結果と pr を横に結合する
このFILTERの結果をUNIQUEしてTOROWしてから、プルダウンで選択した値と横に連結します。
先ほどのFILTERの結果を xと置いて 最後に
TOROW({pr,x},1)
とすれば
このように横に連結ができました~。
ただ、これだと
プルダウンを最後の3段目まで選んでしまうと エラーが出てしまいます。
これは プルダウンを全て選択すると c つまり COUNTA(pr) が 3となり、col,INDEX(m,,c+1), はINDEX(m,,4)となってしまい、3列のデータであるm に存在しない 4列目を取り出そうとしている為です。
気にしなくてもいいんですが、ここは 最後の TOROW({pr,x},1) を TOROW({pr,x},3) として、TOROWで 空白とエラーの両方を無視すれば 解消できます。
というわけで 作業スペースに出力する 3段階プルダウン式(多段階プルダウン式)は
=LET(
pr,A2:C2,m,マスタ,c,COUNTA(pr),col,INDEX(m,,c+1),
x,TOROW(UNIQUE(
IF(c,
FILTER(
col,
BYROW(CHOOSECOLS(pr=m,SEQUENCE(c)),LAMBDA(r,AND(r)))
),
col
)
)),
TOROW({pr,x},3)
)
このようになります。
サンプルは3段階ですが、これは 4段階、5段階の多段階プルダウンにも拡張対応できる式になっています!
Step5. 複数行のプルダウンにも一つの式で対応する
行単位のプルダウン式は完成しましたが、今回目指しているのは一つの式で完結させることです。
つまり上の画像のように 3段階の連動プルダウンが、2行目から8行目までの 7セットあった場合、これをE2 に一つ式を入れるだけで実現したいってことです。
これが実現できれば完成です。最後のお題いってみましょう!
Q4 . 1行対応の連動プルダウン式を 複数行に対応する式に変更したい
=LET(
pr,A2:C2,m,マスタ,c,COUNTA(pr),col,INDEX(m,,c+1),
x,TOROW(UNIQUE(
IF(c,
FILTER(
col,
BYROW(CHOOSECOLS(pr=m,SEQUENCE(c)),LAMBDA(r,AND(r)))
),
col
)
)),
TOROW({pr,x},3)
)
この式を複数行 (範囲 A2:C8)に対応させたい!というお題です。
とりあえず、 A2:C8 のセル範囲を p と置いて処理をしましょう。
出だし部分は
=LET(
p,A2:C8,m,マスタ,
こうなります。
考えてみましょう!
↓↓↓
回答は以下
↓↓↓
A4. 1行対応の連動プルダウン式を 複数行に対応する式に変更する
回答です。
=LET(
p,A2:C8,m,マスタ,
BYROW(p,
LAMBDA(pr,
LET(c,COUNTA(pr),col,INDEX(m,,c+1),
x,TOROW(UNIQUE(
IF(c,
FILTER(
col,
BYROW(CHOOSECOLS(pr=m,SEQUENCE(c)),LAMBDA(r,AND(r)))
),
col
)
)),
TOROW({pr,x},3)
)
)
)
)
LETしてBYROWして、またLETしてBYROWする・・・。なかなかヘビーな式ですね。
プルダウン領域 A2:C8(p)から 1行ずつ取り出して処理をしたいので BYROW関数を使います。
=LET(
p,A2:C8,m,マスタ,
BYROW(p,
LAMBDA(pr,
取り出した行は pr とします。(さっきA2:C2 をprとしたので、この後の式でそのまま使いやす為)
さらに行単位で COUNTA(pr) 、次のプルダウン選択肢となる 列 INDEX(m,,c+1) を変数化して処理したいので、BYROWの中でもう1回 LET関数を使います。
LAMBDAヘルパー関数を使った複雑な式では、LETを入れ子で使うケースも結構あります。
=LET(
p,A2:C8,m,マスタ,
BYROW(p,
LAMBDA(pr,
LET(c,COUNTA(pr),col,INDEX(m,,c+1),
あとは BYROW内のLET式内で 先ほどの式を再現すれば良いですね。
=LET(
p,A2:C8,m,マスタ,
BYROW(p,
LAMBDA(pr,
LET(c,COUNTA(pr),col,INDEX(m,,c+1),
x,TOROW(UNIQUE(
IF(c,
FILTER(
col,
BYROW(CHOOSECOLS(pr=m,SEQUENCE(c)),LAMBDA(r,AND(r)))
),
col
)
)),
TOROW({pr,x},3)
)
)
)
)
E2の一つの式で複数行の連動プルダウンが処理されてますね。
複数行対応の連動プルダウン式の完成です!
Step6. 4連プルダウンへ拡張可能か?を確認する
今回作成した連動プルダウン式の拡張性を確認しましょう。
3段階→4段階への拡張の手順を見ていきます。
まずマスタの方を4列構成に変更します。
テーブルなので、見出し行の一番右の項目3の端にカーソルを当てると +ボタンで列を右に挿入できます。
見出しを項目4として、とりあえずサンプルなんで ポークソテーだけ 2行にして4段目の選択肢を入れておきましょう。
つぎにプルダウンがあるシートの方も拡張します。今回は作業範囲とプルダウン範囲が1列しか空いていないので、先に空白列を1列追加しましょう。
こちらはテーブルにしていないので、D列を選択して右クリックから左に1列追加とします。
項目3の C列をD列にコピペして D列を4段目のプルダウンにします。
プルダウン範囲の選択済みの箇所をDeleteで消して見出しを項目4とすればOK。
この手順だと自動で プルダウン範囲がD列まで相対参照で拡張されたことになります。
最後に式の冒頭部分 =LET( p,A2:C8 の プルダウンセル範囲を
=LET( p,A2:D8 とD列まに修正すれば完成です。
LET関数を使うと数式の修正(メンテナンス)が簡単になりますね。
3段目でポークソテーを選択して確認すると
4段階の連動プルダウンになってますね!
多段階プルダウンの拡張も確認できました。
Step7. プルダウン範囲もテーブル化する
今回作成した多段連動プルダウン式ですが、プルダウン範囲の指定を
=LET( p,A2:C8
と8行目までとしています。
あえて =LET( p,A2:C とお尻(最終行)を指定しない書き方にしていないのは理由があって、数式では参照しているセルがプルダウンかどうか?を判別できない為です。
もし範囲を A2:Cとしてしまうと、プルダウン設定されていない行も含めシートの最終行まで 1段目のプルダウン選択肢が表示され無駄な計算が多い状態となります。
式内で最終行を固定せず 参照するプルダウン範囲を変動にする方法が、プルダウン範囲のテーブル化です。
見出し行を含めプルダウンのセル範囲を選択した状態で
右クック > テーブルに変換
でテーブル化して適当なテーブル名をつけます。
数式側の冒頭
=LET( p,A2:C8 の箇所を =LET( p,プルダウンテーブル_1
とテーブル名指定にすると
このようにテーブルの範囲(プルダウンの範囲)まで数式の結果が展開されます。
プルダウンを拡張したい場合は、テーブルなので 最終行にポインタをあてた時に表示される + ボタンから
このように行を追加すると テーブルの拡張に伴い、プルダウンも拡張され、合わせて数式範囲も拡張されます。便利!
ただしプルダウン範囲をテーブル化してしまうと、先ほど Step6で触れた 3連 → 4連 のような 列の拡張によるプルダウンの相対参照に対応が出来ません。
テーブル内のプルダウンは、セル範囲に対してのデータの入力規制ではなく
列の型という扱いになっている為です。
これだとプルダウン範囲を列方向(横方向)に相対参照してくれない為、プルダウンの連動する段数を拡張する時にちょっと面倒です。
まあ運用中にプルダウンの連動数が変わることはあまり無いんで、可能であればプルダウン範囲のテーブル化はおススメです。
今回の連動プルダウン式のメリット・デメリット
最後にまとめです。
プルダウン範囲もテーブル化した 多段階連動プルダウン式
=LET(
p,プルダウンテーブル_1_,m,マスタ,
BYROW(p,
LAMBDA(pr,
LET(c,COUNTA(pr),col,INDEX(m,,c+1),
x,TOROW(UNIQUE(
IF(c,
FILTER(
col,
BYROW(CHOOSECOLS(pr=m,SEQUENCE(c)),LAMBDA(r,AND(r)))
),
col
)
)),
TOROW({pr,x},3)
)
)
)
)
※プルダウンテーブル_1 は プルダウンを設定したテーブル
※マスタは 別シートの選択肢のマスタデータのテーブル
このようにテーブル機能とシート関数を駆使したちょっと複雑な式を組み合わせることで、多段階連動プルダウンを実現できます。
この方式で連動プルダウンを実装するメリット
■数式を入れる箇所が1カ所だけでよい
式を入れるセルは1つだけなんで、コピペで使えます。
また、LET関数で指定する範囲は2ヵ所だけなのも簡単ですね。
■プルダウンの設定が1回だけでよい
プルダウン化するセル範囲を指定して、データの入力規制で プルダウン(範囲内)で、 作業範囲の行を 相対参照指定 例: =E2:2
■シートをコピーしてそのまま使える
同じマスタを使った連動プルダウンを他のシートで使いたい場合も、シートをコピーするだけで簡単に使えます。
■各行のプルダウンが独立しているので、複数人で同時に使える
共有して同時に作業していた場合でも、複数人がそれぞれ自分の行のプルダウンを操作できます。また、選択途中の行があっても他の行には影響がありません。
というわけで、以前の3段階連動プルダウン式に比べると簡単かつ利便性が向上していると言えます。
この方式で連動プルダウンを実装するデメリット
一方でデメリットもあります。
■プルダウンの 行単位分 作業セルが必要
冒頭にも書きましたが、各行のプルダウンに対して作業領域が必要になります。列の非表示などを使って見えないようにしましょう。
■選択しなおしが不便
このように一度選択したプルダウンを再選択しようとすると、右側の選択肢用の作業領域は次のプルダウン用になってしまっている為、他の項目1の選択肢が出てきません。
一度選択したプルダウンを変更する(選択しなおす)場合は、一旦Deleteでプルダウンを空にしてから再選択する必要があるってことです。
これが一番の欠点ですね。
■プルダウンを自由に配置できない
この方式は行方向は間隔をあけてプルダウンを配置することは可能です。(ただしプルダウン範囲にテーブルは使えない)
しかし、列方向は式に影響があるので 間隔をあけることはできません。
列構成はマスタと同じとする必要があるってことです。
デメリットに幾つか触れましたが、逆に言えばこの程度のデメリットなんで、考慮して利用すれば十分に活用できる方式だと思います。
もしや 複数選択可能な連動プルダウンも実現できる!?
今回は連動プルダウン式の改良版を紹介しました。
今回のプルダウンはあくまでも 単一選択の従来のプルダウンで利用することを想定しています。(チップ表示が矢印表示かは自由)
2024年8月にGoogleスプレッドシートに実装された 複数選択可能なプルダウンでは使えません。
でも、数式を工夫すれば、項目1で 肉類と野菜を選択したら、項目2で 豚肉、鶏肉、牛肉、ニンジン、キャベツ、タマネギ・・・ と 選択した2つの項目で絞り込まれたリストを表示させる。みたいなことが出来るかもしれません。
機会があれば 複数選択での連動プルダウンにも挑戦してみたいと思います。
次回のネタは・・・そろそろ 強力な某関数を取り上げようかなと。(まだ未定です)