GASを使ってスプレッドシートに書き込むというのは、Google Apps Script(GAS)でスプレッドシートを外部から操作するでもやりました。またスクリプトエディタで以下のようなものをつくればスクリプト内の任意の関数を呼び出すことができます。

GASを外部から実行させる

ということで外部からデータを二次元配列で渡せばスプレッドシートに書き込めるのではないかと考えていたのですが、実際にやってみるとうまくいきません。

GASは外部からデータを二次元配列で渡せない

上記のコードは

のように内部で実行する場合はうまくいきますが、外から実行しようとするとSetCellValues関数に渡された配列がundefinedになってしまいます。これは仕様なのでどうすることもできません。

どうしても二次元配列をGASに渡したい場合

ではどうするのかというと配列で渡せないなら文字列で渡します。そしてGASの内部で二次元配列に展開して自作関数SetCellValuesに渡します。

たとえば以下のようなDataクラスのリストがあったとします。

これをスプレッドシートに書き込むためには以下の方法でPostします。

やろうとしていることは二次元配列では送れないのでひとつの文字列に変換しています。各列にセットしたい文字列を改行で区切り、次の行に書き込みたい場合は連続する二つの改行で区切ります。そのため各セルにセットする文字列のなかには改行は存在しないというのが前提です。

それからサンプルプログラムのなかにはWebClientを最後にdisposeしたり、usingで囲っているものがありますが、これはよくないそうです。これに関してはHttpClientをusingで囲わないでくださいを参照してください。

GAS側では以下のようにすればスプレッドシートに書き込むことができます。ただ最後にSetCellValues関数を呼び出していますが、sheet.getRange関数で指定した部分とsetValues関数で渡した配列のサイズが合わないとエラーになります。

C#ではありえないJavaScriptならではのハマりどころ

他にハマったことがあって配列をそのままではなくソートしてから書き込みたい場合、

7,000
4.5万
10万

実際には 7,000 < 4.5万 < 10万なのですが、このままでは文字列として処理されるので期待した結果が得られません。そこで文字列を数値に変換します。この方法は「10万2400」のようなときに使うとおかしなことになります。最後は「万」で終わっていることが前提です。

ここで注意しなければならないのはうっかりすでに数値に変換されているものをまたStringToNumberに渡すとエラーが発生することです。数値なのでreplaceという関数は存在しないと怒られます。

以下のような失敗をしてしまいました。同じ変数にstrig型でもNumber型でも代入できてしまうところがJavaScriptの怖いところです。C#の場合はコンパイル段階でエラーになるのでやらかしてもすぐに気がつきます。

またNumber型に変換できない文字列を渡すと例外が発生すると思い込んでいたのですが、実際にはNaNが返されます。

あとJavaScriptを使っている人なら周知のことと思いますが、この場合「同じ」と表示されます。C#ばっかり使っていると不思議に見えますが、JavaScriptだと同じと判定されます。違うと判定させるためには if(a === b)としなければなりません。動的型付け言語の便利だけどややこしい部分です。