質問者のレベル
職場で事務関係の仕事をしていたところ、「なんで人間様がこんな単純作業をしなくちゃいけないのだ???」と疑問に思い、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が帰ってきたので、単純にデータサイズが問題ってことではなさそう。
諸賢の知恵をお借りしたいです。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/09/10 08:42 編集
2018/09/10 09:06