Googleフォームを使っていると以下のようなエラーが発生することがあります。
TypeError: item.setChoiceValues is not a function()
setChoiceValuesの部分がasListItemになったり、setChoicesでエラーが出ることもあります。基本的にはGoogleフォームで既にある質問項目を後から変更しようとしたときに発生するエラーです。
このエラーの対処をすることは、既にある設問項目をGASを使って後から変更することにもなります。
ここではこのエラーの原因と対処法(既にある設問項目をGASを使って後から変更する方法)についてまとめています。
エラーの発生状況
このエラーはgetItemsやgetItemByIdなどを使ってGoogleフォームからアイテムを取得し、取得したアイテムに対して、設問内容を変更する「setChoiceValues」や「setChoiceValue」メソッドを使用しようとしたときに発生します。
function editForm() {
const formId = "フォームID";
const form = FormApp.openById( formId );
const itemsCheckBox = form.getItems(FormApp.ItemType.CHECKBOX);
const checkBox1 = itemsCheckBox[0];
checkBox1.setChoiceValues(["自分","配偶者", "子供"]); //ここで発生
}
なお、対象のオブジェクト(アイテム)に対して、setTitleやsetDescriptionなどのメソッドは使うことができます。
エラーの原因
エラーが発生する原因はgetItemsやgetItemByIdメソッドで取得したオブジェクト(アイテム)自体に質問などの項目を編集する「setChoiceValues」や「setChoiceValue」を使っているためです。
setTitleやsetDescriptionなどのメソッドはアイテムの型に関係なく汎用的に使えるメソッドのためエラーが発生しません。
ですが、「setChoiceValues」や「setChoiceValue」を使うには型を指定して取得する必要があります。
エラーの対処法
型を指定してアイテムを取得する
「setChoiceValues」や「setChoiceValue」といった各アイテムの設問項目を操作するメソッドを使うためには、asChecboxItemメソッドなどのように「as~」というメソッドを使って、アイテムの中の設問項目を取得する必要があります。
item.as~メソッド.設問項目を操作するメソッド
▼例
item.asCheckboxItem().setChoiceValues()
実例
function editForm() {
const formId = "フォームID";
const form = FormApp.openById( formId );
const items = form.getItems();
const item = items[0];
let itemCheckBox = item.asCheckboxItem();
itemCheckBox.setChoiceValues(["自分","配偶者", "子供"]);
}
as~メソッドの一覧
itemの型を指定して取得するas~メソッドには以下があります。
メソッド | 戻り値のタイプ(型) | 内容 |
---|---|---|
asCheckboxGridItem() | CheckboxGridItem | アイテムをチェックボックスのグリッド アイテムとして返します。 |
asCheckboxItem() | CheckboxItem | アイテムをチェックボックス アイテムとして返します。 |
asDateItem() | DateItem | アイテムを日付アイテムとして返します。 |
asDateTimeItem() | DateTimeItem | アイテムを日時アイテムとして返します。 |
asDurationItem() | DurationItem | そのアイテムを期間アイテムとして返します。 |
asGridItem() | GridItem | アイテムをグリッド アイテムとして返します。 |
asImageItem() | ImageItem | そのアイテムを画像アイテムとして返します。 |
asListItem() | ListItem | アイテムをリストアイテムとして返します。 |
asMultipleChoiceItem() | MultipleChoiceItem | そのアイテムを多肢選択式アイテムとして返します。 |
asPageBreakItem() | PageBreakItem | アイテムを改ページ アイテムとして返します。 |
asParagraphTextItem() | ParagraphTextItem | アイテムを段落テキスト アイテムとして返します。 |
asScaleItem() | ScaleItem | アイテムをスケール アイテムとして返します。 |
asSectionHeaderItem() | SectionHeaderItem | アイテムをセクション ヘッダー アイテムとして返します。 |
asTextItem() | TextItem | アイテムをテキスト アイテムとして返します。 |
エラーが発生しやすい原因
以下は補足です。
このようなエラーが発生し、かつその原因に気づきにくい主な理由は以下の2つです。
setTitleメソッドが使える
対象のオブジェクト(アイテム)に対してsetTitleメソッドは使えてしまうというのが混乱を招く大きな要因の1つになっています。
「setChoiceValues」や「setChoiceValue」などの設問項目を操作するメソッドと比較して、setTitleメソッドはより汎用的に型の指定がなく使えるメソッドなのでこのような差が生まれるのですが、ここがわかりにくいポイントかなと思います。
function editForm() {
const formId = "フォームID";
const form = FormApp.openById( formId );
const itemsCheckBox = form.getItems(FormApp.ItemType.CHECKBOX);
const checkBox1 = itemsCheckBox[0];
checkBox1.setTitle( "参加者を選択してください" ); //正常に動く
checkBox1.setChoiceValues(["自分","配偶者", "子供"]); //エラー発生
}
ちなみにですが、setTitleメソッドは型を指定する前のアイテムに対しても、型を指定した後のアイテムに対してもどちらにも使うことができます。
const items = form.getItems();
const item = items[0];
item.setTitle( "参加者を選択してください" );
↑↓ どちらも同じ処理をします。
const items = form.getItems();
const item = items[0];
let itemCheckBox = item.asCheckboxItem();
itemCheckBox.setTitle( "参加者を選択してください" );
フォームに新たに項目を追加したときは「as~メソッド」による型の指定が必要ない
フォームに新たに項目を追加したときは「as~メソッド」による型の指定がありません。
このため、AppScript公式のサンプルコードでは、item.setChoiceValues()
のように、as~で型を指定していないアイテムに対してsetChoiceValuesなどの設問の内容を操作する処理を行っています。
// Opens the Forms file by its URL. If you created your script from within a
// Google Forms file, you can use FormApp.getActiveForm() instead.
// TODO(developer): Replace the URL with your own.
const form = FormApp.openByUrl('https://docs.google.com/forms/d/abc123456/edit');
// Adds a checkbox item.
const item = form.addCheckboxItem(); //← 型の指定までできてる
// Sets the title of the checkbox item to 'Do you prefer cats or dogs?'
item.setTitle('Do you prefer cats or dogs?');
// Sets the choices.
item.setChoiceValues(['Cats', 'Dogs']); //← ここ!
これは、add~というメソッドがアイテムの型も指定した状態のオブジェクトになっているためです。