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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1992閲覧

スプレッドシート:①判定 ②指定した数の変数を動的に生成したい

kusunoki

総合スコア17

Google Apps Script

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/05/17 10:02

編集2017/06/09 07:01

アドバイスを頂き、質問を3つに分割させていただきました。

###実現したいこと
test2の要素それぞれをtest3の要素と一致するか判定し、test3にその値を入れたい。(test3はシート1のA列)

そのためにtest2の要素数分の変数(配列)を宣言したい。

ex.
test2の要素が2016/05/11,2016/05/14,2016/05/15のとき、

test3が2016/05/11 エラー,2016/05/14 エラー,2016/05/14 A,2016/05/15 B
test3に入っているすべての要素(日付の含まれるテキスト)全てに対して、test2の要素2016/05/11 2016/05/14 2016/05/15それぞれが含まれるか判定したい。
そして
2016/05/11を含むなら、ary_1へ 2016/05/11 エラー
2016/05/14を含むなら、ary_2へ 2016/05/14 エラー,2016/05/14 A
2016/05/15を含むなら、ary_3へ 2016/05/15 B
をpushしたい。

さらに、この日付部分は後にシートの名前やメールタイトルにしたいです。
配列の値は改行を加えた本文や、セルの値として使用していきたいです。

###試したこと
1-1,test2の要素数分の配列を宣言

var count2 = test2.length; for(var i=1;i<=count2;i++){ eval('var ary_' + i -1+ '=[];'); } Logger.log(ary_1);

1-2,配列test2の要素それぞれに、test3の要素それぞれが一致するか判定して、1-1で作った配列に入れたい。

var maxRow=Sheet01.getDataRange().getLastRow(); var test3 = Sheet01.getRange(1,1,maxRow,1).getValues(); var count3 = test3.length; for(var i=1;i<=count2;i++){ var date = test2[i]; for(var j=0;j<count3;j++){ var g = test3[j].match(date); if(g != null){ eval('ary_'+ i-1 +'.push(g)'); } } }

1-3,セルに1-11-2で作ったそれぞれのary_1xの値を使用したい

for(var i=1;i<=count2;i++){ eval('var mailtext = ary_' + i-1 + ';'); /*例. var mailtext = ary_1;*/ eval('var count4 = ary_' + i-1 + '.length;'); /*test2の個数だけ日付のシートを左端に作成して要素をA列にセットしたい*/ for(var j=1;j<=count2;j++){ SpreadsheetObject.insertSheet(test2[i]) `Sheet0`2+i-1`+`.getRange(A,A).setValues(ary_`+i); } /*test2の個数だけary_xそれぞれのメールを送信したい*/ for(var q=1;q<=count2;q++){ eval(`GmailApp.sendEmail("~~~~@~~~.com",test[i]+"分",ary_`+q+`);`); } }

###結果
1-1,これでは重複が除けませんでした。
var test = [2017/05/11,2017/05/14,2017/05/14,2017/05/15];
とすれば動きますが、範囲はかわるためシートから取得したいです。

1-2,
eval();を使用した生成ができない。
また、eval()は使用するべきではないとも聞きます。他に方法があるのでしょうか。

1-3,
出来ませんでした。

###参考
http://qiita.com/htano/items/2476c7f616bed531e2f3

###補足
実際使用するtest2やtest3のデータは
シートからgetRange().getValues()でもってきたもので、になります。

###進行状況 教えていただいたどちらも試しています

A,配列を使用する方法
coco_bauerさんにいただいたアドバイスから

var test2 = Sheet03.getRange(2,1,maxRow).getValues(); var c2 = test2.length; var test3 = Sheet03.getRange(2,2,maxRow).getValues(); var c3 = test3.length; var ary = []; for(var i=0;i<c3;i++){ var date = test3[i]; var ary[i] = []; for(var j=0;j<c2;j++){ var res = test2[j].match(date); if(res != null){ ary[i].push(date) } } }

としてみました。
しかし、
matchのところで、「オブジェクト[2017/05/11 21:53:43]A1で関数matchが見つかりません。」となり、
var ary[i] = [];の箇所で配列の中に配列を作ろうとすると「ステートメントの前に;がありません。」
となってしまいます。
(多次元配列 参考:http://hakuhin.jp/js/array.html#ARRAY_04 https://www.ajaxtower.jp/js/array/index5.html)

B,kei344さんに教えていただいたものも理解したいため、調べながら試しています。

var test2 = [ '東京', '神奈川', '千葉' ]; var test3 = [ '東京都千代田区', '東京都世田谷区', '神奈川県川崎市', '千葉県柏市' ];

データが上記のような場合
Logger.log(res)
{神奈川=[神奈川県川崎市], 東京=[東京都千代田区, 東京都世田谷区], 千葉=[千葉県柏市]}
Logger.log(res["東京"])
[東京都千代田区, 東京都世田谷区]
と出来たのですが、実際使用する日付型のデータだと出来ないでいます。
実際日付を扱うため、並びも日付順(もとのまま)であって欲しいです。

###この後以下の処理をしたい
続けて、内容をテキストファイルとして書き出したり、シートを生成したり、メールとして自動送信する際にここで作った値を使用したいのです。

メール、最初の例のデータの場合
<タイトル>
2016/05/14
<本文(1つずつ改行する)>
2016/05/14 エラー
2016/05/14 A

日付型データでの処理がうまくいかないため、現在はまだ、先程の都道府県のデータで試しているのですが、実現出来ていません。データが追加されるたびに送信されてしまったり、送信順が日付順ではなくなってしまうのです。また、後からループなどで扱おうとした際にres["東京"]など、数字で指定できないのです。
そこでメールの自動送信を諦めて、まず日付ごとに振り分けたデータをその日付毎にシートや別ファイルとして書き出すことにとどめようかと考えています。
しかしシートを日数データ分の数十~数百個も作成するわけにも行かず悩んでいます。

今回の質問はこのために考えた工程だったのですが、遠回りしていますでしょうか。

###メッセージ
解決までまだまだ時間がかかりそうです。スコア等皆様ご迷惑おかけします。

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

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

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

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

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

coco_bauer

2017/05/24 05:34

変数を生成しようとするから苦労しているように見えます。aryという配列を定義して、ary[0]をary_1,ary[1]をary_2,ary[2]をary_3だと思って使えば良いのでは?
kusunoki

2017/05/24 08:28

配列の中に配列を入れるというのがよくわからなくて。こちらを使った方法も試してみます。ありがとうございます。
guest

回答1

0

ベストアンサー

とりあえず重複を拾ってみるコードを。GASで使えるのがES6相当であればもう少しきれいにかけるはず。データの処理については、ブラウザで動くJavaScriptを書いてからGASに組み込んでみてはいかがでしょう。

JavaScript

1var res = {}, i, l, tmp, key; 2var test2 = [ '2016/05/11', '2016/05/14', '2016/05/15' ]; 3var test3 = [ '2016/05/11 エラー', '2016/05/14 エラー', '2016/05/14 A', '2016/05/15 B' ]; 4 5for( i = 0, l = test2.length; i < l ; i++ ) { 6 res[ test2[ i ] ] = []; 7} 8for( i = 0, l = test3.length; i < l ; i++ ) { 9 tmp = test3[ i ]; 10 for ( key in res ) { 11 if ( !res.hasOwnProperty( key ) || tmp.indexOf( key ) == -1 ) { continue; } 12 res[ key ].push( tmp ); 13 } 14} 15console.dir( res ); // ブラウザのデベロッパーツールで確認する場合 16```**動くサンプル:**[https://jsfiddle.net/45a7hvdg/](https://jsfiddle.net/45a7hvdg/) 17```JavaScript 18// 上記結果を使うとき 19for ( key in res ) { 20 if ( !res.hasOwnProperty( key ) ) { continue; } 21 console.log( res[ key ] ); // 配列 22}

追記:

hasOwnProperty

【JavaScriptのループについて(オブジェクト編) - Tomcky's blog】
http://tomcky.hatenadiary.jp/entry/2014/06/16/224904


いまいち状況がわからないのですが、配列でもそれぞれの要素にUtilities.formatDateを使うことができますよ。

JavaScript

1var res = {}, i, l, tmp, key; 2var test2 = [ new Date( '2016/05/11' ), new Date( '2016/05/14' ), new Date( '2016/05/15' ) ]; 3var test3 = [ '2016/05/11 エラー', '2016/05/14 エラー', '2016/05/14 A', '2016/05/15 B' ]; 4 5for( i = 0, l = test2.length; i < l ; i++ ) { 6 res[ Utilities.formatDate( test2[ i ], 'Asia/Tokyo', 'yyyy/MM/dd' ) ] = []; 7} 8for( i = 0, l = test3.length; i < l ; i++ ) { 9 tmp = test3[ i ]; 10 for ( key in res ) { 11 if ( !res.hasOwnProperty( key ) || tmp.indexOf( key ) == -1 ) { continue; } 12 res[ key ].push( tmp ); 13 } 14} 15console.dir( res ); // ブラウザのデベロッパーツールで確認する場合

投稿2017/05/24 07:50

編集2017/05/26 16:47
kei344

総合スコア69364

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

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

kusunoki

2017/05/24 08:27

ありがとうございます。 教えていただいたものを理解出来るよう、もう少し調べてみたいと思います。
kusunoki

2017/05/26 16:32 編集

・どうしてもわからない箇所があり、よければ質問させてください for in辺りからうまく理解できないでいます。 tmp.indexOf( key ) == -1では、-1が返ることを利用しているのだと思うのですが、!res.hasOwnProperty( key )がどんなことをしており、なぜ必要なのかがわからず悩んでいます。 resがkeyというプロパティを含むか?だと思うのですがfor inの箇所でresのプロパティがkeyとして取り出されていっているのだと認識していて、それならば必ず含んでいるのではないかと解釈してしまいます。 一つづつ試してみたのですが、躓いてしまっています。 ・例にあげた値について 例にあげたものがよくありませんでした。申し訳ありません。 実際のtest3のデータはtest2から抽出し、セルにセットしたものでした。 その時点までは文字列として扱えたのですが、今回のように拾うと日付型になってしまうのです。例[Thu May 11 00:00:00 GMT+09:00 2017] Utilities.formatDateで一つ一つなら扱えるのですが配列では出来ず、その後に何か処理をすることも出来ません。
kusunoki

2017/06/12 08:09 編集

hasOwnPropertyについて少し理解できた気がします。 ただ配列の番号ではなく、プロパティ名を指定していく方法がわからないでいます。 for(x in res)などを使うのだろうかと思ったので頑張ってみます。 皆さんありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問