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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

Q&A

解決済

2回答

1572閲覧

【GAS】条件に合致した行にだけ連番を振りたい

donguriko

総合スコア30

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google Apps Script

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

0グッド

1クリップ

投稿2023/02/11 08:39

前提・実現したいこと

C列に連番を振りたい。
ただし、連番を振る対象は、A列にチェックがある行だけ。
(A列にチェックなしは連番は振らない)

(スプレッドシートイメージ)
イメージ説明

発生している問題・エラーメッセージ

(正)
セルC2:1
セルC3:2
セルC4:ブランク
セルC5:ブランク
セルC6:3  としたいが、

現コードだとA列が trueか falseかを問わずセルC2から連番が
振られてしまう。

試したこと

連番ではなく、A列が trueの時に一律"★"を追記 の処理はできました。

なので、一律"★"を追記 の部分を、
A列=true分だけでループをまわし、1はじまりのループカウンタ(j)を
setValue()すればできるか? の発想からコードを書いてみたのですが、
現コードではA列の値を問わず、ループがまわってしまい、失敗して
いそうです。

(処理後のイメージ)
イメージ説明

現コード(orアプローチの仕方) のどこがNGで、どのように
コード修正すればよいか、アドバイスをいただけないでしょうか?

該当のソースコード

下にコード全文記載します

GAS

1function addNumber() { 2 3 /* 4 A列チェックありの行だけで新配列arrTrueを作成 5 */ 6 7 const ss = SpreadsheetApp.getActiveSpreadsheet(); 8 const sheet = ss.getActiveSheet(); 9 const lastRow = sheet.getLastRow(); 10 console.log('lastRow ' + lastRow); //6が出た 11 12 const myValues = sheet.getRange(2, 1, 5, 1).getValues(); 13 console.log('myValues ', myValues); 14 15 const arrTrue = myValues.filter(value => value[0]); 16 console.log("arrTrue.length " + arrTrue.length); 17 console.log("arrTrue ", arrTrue); 18 const trueNum = arrTrue.length; //最終連番 19 console.log('trueNum ' + trueNum); //3が正解 20 21 for (i = 0; i <= 4; i++) { 22 const flag = myValues[i][0]; 23 if (flag === true) { 24 for (let j = 1; j <= trueNum; j++) { 25 //A列=trueの配列arrTrueの要素の数trueNum分だけ処理を行う 26 //sheet.getRange(i + 2, 3, 1, 1).setValue("★"); //できる 27 sheet.getRange(j + 1, 3, 1, 1).setValue(j); //★うまくできない★ 28 } 29 } 30 } 31 SpreadsheetApp.flush(); 32 Browser.msgBox("処理したよ"); 33} 34

補足情報(FW/ツールのバージョンなど)

回答は急ぎません。
次回から自分で解決できるようになりたいので、
非エンジニアビギナーでも理解できるレベルでの解説を
いただけると助かります。
お手数をおかけいたしますが、どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

既にベストアンサー付いていますが、GAS使わず数式だけで実現できるので回答しておきます。

C2 セルに以下の数式を指定し、C3~C6 セルはこの C2 セルをコピーしてやるとA列にチェックされている行だけ番号が表示されます。

=IF($A2=TRUE, COUNTIF($A$2:$A2,TRUE), "")

やっていることは簡単で、A2セルから対象行までのAnせるまでのチェックされている(値がTRUE)のセル数をカウントして、表示しています。

$A$2$A2の違いがポイントになります。

注意点として、GASで実現する場合と違い、チェックON・OFFするとリアルタイムにC列の数値が変わります。

これはExcelでも使えるテクニックなので、覚えておくと便利です。

投稿2023/02/11 09:56

編集2023/02/11 09:57
draq

総合スコア2573

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

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

donguriko

2023/02/11 10:27

draqさま 別解ありがとうございます。 関数で処理する方法もアリですね。 現在の想定データの最終行は6行目固定ですが、 もし処理の都度最終行が変わる場合には、 最終行(見出し行を除外したデータ行数)を取得のうえ、 setFormula('IF($A2=TRUE, COUNTIF($A$2:$A2,TRUE), "")') で 処理するやり方もできる、ということですね。 ご教示いただくとなるほど~、となるものの、自分ひとりでは思いつけない。。。 =IF($A2=TRUE, COUNTIF($A$2:$A2,TRUE), "") これから使い倒したいと思います。 精進します!! レクチャーありがとうございました。 勉強になりました。(感謝)
draq

2023/02/11 10:58

> setFormula('IF($A2=TRUE, COUNTIF($A$2:$A2,TRUE), "")') で GASから数式をセットする場合は、$A2の行番号の部分が自動的に変動しないので、その部分だけ注意です。 GASのコード内で行番号を必要に応じてカウントアップしていく必要があります。 回答にも書いたように、チェックON・OFFのタイミングでリアルタイムに番号が変わってほしいかどうかで、この方法を採用するか判断すればいいと思います。
guest

0

ベストアンサー

解説はコード内のコメントと、つまづきそうなポイントには参考URLを紹介しています。
ご一読ください。

コード例

javascript

1function writeSerialNumbers() { 2 const ss = SpreadsheetApp.getActiveSpreadsheet(); 3 const sheet = ss.getActiveSheet(); 4 5 // A列の値(True/False)を取得して一次元配列化 6 const bools = sheet.getRange(2, 1, sheet.getLastRow()-1, 1).getValues().flat(); 7 // [[true], [true], [false], [false], [true]] ---> [true, true, false, false, true] 8 9 // 連番の開始番号 10 let i = 1; 11 12 // 連番の2次元配列を生成 13 // チェックボックスの値がtureなら、iを配列に入れた[i]を値とし、iに+1加算する 14 // falseなら、空文字を配列にいれたもの['']を値とする 15 const numbersToWrite = bools.map(bool => bool ? [i++] : ['']); 16 // [[1], [2], [''], [''], [3]] 17 18 // C列に生成した連番を書き込む 19 sheet.getRange(2, 3, bools.length, 1).setValues(numbersToWrite); 20}

参考

投稿2023/02/11 09:04

Cocode

総合スコア2314

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

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

donguriko

2023/02/11 09:18

Cocodeさま 早速の回答ありがとうございます。 連番なし(ブランク)も含めた、転記用の「連番」配列を生成し、 生成した配列をまるっとsetValues()するのですね。 連番をふる対象にばかり意識が向き、視野が狭くなってました。 考え及ばず。。。 そして、苦手なmap()と三項演算子のリンクもありがとうございます。 ご回答いただいた内容、勉強します。 回答ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問