🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google Apps Script

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

Q&A

解決済

1回答

849閲覧

if文での条件分岐(continueの使い方)

kumer1

総合スコア26

Google Apps Script

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

0グッド

0クリップ

投稿2019/12/17 04:58

前提・実現したいこと

あるスプレッドシート(サンプルデータ)から”Baby”という件名の入った行データを別のシート(集計表)に抽出したいです。データはうまく抽出できましたが、”Baby”以外の件名が入っている行が空白として集計表に組み込まれてしまうのをなんとかしたいです。
※これはサンプルデータですので数行ですが、本番は数百行あります。

▼サンプルデータ

No件名金額
Tk01001Baby15,000
Tk01002Baby15,000
Tk02001Kids20,000
Tk03001Adult25,000
Tk01003Baby15,000
Tk03002Adult25,000

▼実現したい結果(集計表)

No件名金額
Tk01001Baby15,000
Tk01002Baby15,000
Tk01003Baby15,000

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

スクリプトを実行するとBaby以外の件名の部分が空白行になって表示され、行が上に詰まっていかないです。

▼実行結果(集計表)

No件名金額
Tk01001Baby15,000
Tk01002Baby15,000
Tk01003Baby15,000

該当のソースコード

GAS

1function confirmation() { 2 var ss = SpreadsheetApp.getActiveSheet();//集計表 3 var ssid = "xxx";//サンプルデータ 4 var ss2 = SpreadsheetApp.openById(ssid); 5 var sht = ss2.getSheets(); 6 var area = sht[0].getRange('B:B').getValues(); 7 var rows = area.length; 8 for(var i = 2; i<rows; i++){ 9 if(sht[0].getRange(i, 2).getValue() === 'Baby'){ 10 ss.getRange(i, 1).setValue(sht[0].getRange(i, 1).getValue()); 11 ss.getRange(i, 2).setValue(sht[0].getRange(i, 2).getValue()); 12 ss.getRange(i, 3).setValue(sht[0].getRange(i, 3).getValue()); 13 }else if(sht[0].getRange(i, 2).getValue() != 'Baby'){ 14 continue; 15 } 16 } 17} 18

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

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

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

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

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

azuapricot

2019/12/17 05:07

そりゃ i を行番号として使ってるからじゃないですか? 行番号を別で計算しておかないとcontinueで飛ばした行数分空くのは当たり前かと?
guest

回答1

0

ベストアンサー

いろいろと問題点があるっぽいのでいろいろ書いておきます。

空白行の問題

これはazuapricotさんの意見がズバリそうなのですが、continue;はループ文内でそれ以降をスキップするものですので、for文を繰り返していくと


for(var i= 2; i<rows; i++)

i = 2 (一回目の処理)
sht[0].getRange(2,2).getValue() == 'Baby'
だったら、
ss.getRange(2, 1).setValue(sht[0].getRange(2, 1).getValue());以下略
ちがってたら、continue


i = 2 → i++ = 3 (二回目の処理)

sht[0].getRange(3,2).getValue() == 'Baby'
だったら、
ss.getRange(3, 1).setValue(sht[0].getRange(3, 1).getValue());以下略
ちがってたら、continue


i = 3 → i++ = 4 (三回目の処理)
sht[0].getRange(4,2).getValue() == 'Baby'
だったら、
ss.getRange(4, 1).setValue(sht[0].getRange(4, 1).getValue());以下略
ちがってたら、continue


ここで3回目の処理をみてみると、
対象が'Baby'に関係なく、 i はカウントされていきます。
その結果、

.setValue(sht[0].getRange(4, 1).getValue())

ここの部分が問題で、空白が出てきます。

例えばの対応策

まずは同じiを取らない事と、貼り付け文が動いたら、独立させてカウントしてみましょう。

GAS

1var j = 2 2 for(var i = 2; i<rows; i++){ 3 if(sht[0].getRange(i, 2).getValue() === 'Baby'){ 4 ss.getRange(j, 1).setValue(sht[0].getRange(i, 1).getValue()); 5 ss.getRange(j, 2).setValue(sht[0].getRange(i, 2).getValue()); 6 ss.getRange(j, 3).setValue(sht[0].getRange(i, 3).getValue()); 7 j += 1 8 }else if(sht[0].getRange(i, 2).getValue() != 'Baby'){ 9 continue; 10 } 11

その先にある問題点

本番は数百行あるようなのですが、
ループ文内で.getRange .getValueを使いすぎると処理速度の問題がでてきます。
まずは、getValuesをして、それをループ文内で処理をして、その後setValuesしてみてください。

サンプルコードはこんな感じ

GAS

1function confirmation() { 2 var ss = SpreadsheetApp.getActiveSheet();//集計表 3 var ssid = "xxx";//サンプルデータ 4 var ss2 = SpreadsheetApp.openById(ssid); 5 var sht = ss2.getSheets(); 6 var area = sht[0].getRange('B:B').getValues(); 7 var rows = area.length; 8 9 var arr = []; 10//格納スペースを作ります。 11 var data = sht[0].getRange(1,1,sht[0].getLastRow(),sht[0].getLastColumn()).getValues() 12 //対象データを一括で取り込みます。 13 14 for(var i in data){ 15 if(data[i][1] === 'Baby') 16 { 17 arr.push(data[i]) 18 } 19 } 20 21ss.getRange(2,1,arr.length,arr[0].length).setValues(arr) 22} 23

正しく動くかはわからないので動きだけ解説しますと、

1.対象のデータをgetValues()します。
2.対象をループ文で調べていきます。
3.if文で正しければ別のスペースに正しいものだけ格納していきます。
4.終わったら、それを纏めて貼り付けます。

以上後は頑張ってみてください。

投稿2019/12/17 11:16

編集2019/12/17 11:20
takaD

総合スコア315

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

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

kumer1

2019/12/17 13:36

いつもご回答ありがとうございます。最初のcontinueの部分の説明分かりやすかったです。理解できました。あとプログラムの修正点も。爆速になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問