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

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

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

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

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

1307閲覧

GASからjQueryに2次元配列を渡そうとするとnullが渡される

ishiokapl23

総合スコア16

Google Apps Script

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

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2018/09/09 15:05

編集2018/09/10 09:13

質問者のレベル

職場で事務関係の仕事をしていたところ、「なんで人間様がこんな単純作業をしなくちゃいけないのだ???」と疑問に思い、EXCEL VBAを使って非効率な業務を人権ある快適な業務に改善していました。
次第にプログラミングの楽しさを感じ、プライベートでこの手の勉強を始めた人間です。
趣味で無線をやっているので、交信の記録をつけたり、参照したりする自分専用のWebアプリを作りたいと思い、GoogleAppsScript(以下GAS)に手を出しました。

HtmlとCSSは最低限触ったことがあります。
以前は勉強のためにApacheで開発環境を用意し、PHPとMySQLを使ってDBを操作するWebアプリを作成したことがあります。
(ただし詳しい内容までは理解していませんので、こうやって勉強している最中です。)

しかし今回は、自分でサーバーを用意せずにWebアプリを完成させられるという点に魅力を感じ、GASを使うこととしました。

前提・実現したいこと

無線の交信記録を管理するため、GAS、Html、jQuery(以下JS)を使って、データの登録と参照を行えるWebアプリのようなものを作成しています。
(データベースにはGoogle スプレッドシートを用いています)

参照機能の大まかな流れは
1 Htmlのform内に配置したbutton要素にonclick="google.script.run.withSuccessHandler……が書いてあり、ボタン押下時に指定したGASの関数が走る
2 GASの関数が、データベース用のスプレッドシートについて
(1)最新行を取得
(2)最初の行から最新行までのデータを、valuesという変数に2次元配列で変数に格納
3 JSで書いた表示用のコードに2次元配列(values)が渡され、良い感じに表示される
となっています。
(Htmlのボタン → GAS(配列取得) → JS(配列の整形と表示))

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

登録機能は諸先輩方の知恵を借りてどうにか動くようになったのですが、参照機能を作成中に不可解な挙動にぶつかりました。

まずGAS側で次のコードによって最新行を取得しています

GAS

1 var last_row = sheet.getRange("A:A").getValues().filter(String).length;

その後、次のコードによって、A1セルから最新行のPセルまでのデータを取得しています。
(spreadsheetやsheetはちゃんと事前に開いてあります)

GAS

1 var values = sheet.getRange(1, 1, last_row, 16).getValues(); 2 return(values);

さて、ここからが問題で……

・スプレッドシートに入っているデータが232行以下の場合、問題なく動作した
・データが233行以上の場合、JSはnullを受け取っていた(うまく送れてない or うまく受け取れてない)
・データが233行以上でも、GAS側で「最新行-1行目」までとか、-2行目までとかしか2次元配列に格納しないようにした場合、最新業までは取得できないもののちゃんと配列が渡せていた
・最初の行などの古いデータは参照しないように、例えば「10行目から最新行まで」のような指定の仕方をしても、233行以上データが登録されているとJSはnullを受け取っていた。

という状況に陥っています。
最初は単純にデータサイズが大きくてうまくいっていないのかな?と思ったものの、最後の条件がわからず、質問するに至りました。

該当のソースコード(抜粋)

不必要なまでにidとclassとnameを書いてあります。自覚してます。

html

1 <form> 2 <div class="search_form"> 3 <button type='button' class="search_btn" id="search_btm" name='action' onclick="google.script.run.withSuccessHandler(onSuccess_ref).ref_DB();" value='search'>検索</button>< 4 </div> 5 </form> 6 7 <div id="result"> 8 <!--ここに結果が表示される--> 9 </div>

GAS

1 2function ref_DB(){ 3 //シートを定義 4 var spreadsheet = SpreadsheetApp.openById('スプレッドシートのID'); 5 var sheet = spreadsheet.getSheetByName('シート名'); 6 7 //最新行を取得 8 var last_row = sheet.getRange("A:A").getValues().filter(String).length; 9 10 //最新行までのデータを2次元配列で取得 11 var values = sheet.getRange(1, 1, last_row, 16).getValues(); 12 return(values); 13} 14

JS

1 2 3function onSuccess_ref(values){ 4 $("#result").empty(); 5 alert(values); /*valuesの中身を確認するデバック用*/ 6 7 //Table要素を始める 8 var res="<table class=\"result_table\">"; 9 //DBシートの1行目を引っ張ってきてth要素を整備 10 for(var c=0; c<=15; c++){ 11 res=res+"<th>"+values[0][c]+"</th>"; 12 } 13 14 var length = values.length; 15 //2次元配列から行を取り出すfor文 16 for(var r=1; r<=length-1; r++){ 17 res=res+"<tr>"; 18 //取り出した行の中身をズビャーって取り出すfor文 19    for(var c=0; c<=15; c++){ 20 res=res+"<td>"+values[r][c]+"</td>"; 21    } 22 res=res+"</tr>"; 23 } 24 res=res+"</table>" 25 26 $("#result").prepend(res); 27 28} 29

試したこと

GASの、2次元配列を取得する範囲を指定するコードについて、範囲指定の仕方をいろいろ試してみました。
スプレッドシートのデータは234行あります。

GAS

1 var values = sheet.getRange(1, 1, last_row, 16).getValues();

・(1, 1, last_row, 16)→null
・(1, 1, last_row-2, 16)→成功
・(1, 1, 232, 16)→成功
・(2, 1, 232, 16)→null
・(last_row-50, 1, last_row, 16)→null (最新50データだけを扱うようにしてみたかった)

まとめ

2次元配列に格納するデータを232行目までに制限して取り扱えばうまく行ったので、データサイズがネックなのか?と思いきや、
最新マイナス50行目から最新行までを取得させるように書き換えたらnullが帰ってきたので、単純にデータサイズが問題ってことではなさそう。

諸賢の知恵をお借りしたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

なにが原因かは私にはわかりませんが、少し関数について誤解されているようなので、それについて補足しますね。

getRange(row, column, numRows, numColumns)で、numRows numColumnsは行数、列数を指します。

つまり(last_row = 234と仮定すると)

  • (1, 1, last_row, 16) → 1~234行目 → null
  • (1, 1, last_row-2, 16) → 1~232行目 → 成功
  • (1, 1, 232, 16) → 1~232行目 → 成功
  • (2, 1, 232, 16) → 2~233行目 → null
  • (last_row-50, 1, last_row, 16) → 184~417行目 → null

となります。

私からは、233行目になにかnullとなるデータが入っているのでは?という仮定です。
getRange(233, 1, 1, 16)
で一度試してみるといいかもしれません。

投稿2018/09/10 01:28

macaron_xxx

総合スコア3191

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

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

ishiokapl23

2018/09/10 08:42 編集

早速のお答えありがとうございます。 getRangeは2つの座標を指定してその範囲を取得するのではなく、始点の座標を指定して、そこから参照する範囲を決めているんですね。誤解していました……。 さて、お勧め頂いたとおり233行目のみを呼び出すようにgetRange(233, 1, 1, 16)してみたところ、お見込みの通り、nullが帰ってきました。 他のデータとの違いを検討した結果、233行目は手入力したデータだったため、日付欄が単純な数字ではなく日付データ(?)扱いになっていました。 Google スプレッドシートの表示形式を「日付」ではなく「書式なしテキスト」としたところ、無事に最新業までのデータを取得することができました。 お陰様で解決することができ嬉しく思います。ありがとうございました!
macaron_xxx

2018/09/10 09:06

解決してよかったです。 試したことまで場合分けしてキチンと書いていただいていたので、問題を発見することができました。 ナイス質問でしたよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問