質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

1回答

940閲覧

GASを使用した条件分岐によるデータ貼り付けしたあとプルダウン作成を追加したい

tkt1964

総合スコア5

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2022/05/16 15:33

編集2022/05/17 08:30

前提

スプレッドシートに入力した内容から
別シートの対照表を基にデータの貼り付けとプルダウンの選択肢を表示させたい

実現したいこと

・スプレッドシート上で既に設定したプルダウンを選択、その内容を基に別シートの対照表の最初に該当するデータを貼り付け
・貼り付けたセルにプルダウンを作成
・作成されたプルダウンの内容は別シートの対照表を参照
・貼り付ける/プルダウンを作成される列は6列(B列で項目選択、C~H列にプルダウン作成)

発生している問題

以前ここで回答いただいた下記、コードで
基準となる情報を”使用シート”で選択すると
その隣の列へ”設定シート”の対照表を基に”使用シート”上にプルダウンが作成されます。

今回したいのは、プルダウントと貼り付けになります。

<使用シート>
B列      C列      D列・・・
データ1    ①←貼り付け  ③←貼り付け
(プルダウン)  (プルダウン)  (プルダウン)

A列:空白(他データを入れるため)  
B列:このシート上で選択
C列:GASで”設定シート”の対照表のB列を基にプルダウン作成
D列:GASで”設定シート”の対照表のC列を基にプルダウン作成

”設定シート”
A列      B列      C列      D列・・・
データ1    ①       ③       ④
データ1    ②       ④       ④
データ2    ③       ⑤       ⑥ 
データ2    ③       ⑤       ⑦

該当のソースコード

GAS

1/** 2 * ①グローバル変数の定義 3 */ 4const USE_SHEET_NAME = "使用シート"; 5const SETTING_SHEET_NAME = "設定シート"; 6const CATEGORY1_COL_NUM = 2; // B列 7 8/** 9 * ②本体 10 */ 11function onEdit(e) { 12 if (!isTargetCol(e)) return; 13 14 const category1Value = e.value; 15 const changedRow = e.range.getRow(); 16 const changedCol = e.range.getColumn(); 17 const useSheet = e.source.getSheetByName(USE_SHEET_NAME); 18 19 // 設定シート のデータ(二次元配列) 20 const settingData = e.source.getSheetByName(SETTING_SHEET_NAME).getDataRange().getValues(); 21 22 // 編集されたセルの右のセルにカテゴリ2のプルダウンをセットする 23 for (let i = 1; i <= 6; i++) { 24 const range = useSheet.getRange(changedRow, changedCol + i); 25 const rule = getRule(category1Value, settingData, i); 26 if (rule == null) continue; 27 range.setDataValidation(rule); 28 } 29} 30//追加箇所 31function getRule(category1Value, settingData, column) { 32 // カテゴリ1に対応するカテゴリ2を入れておくところ 33 let catgory2List = []; 34 35 // 設定シート のデータの中から、「選択されたカテゴリ1」に対応するカテゴリ2を取り出すところ 36 settingData.forEach(row => { 37 if (row[0] === category1Value) { 38 catgory2List.push(row[column]); 39 } 40 }); 41 if (catgory2List.length === 0) return; 42 43 // 編集されたセルの右以降のセルにカテゴリ2のデータを貼り付ける 44 const rule = SpreadsheetApp.newDataValidation().requireValueInList(catgory2List, true); 45 rule.editsheet.appendRow(catgory2List); 46 return rule; 47} 48//追加箇所 49 50function getRule(category1Value, settingData, column) { 51 // カテゴリ1に対応するカテゴリ2を入れておくところ 52 let catgory2List = []; 53 54 // 設定シート のデータの中から、「選択されたカテゴリ1」に対応するカテゴリ2を取り出すところ 55 settingData.forEach(row => { 56 if (row[0] === category1Value) { 57 catgory2List.push(row[column]); 58 } 59 }); 60 if (catgory2List.length === 0) return; 61 62 // 編集されたセルの右以降のセルにカテゴリ2のプルダウンをセットする 63 const rule = SpreadsheetApp.newDataValidation().requireValueInList(catgory2List, true); 64 rule.setAllowInvalid(false).build(); 65 return rule; 66} 67 68/** 69 * ⑦プルダウン連動をさせる列かどうかの判断 70 */ 71function isTargetCol(e) { 72 // 値が削除されたときはvalueが undefになるので無視 73 if (!e.range.getValue()) return false; // ※1 74 75 // 関係ないシートのとき 76 if (e.source.getSheetName() !== USE_SHEET_NAME) return false; 77 78 // 列が違うとき 79 if (e.range.getColumn() != CATEGORY1_COL_NUM) return false; 80 81 return true; 82}

試したこと

プルダウンをセットする前に、貼り付けするコードを入れてみましたが
エラーが出てしまい、こちらに再度ご質問させていただきました。

追加箇所に二次元配列のデータを貼り付けるコードを入れてみましたが
上手く作動しません。
入力してもデータ貼り付けなし、プルダウン作成もしなくなりました。

お手数ですが、ご尽力いただければ幸いです。
何卒宜しくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k.a_teratail

2022/05/17 02:32

> エラーが出てしまい どのようなエラーが表示されたのでしょうか?
tkt1964

2022/05/17 07:57

ご質問ありがとうございます。 あれから、自分で編集し直してみまして //~プルダウンをセットする 内に setValuesを入れて、エラー自体は発生しなくなったのですが 動作自体しなくなってしまいました。
k.a_teratail

2022/05/17 09:52

> エラー自体は発生しなくなったのですが > 動作自体しなくなってしまいました。 console.log()などを入れて、どこで終了しているか確認するのはどうでしょうか?
k.a_teratail

2022/05/17 10:33 編集

追加で、「getRule」の関数が二つあります。 これのせいで、期待している結果にならないとかでは無いでしょうか? 同じ関数名がある場合、後に定義された関数で実行されます。 ---------------------------- function myFunction1() { aaa() } function aaa() { console.log("先") } function aaa() { console.log("後") } ---------------------------- 実行ログ 19:32:45 情報 後 ----------------------------
guest

回答1

0

下記のようにしてはいかがでしょうか。

js

1/** 2 * ①グローバル変数の定義 3 */ 4const USE_SHEET_NAME = "使用シート"; 5const SETTING_SHEET_NAME = "設定シート"; 6const CATEGORY1_COL_NUM = 2; // B列 7 8/** 9 * ②本体 10 */ 11function onEdit(e) { 12 if (!isTargetCol(e)) return; 13 14 const category1Value = e.value; 15 const changedRow = e.range.getRow(); 16 const changedCol = e.range.getColumn(); 17 const useSheet = e.source.getSheetByName(USE_SHEET_NAME); 18 19 // 設定シート のデータ(二次元配列) 20 const settingData = e.source.getSheetByName(SETTING_SHEET_NAME).getDataRange().getValues(); 21 22 // 編集されたセルの右以降のセルにカテゴリ2のプルダウンをセットする 23 for (let i = 1; i <= 6; i++) { 24 const range = useSheet.getRange(changedRow, changedCol + i); 25 26 // 設定シートから入力規則と初期値を受け取る。 27 const [rule, initialValue] = getRuleAndInitialValue(category1Value, settingData, i); 28 29 // 入力規則を設定 30 range.setDataValidation(rule); 31 32 // 初期値を設定 33 range.setValue(initialValue); 34 } 35} 36 37function getRuleAndInitialValue(category1Value, settingData, column) { 38 // カテゴリ1に対応するカテゴリ2を入れておくところ 39 let catgory2List = []; 40 41 // 設定シート のデータの中から、「選択されたカテゴリ1」に対応するカテゴリ2を取り出すところ 42 settingData.forEach(row => { 43 if (row[0] === category1Value) { 44 catgory2List.push(row[column]); 45 } 46 }); 47 if (catgory2List.length === 0) { 48 catgory2List.push(''); 49 } 50 51 // プルダウンのデータを設定する 52 const rule = SpreadsheetApp.newDataValidation().requireValueInList(catgory2List, true); 53 rule.setAllowInvalid(false).build(); 54 return [rule, catgory2List[0]]; 55} 56 57/** 58 * ⑦プルダウン連動をさせる列かどうかの判断 59 */ 60function isTargetCol(e) { 61 // 値が削除されたときはvalueが undefになるので無視 62 if (!e.range.getValue()) return false; // ※1 63 64 // 関係ないシートのとき 65 if (e.source.getSheetName() !== USE_SHEET_NAME) return false; 66 67 // 列が違うとき 68 if (e.range.getColumn() != CATEGORY1_COL_NUM) return false; 69 70 return true; 71}

 

説明

 
前のコードから変更したところ:
① getRuleAndInitialValue 関数:入力規則(プルダウンの設定項目)とともに、初期値(該当するデータの最初の値)も返すようにしています。
(catgory2List[0] が初期値(=条件に当てはまるデータの最初の値)です)

js

1 return [rule, catgory2List[0]];

 
② onEdit 関数の中で getRuleAndInitialValue 関数から値を受け取るところでは、入力規則とともに初期値を受け取り、
入力規則を設定したに、そのセルに初期値を上書きしています。

js

1 // 設定シートから入力規則と初期値を受け取る。 2 const [rule, initialValue] = getRuleAndInitialValue(category1Value, settingData, i); 3 4 // 入力規則を設定 5 range.setDataValidation(rule); 6 7 // 初期値を設定 8 range.setValue(initialValue);

 
③ 使用シートのプルダウンで選んだデータが設定シートの中にない場合は、空白文字を設定するように変えています。

js

1 if (catgory2List.length === 0) { 2 catgory2List.push(''); 3 }

投稿2022/05/17 11:55

編集2022/05/17 12:26
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tkt1964

2022/05/19 08:46 編集

誠にありがとうございます。 お答え頂戴した日から確認していたのですが どうしても、”使用シート”のプルダウンをデータ1を関数にすると反応しなくなるのですが ここはどの様に解消すればよろしいでしょうか? ご教授いただければ幸いです。 何卒宜しくお願いいたします。
退会済みユーザー

退会済みユーザー

2022/05/19 21:35 編集

> 「どうしても、”使用シート”のプルダウンをデータ1を関数にすると反応しなくなる」 使用シートのB1セルに数式を入れているということでしょうか。それとも別のやり方でしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問