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

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

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

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

Q&A

解決済

2回答

722閲覧

IF関数で複数の処理を行いたい。

koromo_t

総合スコア60

Google Apps Script

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

0グッド

0クリップ

投稿2018/03/27 20:41

編集2018/03/29 04:01

こちらの質問の関連です。
上記の質問で作ったスクリプトを強化しようと思いました。
そこで、

「変更のあったセルの左隣のセルが空白ではなく、
変更のあったセルの値が変更のあったセルの左隣のセルの値よりも小さかった時に、
変更のあったセルに1を入力して、
変更のあったセルの有る行の下の行の2列目に0を入力して、
変更のあったセルの有る行の下の行の3列目に変更のあったセルの値を入力して
右隣にアクティブセルを移動」

ということがしたくて、スクリプトを書きました。

javaScript

1// シートに変更があった時に実行する関数 2function onEditEvent24() { 3 // 変更のあったシート 4 var ss = SpreadsheetApp.getActiveSpreadsheet(); 5 var sh = ss.getActiveSheet(); 6 // 変更のあったセル 7 var cell = ss.getActiveRange(); 8 // 変更のあったセルの有る行番号 9 var r = cell.getRow(); 10 // 変更のあったセルの有る列番号 11 var c = cell.getColumn(); 12 // 変更のあったセルの左隣のセル 13 var cellLeft = sh.getRange(r, c-1); 14 // 変更のあったセルの値 15 var val = cell.getValue(); 16 // 変更のあったセルの左隣のセルの値 17 var val2 = cellLeft.getValue(); 18 // 変更のあったセルの左隣のセルの値が空白ではなく、変更のあったセルの値が変更のあったセルの左隣のセルの値よりも小さかった時に 19 if( ( val2 != "" && val2 > val ) ) { 20 // 変更のあったセルの有る行の下の行の2列目を選択 21 var rowRange = sh.getRange(r+1, 2); 22 // 変更のあったセルの有る行の下の行の3列目を選択 23 var rowRangeRight = sh.getRange(r+1, 3); 24 // 変更のあったセルに1を入力 25 cell.setValue(1) ; 26 // 変更のあったセルの有る行の下の行の2列目に0を入力 27 rowRange.setValue(0) ; 28 // 変更のあったセルの有る行の下の行の3列目に変更のあったセルの値を入力して右隣にアクティブセルを移動 29 rowRangeRight.setValue(val).offset(0, 1).activate(); 30 } 31}

このスクリプトを実行しても、特に反応はありません。
しかし、実行トランスクリプトにはエラーは出ていません。
私の予想では、IF関数の中が混乱しているのではないかと思うのですが、
期待通りの結果を得るには、それをどのように書けばよいかわかりません。
アドバイスをいただけると嬉しいです。

#~解決後のまとめ~
Zuishinさんの回答を参考に解決しましたので、まとめておきます!
というか、後日談的なやつです。

今回の質問のネックは、トリガーの設定変更時に、
一旦そのトリガーを削除していなかったらしいことだったみたいです。
トリガーの設定を変更する際は、一度そのトリガーを削除して、
もう一度、初めから設定し直す必要があるみたいですね。
今回もそのようにしたつもりだったのですが、していなかった模様…?
設定し直すと、やはり「値の変更」でも「編集時」でも、
仮にイベントハンドラでなくても、動作するみたいですね。
お騒がせいたしました…。


後日談。

質問文には書いていなかったことなのですが、
今回、スプレッドシートのA列に日付リストがある状態で、
B列からデータを入力していくという状況であり、
私がもともと書いていたスクリプトのIF関数の条件、

javaScript

1 // 変更のあったセルの左隣のセルの値が空白ではなく、変更のあったセルの値が変更のあったセルの左隣のセルの値よりも小さかった時に 2 if( ( val2 != "" && val2 > val ) )

このなかの前半部分「変更のあったセルの左隣のセルの値が空白ではなく、」だけでは、
日付リストの横のデータを入力したときにも反応してしまうということがわかったので、
「変更のあったセルの2つ左隣のセル」の情報も取得して活用することで、
日付リストの横にデータを入力したら反応してしまう問題を解決しました。

最終的にはこんな感じのスクリプトになりましたので、お納めください(?)。

javaScript

1function onEdit(e) { 2 // 変更のあったシート 3 var ss = SpreadsheetApp.getActiveSpreadsheet(); 4 var sh = ss.getActiveSheet(); 5 // 変更のあったセル 6 var cell = ss.getActiveRange(); 7 Logger.log(cell); 8 // 変更のあったセルの有る行番号 9 var r = cell.getRow(); 10 Logger.log(r); 11 // 変更のあったセルの有る列番号 12 var c = cell.getColumn(); 13 Logger.log(c); 14 // 変更のあったセルの左隣のセル 15 var cellLeft = sh.getRange(r, c - 1); 16 Logger.log(cellLeft); 17 // 変更のあったセルの2つ左隣のセル 18 var cell2Left = sh.getRange(r, c - 2); 19 Logger.log(cell2Left); 20 // 変更のあったセルの値 21 var val = cell.getValue(); 22 Logger.log(val); 23 // 変更のあったセルの左隣のセルの値 24 var val2 = cellLeft.getValue(); 25 Logger.log(val2); 26 // 変更のあったセルの2つ左隣のセルの値 27 var val3 = cell2Left.getValue(); 28 Logger.log(val3); 29 // 変更のあったセルが変更のあったセルの2つ左隣のセルの値よりも小さいか、変更のあったセルの左隣のセルの値が空白ではなく、変更のあったセルの値が変更のあったセルの左隣のセルの値よりも小さかった時に 30 if( ( ( ( val < val3 ) || ( val2 != "" ) ) && val2 > val ) ) { 31 Logger.log( ( ( val < val3 ) || ( val2 != "" ) && val2 > val ) ); 32 // 変更のあったセルの有る行の下の行の2列目を選択 33 var rowRange = sh.getRange(r+1, 2); 34 // 変更のあったセルの有る行の下の行の3列目を選択 35 var rowRangeRight = sh.getRange(r+1, 3); 36 // 変更のあったセルに1を入力 37 cell.setValue(1) ; 38 // 変更のあったセルの有る行の下の行の2列目に0を入力 39 rowRange.setValue(0) ; 40 // 変更のあったセルの有る行の下の行の3列目に変更のあったセルの値を入力して右隣にアクティブセルを移動 41 rowRangeRight.setValue(val).offset(0, 1).activate(); 42 } 43}

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

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

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

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

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

guest

回答2

0

ベストアンサー

スクリプトを直接実行してもセルに変更がないので働きません。
セルの変更に併せてスクリプトが動くようにトリガーを設定するかイベントハンドラにする必要があります。
また、Logger を活用してください。
下記のスクリプトが動くことを確認しました。

JavaScript

1function onEdit(e) { 2 // 変更のあったシート 3 var ss = SpreadsheetApp.getActiveSpreadsheet(); 4 var sh = ss.getActiveSheet(); 5 // 変更のあったセル 6 var cell = ss.getActiveRange(); 7 Logger.log(cell); 8 // 変更のあったセルの有る行番号 9 var r = cell.getRow(); 10 Logger.log(r); 11 // 変更のあったセルの有る列番号 12 var c = cell.getColumn(); 13 Logger.log(c); 14 // 変更のあったセルの左隣のセル 15 var cellLeft = sh.getRange(r, c - 1); 16 Logger.log(cellLeft); 17 Logger.log(cellLeft.getRow()); 18 Logger.log(cellLeft.getColumn()); 19 // 変更のあったセルの値 20 var val = cell.getValue(); 21 Logger.log(val); 22 // 変更のあったセルの左隣のセルの値 23 var val2 = cellLeft.getValue(); 24 Logger.log(val2); 25 // 変更のあったセルの左隣のセルの値が空白ではなく、変更のあったセルの値が変更のあったセルの左隣のセルの値よりも小さかった時に 26 if( ( val2 != "" && val2 > val ) ) { 27 Logger.log("val2 != \"\" && val2 > val"); 28 // 変更のあったセルの有る行の下の行の2列目を選択 29 var rowRange = sh.getRange(r+1, 2); 30 // 変更のあったセルの有る行の下の行の3列目を選択 31 var rowRangeRight = sh.getRange(r+1, 3); 32 // 変更のあったセルに1を入力 33 cell.setValue(1) ; 34 // 変更のあったセルの有る行の下の行の2列目に0を入力 35 rowRange.setValue(0) ; 36 // 変更のあったセルの有る行の下の行の3列目に変更のあったセルの値を入力して右隣にアクティブセルを移動 37 rowRangeRight.setValue(val).offset(0, 1).activate(); 38 } 39}

投稿2018/03/28 00:41

Zuishin

総合スコア28656

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

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

koromo_t

2018/03/29 00:56

回答ありがとうございます! お返事遅くなりましてすみません! 書いていただいたスクリプトを使ってみところ、 期待通りの結果を得ることができました! ありがとうございます! 「Logger」というコマンド?があるのですね! 初耳でした。 宣言した変数の計算結果を得るイメージと理解しました。 「変更のあったセル」が流動的だから、そのあとの処理に向けて固定する、みたいな…? あと、ダブルクォーテーションのなかにある「\」の意味はなにかなと思い調べたところ、 ダブルクォーテーション内でダブルクォーテーションを使ったりする際、 内部のダブルクォーテーションの前につけると、 ダブルクォーテーションの扱いじゃなくなる的なことなんですね、これも新たな知識でした。 ちなみに、そのあとその値の登場もないので「Logger.log(cellLeft.getRow());」と 「Logger.log(cellLeft.getColumn());」の行はいらないんじゃないかと思い、 削除して試してみたところ、やはり動作するっぽいです。 --- 「Logger」以外のアイデアについて。 セルの変更に併せてスクリプトが動くようにトリガーを設定するというのは、 具体的にはちょっとよくわからなかったですけど、 今回は「Logger」の方法がうまくいったのでそちらでいきます! もうひとつのイベントハンドラ…、 これも初めて聞く言葉だったので調べてみたところ、 「onClick」の例が出てきて、なんとなく理解しました。 そういうものがあること、覚えておきます! --- あと、ものすごく余談ですが、 Zuishinさんのアイコン画像を見て、東京駅の天井を思い出しました。
Zuishin

2018/03/29 01:15

Logger というのはログを取るための関数です。 その時の変数の状態を記録することができます。 動作には必要ありませんが、デバッグには役立ちます。 今回うまくいったのは Logger を使ったからではなく関数の名前を変えてイベントハンドラにしたからです。 「GAS Logger」で調べてみてください。 自分のプログラムのどこまでがうまくいってどこから失敗しているのか知るために大変重要な関数です。
koromo_t

2018/03/29 02:06

なるほど!! そうか、そう言われてみれば、関数の名前が変わっていますね! スプレッドシートが 編集されたときに動作する、という意味の、 イベントハンドラになっていたのですね! ああ~、なるほど~…。 これは実際やってみてダメだったことですが、 なぜ、スプレッドシートのトリガーの「値の変更」とか「編集時」ではダメなんでしょう…? いまさらながら、いただいた回答に書いてあった「セルに変更がないので働かない」の意味が よくわからないということがわかりました。 スプレッドシートにデータを入力するということは、値の変更であり、 編集時のような気がするのですが…。調べてみても、よくわかりませんでした。 Loggerの意味も、完全に勘違いしていました! これを仕込んでおけば、スクリプトの動作時、どのような値が結果となっているか、 ログをみれば確認できるようになるのですね。ようやく正しく理解したと思われます! あと、Zuishinさんのアイコン画像は東京駅の天井ですか?
Zuishin

2018/03/29 02:46

なぜ東京駅の天丼なのかわかりませんが、違います。 これは私のキーボードを万華鏡で見たもので、法則に則った無限の可能性がキーボードから生まれることを意味しています。 本題ですが、トリガーを使って何がうまくいかなかったのかよくわかりません。 トリガーの使い方が間違っていたのかもしれませんし、実行アカウントが違うのかもしれません。 関数名は変えなければいけませんが編集時のトリガーで正しく動作するはずです。 トリガーの使い方をもう一度調べてみてください。 そしてわからなければ別の質問を立て、調査結果を詳しく書いて尋ねてみてください。
koromo_t

2018/03/29 03:37 編集

気を悪くされたらすみません…! 私には、東京駅の天井を万華鏡加工したものに見えたので、そのように言いました。 いまさらですが、具体的な指定はせず、アイコン画像はなんの画像ですかという聞き方をすれば よかったと思いました。。。学習しました。 なるほど、キーボードを万華鏡で見たものだったのですね! 言われなければそうは思わないし、聞いたところで どこがどうなっているのか見当が付きませんが…w アイコンに込められた意味、とてもかっこいいです! やはり、聞いてみてよかったと思いました! --- トリガーを変更する際は、一度そのトリガーを削除して、 もう一度、初めから設定し直す必要があるみたいですね。 今回もそのようにしたつもりだったのですが、していなかった模様…? 今回は、ここがネックだったみたいです。 設定し直すと、やはり「値の変更」でも「編集時」でも、 仮にイベントハンドラでなくても、動作するみたいですね。 お騒がせいたしました…。
guest

0

#~解決後のまとめ~
Zuishinさんの回答を参考に解決しましたので、まとめておきます!
というか、後日談的なやつです。

今回の質問のネックは、トリガーの設定変更時に、
一旦そのトリガーを削除していなかったらしいことだったみたいです。
トリガーの設定を変更する際は、一度そのトリガーを削除して、
もう一度、初めから設定し直す必要があるみたいですね。
今回もそのようにしたつもりだったのですが、していなかった模様…?
設定し直すと、やはり「値の変更」でも「編集時」でも、
仮にイベントハンドラでなくても、動作するみたいですね。
お騒がせいたしました…。


後日談。

質問文には書いていなかったことなのですが、
今回、スプレッドシートのA列に日付リストがある状態で、
B列からデータを入力していくという状況であり、
私がもともと書いていたスクリプトのIF関数の条件、

javaScript

1 // 変更のあったセルの左隣のセルの値が空白ではなく、変更のあったセルの値が変更のあったセルの左隣のセルの値よりも小さかった時に 2 if( ( val2 != "" && val2 > val ) )

このなかの前半部分「変更のあったセルの左隣のセルの値が空白ではなく、」だけでは、
日付リストの横のデータを入力したときにも反応してしまうということがわかったので、
「変更のあったセルの2つ左隣のセル」の情報も取得して活用することで、
日付リストの横にデータを入力したら反応してしまう問題を解決しました。

最終的にはこんな感じのスクリプトになりましたので、お納めください(?)。

javaScript

1function onEdit(e) { 2 // 変更のあったシート 3 var ss = SpreadsheetApp.getActiveSpreadsheet(); 4 var sh = ss.getActiveSheet(); 5 // 変更のあったセル 6 var cell = ss.getActiveRange(); 7 Logger.log(cell); 8 // 変更のあったセルの有る行番号 9 var r = cell.getRow(); 10 Logger.log(r); 11 // 変更のあったセルの有る列番号 12 var c = cell.getColumn(); 13 Logger.log(c); 14 // 変更のあったセルの左隣のセル 15 var cellLeft = sh.getRange(r, c - 1); 16 Logger.log(cellLeft); 17 // 変更のあったセルの2つ左隣のセル 18 var cell2Left = sh.getRange(r, c - 2); 19 Logger.log(cell2Left); 20 // 変更のあったセルの値 21 var val = cell.getValue(); 22 Logger.log(val); 23 // 変更のあったセルの左隣のセルの値 24 var val2 = cellLeft.getValue(); 25 Logger.log(val2); 26 // 変更のあったセルの2つ左隣のセルの値 27 var val3 = cell2Left.getValue(); 28 Logger.log(val3); 29 // 変更のあったセルが変更のあったセルの2つ左隣のセルの値よりも小さいか、変更のあったセルの左隣のセルの値が空白ではなく、変更のあったセルの値が変更のあったセルの左隣のセルの値よりも小さかった時に 30 if( ( ( ( val < val3 ) || ( val2 != "" ) ) && val2 > val ) ) { 31 Logger.log( ( ( val < val3 ) || ( val2 != "" ) && val2 > val ) ); 32 // 変更のあったセルの有る行の下の行の2列目を選択 33 var rowRange = sh.getRange(r+1, 2); 34 // 変更のあったセルの有る行の下の行の3列目を選択 35 var rowRangeRight = sh.getRange(r+1, 3); 36 // 変更のあったセルに1を入力 37 cell.setValue(1) ; 38 // 変更のあったセルの有る行の下の行の2列目に0を入力 39 rowRange.setValue(0) ; 40 // 変更のあったセルの有る行の下の行の3列目に変更のあったセルの値を入力して右隣にアクティブセルを移動 41 rowRangeRight.setValue(val).offset(0, 1).activate(); 42 } 43}

投稿2018/03/29 03:41

編集2018/03/29 04:02
koromo_t

総合スコア60

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問