#はじめに
こんにちはGoogle Apps Scriptを扱い初めてまだ2ヶ月の初心者山口です。ここ一ヶ月くらい悩んでいたエラーがやっと解決したのでQiitaに初投稿します。気づいてみれば初心者らしい基本的な間違いなのですが、ググってもヒットしなかったので、同じようなエラーに悩んでいる人のためにまとめました。
#やりたいこと:フォームの入力先URLを得る
グーグルフォームの入力用URLを毎日メールで配信しており、これを自動化したいとスクリプトを組んでました。
作業としてはテンプレートのformをコピーして新しいファイルを作り、フォームの入力先URLを得る(.publishedUrl)というだけの単純なスクリプトです。
function createform() {
var templateFile = DriveApp.getFileById('XXXXXXXXXX'); //テンプレートのフォームのIDを取得
var OutputFolder = DriveApp.getFolderById('yyyyyyyyyy'); //コピー先フォルダ
var OutputFileName = 'hogehoge' //新しいファイル名
var form = templateFile.makeCopy(OutputFileName, OutputFolder); //テンプレートをコピーしたものをformに
var PublishedUrl = form.getPublishedUrl(); //入力用URL取得
しかし、これがエラーになるのです。回答先のシートを変更する(.setDestination)でも同じエラーが帰ってきます。
TypeError: form.getPublishedUrl is not a function(行 7、ファイル「コード」)
##TypeError:(オブジェクト)(メソッド) is not a function
このtypeErrorをぐぐってみると、
・エラーの理由:関数以外のオブジェクトを関数呼び出ししている
・よくある原因:undefinedを関数呼び出ししている
・対策:undefinedに気をつける
(中略)
つまり、だいたいタイプミスかメソッド名の勘違いです。undefinedには気をつけましょう。
Subterranean Flower Blog
とのことで目を皿のようにして何回もチェックしたり、webからコードをコピーして貼り付けたりしましたが、うまくいきません。1ヶ月ほど悶々と悩んで、今日やっと原因に気づきました。
#オブジェクトのクラスが違っていた
原因は formというオブジェクトがfileとして定義されていることでした。makeCopyというメソッドはFileクラスなので、それで得られたformもfileオブジェクトになっていたのでした。
あらためてformオブジェクトとしてopenしたところうまくいきました
var form = Formapp.openById('zzz') //id=zzzのフォームを開く
普通フォームを作るときは
var form = FormApp.create('ファイル名');
という風にやると思いますが、これだとマイドライブにフォームが作られてしまって、そのあと希望のフォルダーに移動しないといけないので面倒です。いっぽうmakeCopyは同じフォルダーにコピーしてくれるので便利です。しかし、今回はこれが落とし穴だった訳ですね。すっぽりハマりました笑。
#コンテンツアシスト大事ですね
ちなみに気づいたきっかけはコンテンツアシストを使い始めたら、getpubshedUrlや.setDestinationが選択肢に出てこないことでした。もしかしてクラスが違うのかな?と思って、formとして開いたらうまくいきました。日頃からコンテンツアシストを使うのも重要ですね。
あとオブジェクトのクラスが調べられると良いなぁと思ったのですが、そのような機能はないようです。(あったら教えて下さい)
#まとめ
" is not a function"のエラーがでたら関数のスペルチェックとともにオブジェクトのクラスを確認
予防としてコンテンツアシストを日頃から使おう