paiza レベルアップ問題集 「FINAL問題 正則表現のエントリーポイント」をPythonとGASで解いてみた

この記事を読むことで、Pythonの標準入力で文字列を取得する方法、GASでは二次元配列として文字列を取得する方法、Python・GASで文字列を連結して出力する方法が学べます。

このコーナーでは、学習コンテンツpaizaラーニングレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。

GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。

正則表現のエントリーポイント (paizaランク D 相当)

問題:
あなたはプログラミングの課題を解いています。
2 つの単語が改行区切りで入力されるので「;」区切りで出力してください。

この記事では、下記の入力例1の場合を例にして、標準入力で2つの単語を取得して「;」を用いて文字列の連結をして出力します。

入力例1
STEINS
GATE

出力例1
STEINS;GATE

ではまず、Pythonで解いてみます。

今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。

■ Pythonでの解き方 ■

下準備として、paiza.ioにこの様に入力します。
(入力例1をそのままioにコピーしただけ。)

手順として、

1:標準入力で最初の単語aを読み込む

2:標準入力で最初の単語bを読み込む


3:「;」も使って文字列連結して出力する

で、行います。

この手順で作成したプログラムを実行した出力結果です。

コードはこちらになります。

#標準入力で最初の文字と次の文字を読み込む
a=input()
b=input()

#「;」も使って文字を連結して出力する
print(a+';'+b)

■ GASでの解き方 ■

では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。

スプレッドシートの緑のセルに最初の文字「STEINS」を入力しました。
スプレッドシートの灰色のセルに次の文字「GATE」を入力しました。

上記のセル2つはarrayという二次元配列として一度に取得します。そうすることによって、SpreadSheetAppから階層を辿って現在のシートにアクセスするという手間を減らすことが出来ます。

黄色いセルには、二次元配列arrayから2つの文字列を取得し「;」で連結した文字列を出力します。

※スプレッドシートに表示する場合は、二次元配列としての配列に追加をして作成します※

手順はこのようになります。

1:スプレッドシートからアクティブシートにアクセスする

2:スプレッドシートの緑のセルに入力された「STEINS」と、灰色のセルに入力された「GATE」の部分を二次元配列arrayとして取得する


3:二次元配列arrayが無事取得出来たことをログで出力して確認する

4:二次元配列array[0][0]とarray[1][0]を「;」も用いて連結して定数strに代入する

5:文字列の連結が出来たことをstrをログ出力して確認する

6:スプレッドシートに二次元配列として取得する配列str2を宣言する

7:str2が二次元配列になるようにstrを追加する

8:str2をスプレッドシートに出力する前にログ出力して確認する

9:スプレッドシートの黄色い所に二次元配列str2を出力する

手順1: スプレッドシートからアクティブシートにアクセスする

const ss=SpreadsheetApp.getActiveSheet();

ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。

手順2:2つの文字列を二次元配列として取得

const array=ss.getRange(1,1,2).getValues();

セルA1から2行分1列分の二次元配列として取得しています。

手順3:取得した二次元配列をログ出力で確認する
2行1列の二次元配列として取得出来たことを確信しました。

console.log(array);

手順4:文字列を連結させる

const str=array[0][0]+”;”+array[1][0];

文字列は二次元配列で、最初の行の0番目のarray[0][0]と、次の行の0番目のarray[1][0]を「;」も使って文字列を連結させて定数strに代入しています。

手順5:文字列の連結をログ出力で確認する

console.log(str);

手順6:連結させた文字列を二次元配列として格納させる配列str2を宣言

let str2=[];

手順7:str2が二次元配列になる様に、strを追加する

str2.push([str]);

手順7:スプレッドシートに出力する前に確認する

console.log(str2);

手順8:スプレッドシートの黄色いセルに連結した文字列を出力する

ss.getRange(4,1).setValue(str2);

実行後のスプレッドシートです。

GASでの全コードはこちらになります。

function sg1() {

  //現在のスプレッドシートに階層を辿ってアクセスする
  const ss = SpreadsheetApp.getActiveSheet();

  //2つの文字列を二次元配列として取得
  const array = ss.getRange(1, 1, 2).getValues();

  //取得した二次元配列をログ出力で確認する
  console.log(array);

  //文字列を連結させる
  const str = array[0][0] + ";" + array[1][0];

  //文字列の連結をログ出力で確認する
  console.log(str);

  //連結させた文字列を二次元配列として格納させる配列str2を宣言
  let str2 = [];

  //str2が二次元配列になる様に、strを追加する
  str2.push([str]);

  //スプレッドシートに出力する前に確認する
  console.log(str2);

  //スプレッドシートの黄色いセルに連結した文字列を出力する
  ss.getRange(4, 1).setValue(str2);
}

宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。

お台場自由の女神とレインボーブリッジと、レインボーブリッジの右端から1cmの所の東京タワー

お台場の日帰り旅行日誌動画付き

■ 参考文献の紹介■

じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。

初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

プログラミングのアンケートにご協力頂ける方はこちらのフォームで勉強法など色々と教えて下さい。

paiza レベルアップ問題集 「FINAL問題 約数の列挙」をPythonとGASで解いてみた

この記事を読むことで、PythonとGASでforループとループの中で単純なIF文を使って、指定された整数の約数を全て列挙し出力することが出来るようになります。

このコーナーでは、学習コンテンツpaizaラーニングレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。

GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

プログラミングのアンケートにご協力頂ける方はこちらのフォームで勉強法など色々と教えて下さい。

paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。

約数の列挙 (paizaランク D 相当)

問題:
整数 N が与えられます。
N の約数を小さい方から順に改行区切りで出力してください。

この記事では、下記の入力例2の場合を例にして、標準入力でリストの要素数N=100を取得し、その約数を昇順に列挙して行きます。

入力例2
100

出力例2
1
2
4
5
10
20
25
50
100

ではまず、Pythonで解いてみます。
今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。

■ Pythonでの解き方 ■

下準備として、paiza.ioにこの様に入力します。
(入力例2をそのままioにコピーしただけ。)

手順として、

1:Nを標準入力で取り込む

2:ループでi=1からNまでの範囲でループ内でIF文を使って、N%i==0と割り切れた場合にiを出力する

で、行います。

コードはこちらになります。

#Nを標準入力で取り込む
N=int(input())

#ループでi=1からNまでの範囲でループ内でIF文を使って、N%i==0と割り切れた場合にiを出力する
for i in range(1,N+1):
    if N%i==0:
        print(i)

この問題の類題のトレースは、前回の記事で詳しく行なっておりますので、変数の動きを知りたい方は前回の記事をご覧下さい。

■ GASでの解き方 ■

では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。

スプレッドシートの緑のセルに約数を列挙する整数N:100を入力しました。
黄色いセルには配列の中にあるNの約数の個数を出力します。

※スプレッドシートに表示する場合は、二次元配列としてからの配列に追加をして作成します※

手順はこのようになります。

1:スプレッドシートからアクティブシートにアクセスする

2:スプレッドシートの緑のセルから整数N(この例の場合は100)を取得する

3:整数Nが取得出来たことをログで確認する

4:約数をスプレッドシートに二次元配列として格納する配列divisorを宣言する

5:ループ内でIF文を使ってN=100の約数を見つけたら配列divisorに追加する

6:ループを抜けて、スプレッドシートに出力する前に配列divisorをログで出力する

7:スプレッドシートの黄色い所にdivisorを出力する

手順1: スプレッドシートからアクティブシートにアクセスする

const ss=SpreadsheetApp.getActiveSheet();

ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。

手順2:スプレッドシートの緑のセルから整数N(この例の場合は100)を取得する

const N=ss.getRange(1,2).getValue();

手順3:整数Nが取得出来たことをログで確認する

console.log(N);

手順4:約数をスプレッドシートに二次元配列として格納する配列divisorを宣言する

let divisor=[];

手順5:ループ内でIF文を使ってN=100の約数を見つけたら配列divisorに追加する

ループ内での約数を見つけた時の動きは、前回の記事で詳しく行なっておりますので、変数の動きを知りたい方は前回の記事をご覧下さい。

ループの部分のコードです。

//ループ内でIF文を使ってN=100の約数を見つけたら配列divisorに追加する
  for (let i=1;i<=N;i++){
    if(N%i==0){
      divisor.push([i]);
    }
  }

手順6:ループを抜けて、スプレッドシートに出力する前に配列divisorをログで出力する

console.log(divisor);

手順7:スプレッドシートの黄色い所にdivisorを出力する

ss.getRange(3,2,divisor.length).setValues(divisor);

実行後のスプレッドシートです。

GASでの全コードはこちらになります。

function loop2no20(){

  //スプレッドシートからアクティブシートにアクセスする
  const ss=SpreadsheetApp.getActiveSheet();

  //スプレッドシートの緑のセルから整数N(この例の場合は100)を取得する
  const N=ss.getRange(1,2).getValue();

  //整数Nが取得出来たことをログで確認する
  console.log(N);

  //約数をスプレッドシートに二次元配列として格納する配列divisorを宣言する
  let divisor=[];

  //ループ内でIF文を使ってN=100の約数を見つけたら配列divisorに追加する
  for (let i=1;i<=N;i++){
    if(N%i==0){
      divisor.push([i]);
    }
  }

  //ループを抜けて、スプレッドシートに出力する前に配列divisorをログで出力する
  console.log(divisor);

  //スプレッドシートの黄色い所にdivisorを出力する
  ss.getRange(3,2,divisor.length).setValues(divisor);

}

宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。

東京ドームシティ、恋するイタリア

■ 参考文献の紹介■

じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。

初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

プログラミングのアンケートにご協力頂ける方はこちらのフォームで勉強法など色々と教えて下さい。

←前の問題へ          

paiza レベルアップ問題集 「STEP: 14 約数の個数」をPythonとGASで解いてみた

この記事を読むことで、PythonとGASでforループとループの中で単純なIF文を使ってリスト(配列)の中で約数の個数を求めることが出来るようになります。

このコーナーでは、学習コンテンツpaizaラーニングレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。

GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

プログラミングのアンケートにご協力頂ける方はこちらのフォームで勉強法など色々と教えて下さい。

paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。

約数の個数 (paizaランク D 相当)

問題:
整数 N が与えられます。
N の約数の個数を出力してください。
約数とは、N を割り切る整数のことを指します。

この記事では、下記の入力例2の場合を例にして、標準入力でリストの要素数N=100を取得し、その約数の個数を求めます。

入力例2
100

出力例2
9

ではまず、Pythonで解いてみます。

今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。

■ Pythonでの解き方 ■

下準備として、paiza.ioにこの様に入力します。
(入力例2をそのままioにコピーしただけ。)

手順として、

1:Nを標準入力で取り込む

2:約数の個数を格納する変数countを0で初期化する


3:ループでi=1からNまでの範囲で、N%i==0と割り切れた場合にcountをインクリメントする


4:countを出力する

で、行います。

では、ループのトレースのコードの出力結果を掲載します。

i=1の時

N=100をi=1で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=2の時

N=100をi=2で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=3の時

N=100をi=3で割っても割り切れないのでIF文を飛ばします。

i=4の時

N=100をi=4で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=5の時

N=100をi=5で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

以下省略して、割り切れる所を含む部分をトレースします。

i=10〜15の時

N=100をi=10で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=11〜15まで割れません。

i=20〜26の時

N=100をi=20で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=21〜24まで割れません。

N=100をi=25で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=26は割れません。

i=50〜56の時

N=100をi=50で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

I=51〜56まで割れません。

i=95〜100の時

N=100をi=95〜99まで割っても割れません。

N=100をi=100で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

約数の個数が9個になってループを抜けました。

ループを抜けた後、約数を出力しています。

ここまでのトレースのコードです。

#Nを標準入力で取り込む
N=int(input())

#約数の個数を格納する変数countを0で初期化する
count=0

#ループでi=1からNまでの範囲で、N%i==0と割り切れた場合にcountをインクリメントする
print('<<<ループに入ります。>>>')
for i in range(1,N+1):
    print('除算前のcount:「'+str(count)+'」')
    print('N='+str(N)+'を「i='+str(i)+'」で割ります。')
    if N%i==0:
        print('i='+str(i)+'で割り切れたので約数みっけ(=^x^=)')
        count+=1
        print('count:【'+str(count)+'】')
    print('------------------------------------')
print('<<<ループを抜けました。>>>')

#countを出力する
print(count) 

ループのrange(1,N+1)となっているのは、引数の最後のところがN+1未満、すなわちNまでの範囲が適用されるからです。

このままでは、出力結果である出力例2に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。

#Nを標準入力で取り込む
N=int(input())

#約数の個数を格納する変数countを0で初期化する
count=0

#ループでi=1からNまでの範囲で、N%i==0と割り切れた場合にcountをインクリメントする
#print('<<<ループに入ります。>>>')
for i in range(1,N+1):
    #print('除算前のcount:「'+str(count)+'」')
    #print('N='+str(N)+'を「i='+str(i)+'」で割ります。')
    if N%i==0:
        #print('i='+str(i)+'で割り切れたので約数みっけ(=^x^=)')
        count+=1
        #print('count:【'+str(count)+'】')
    #print('------------------------------------')
#print('<<<ループを抜けました。>>>')

#countを出力する
print(count)

スッキリするように、コメントアウトした部分を省いたコードです。

#Nを標準入力で取り込む
N=int(input())

#約数の個数を格納する変数countを0で初期化する
count=0

#ループでi=1からNまでの範囲で、N%i==0と割り切れた場合にcountをインクリメントする
for i in range(1,N+1):
    if N%i==0:
        count+=1
        
#countを出力する
print(count)

ioの出力結果です。

■ GASでの解き方 ■

では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。

スプレッドシートの緑のセルに約数の個数を求める整数N:100を入力しました。
黄色いセルには配列の中にあるNの約数の個数を出力します。

※スプレッドシートに表示する場合は、二次元配列としてからの配列に追加をして作成します※

手順はこのようになります。

1:スプレッドシートからアクティブシートにアクセスする

2:スプレッドシートの緑のセルから整数N(この例の場合は100)を取得する


3:整数Nが取得出来たことをログで確認する


4:約数の個数countを0で初期化する


5:ループ内でIF文を使ってN=100の約数を見つけたらcountをインクリメントする


6:ループを抜けてcountをログで出力する


7:二次元配列としてcountを出力する配列count2を宣言する


8:count2に二次元配列になるようにcountを追加する


9:スプレッドシートに出力する前にcount2をログで確認する


10:スプレッドシートの黄色い所にcount2を出力する

手順1: スプレッドシートからアクティブシートにアクセスする

const ss=SpreadsheetApp.getActiveSheet();

ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。

手順2:スプレッドシートの緑のセルから整数N(この例の場合は100)を取得する

const N=ss.getRange(1,2).getValue();

手順3:整数Nが取得出来たことをログで確認する

console.log(N);

手順4:約数の個数countを0で初期化する

let count=0;

手順5:ループ内でIF文を使ってN=100の約数を見つけたらcountをインクリメントする

i=1の時

N=100をi=1で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=2の時

N=100をi=2で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=3の時

N=100をi=3で割っても割り切れないのでIF文を飛ばします。

i=4の時

N=100をi=4で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=5の時

N=100をi=5で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

以下省略して、割り切れる所を含む部分をトレースします。

i=10〜15の時

N=100をi=10で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=20〜24の時

N=100をi=20で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=21〜24まで割れません。

i=25〜30の時

N=100をi=25で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=26〜30まで割れません。

i=48〜53の時

i=48,49まで割れません。

N=100をi=50で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

i=51〜53まで割れません。

i=96〜100の時

N=100をi=96〜99まで割っても割れません。

N=100をi=100で割ると割り切れるので約数が見つかりました。
countをインクリメントします。

約数の個数が9個になってループを抜けました。
ここまでのトレースのループ部分のコードです。

//ループ内でIF文を使ってN=100の約数を見つけたらcountをインクリメントする
  console.log('<<<ループに入ります。>>>');
  for(let i=1;i<=N;i++){
    console.log(`現在のcount:【${count}】`);
    console.log(`N=${N}を「i=${i}」で割る`);
    if(N%i==0){
      console.log(`約数みっけ(=^x^=) i:「${i}」はN:${N}の約数です。`);
      count++;
      console.log(`約数count:【${count}】個目です。`);
    }
    console.log('--------------------------------------------');
  }
  console.log('<<<ループを抜けました。>>>');

手順6:ループを抜けてcountを出力する

console.log(count);

手順7:二次元配列としてcountを出力する配列count2を宣言する

let count2=[];

手順8:count2に二次元配列になるようにcountを追加する

count2.push([count]);

手順9:スプレッドシートに出力する前にcount2をログで確認する

console.log(count2);

手順10:スプレッドシートの黄色い所にcount2を出力する

ss.getRange(3,2).setValue(count2);

実行後のスプレッドシートです。

GASでの全コードはこちらになります。

function loop2no19(){

  //スプレッドシートからアクティブシートにアクセスする
  const ss=SpreadsheetApp.getActiveSheet();

  //スプレッドシートの緑のセルから整数N(この例の場合は100)を取得する
  const N=ss.getRange(1,2).getValue();

  //整数Nが取得出来たことをログで確認する
  console.log(N);

  //約数の個数countを0で初期化する
  let count=0;

  //ループ内でIF文を使ってN=100の約数を見つけたらcountをインクリメントする
  console.log('<<<ループに入ります。>>>');
  for(let i=1;i<=N;i++){
    console.log(`現在のcount:【${count}】`);
    console.log(`N=${N}を「i=${i}」で割る`);
    if(N%i==0){
      console.log(`約数みっけ(=^x^=) i:「${i}」はN:${N}の約数です。`);
      count++;
      console.log(`約数count:【${count}】個目です。`);
    }
    console.log('--------------------------------------------');
  }
  console.log('<<<ループを抜けました。>>>');

  //ループを抜けてcountを出力する
  console.log(count);

  //二次元配列としてcountを出力する配列count2を宣言する
  let count2=[];

  //count2に二次元配列になるようにcountを追加する
  count2.push([count]);

  //スプレッドシートに出力する前にcount2をログで確認する
  console.log(count2);

  //スプレッドシートの黄色い所にcount2を出力する
  ss.getRange(3,2).setValue(count2);

}

宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。

大井競馬場メガイルミ

■ 参考文献の紹介■

じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。

初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

プログラミングのアンケートにご協力頂ける方はこちらのフォームで勉強法など色々と教えて下さい。

←前の問題へ          次の問題へ→

<ねこフォーム実践編2>プログラミング学習アンケート

この記事では、GAS(Google Apps script)を使って、プログラミング学習者向け(さっき始めたばかりの方から、何十年もやっているベテランの方まで)を対象としたアンケートを作成します。

プログラミングのアンケートにご協力頂ける方はこちらのフォームで勉強法など色々と教えて下さい。

お世話になっているサイトは、いつも隣にITのお仕事さんの

GASでGoogleフォームを一発で作成するツールを作る

です。

まず、下記のような3枚のスプレッドシートを用意します。

・シート「トップ画面」

ここには、ボタンを設置して、このボタンを押すとフォームが作れるようにします。

・シート「フォームのタイトルと説明の情報」

ここには、作成するフォームのタイトルと説明文を入れます。

・シート「項目データ」

ここには、アンケート回答者がラジオボタン、チェックボックス、リストアイテムから選択出来るようスプレッドシートに配置しています。

このデータを二次元配列として取得して、各列ごとに1次元配列に変換して、ラジオボタンなどから選択出来るようにしています。

まず、スプレッドシートのボタンを押すとフォームが作れる関数、「pushButton」を作ります。

function pushButton() {

  //スプレッドシートのトップから現在のスプレッドシートにアクセスする 
  const ss=SpreadsheetApp.getActiveSpreadsheet();
  

  //フォームのタイトルと説明を取得
  const array=ss.getSheetByName('フォームのタイトルと説明の情報').getDataRange().getValues();
  const formTitle=array[0][1];//タイトル
  const formDescription=array[1][1];//概要

  //フォームを指定のタイトルと説明の元、作成する
  const form=FormApp.create(formTitle);  
  form.setDescription(formDescription);
 }

シート「フォームのタイトルと説明の情報」を二次元配列arrayとして取得して、array[0][1]をタイトル、array[1][1]をフォームの説明文として取得しています。

では、いよいよスプレッドシートのシート「項目データ」からデータを取得して、フォームを作成して行きます。

まず、シート「項目データ」を二次元配列として取得するために、下記のコードを書きました。

//項目データからフォームに追加するアイテムの内容を取得
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift()

このコードでは、定数dataValuesにシートを二次元配列として取得したデータを格納して、先頭のタイトル行をshisft()で削除しています。

この二次元配列の各行をフォームのアイテムから選択出来るように一次元配列に変換して、更に空白行を取り除く関数generateArrayを作成しました。

引数に二次元配列のデータとその行を指定して関数generateArrayに送ります。

ここではmapで一次元配列に変換して、filterで空白行を取り除いています。

/**
 * シート「項目データ」全体の値を取得した二次元配列から、指定の列のデータを抜き出し一次元配列を構成する 
 * 
 * @param{Object[][]}シートのデータを二次元配列化とした配列
 * @param{number}配列の列数(0以上のインデックス)
 * @return{Object{}}指定の列(見出しを除く)のデータによる一次元配列
 */
function generateArray(values,column){
  return values.map(record=>record[column]).filter(value=>value);
}

関数呼び出し時には、下記のように指定しました。

A列「性別」は、ラジオボタン(※必須)で、

generateArray(dataValues,0)

と記述し、引数に二次元配列のデータと列数を指定することで「性別」が選択出来ます。

form.addMultipleChoiceItem()    //ラジオボタン
    .setTitle('性別')
    .setChoiceValues(generateArray(dataValues,0))
    .setRequired(true);

B列「年齢」の呼び出しは、リストアイテム(※必須)で、

generateArray(dataValues,1)

です。

form.addListItem()              //プルダウン
    .setTitle('ご年齢')
    .setChoiceValues(generateArray(dataValues,1))
    .setRequired(true);

C列「出身在住都道府県」はリストアイテム(※必須)で、

generateArray(dataValues,2)

です。タイトルを変えて2回呼び出すことで、お住まいの都道府県と出身地を入力できます。

form.addListItem()              //プルダウン
    .setTitle('お住まいの都道府県は?')
    .setChoiceValues(generateArray(dataValues,2))
    .setRequired(true);


  form.addListItem()              //プルダウン
    .setTitle('ご出身の都道府県は?')
    .setChoiceValues(generateArray(dataValues,2))
    .setRequired(true);

D列「プログラミング歴」はリストアイテム(※必須)で、

generateArray(dataValues,3)

です。

form.addListItem()              //プルダウン
    .setTitle('プログラミング歴')
    .setChoiceValues(generateArray(dataValues,3))
    .setRequired(true);

E列「学習済み言語・1番得意な言語」はチェックボックスとラジオボタン(※必須)で、タイトルを変えて2回呼び出しています。

generateArray(dataValues,4)

です。

これらもそれぞれ、「その他」を選択出来るようにしています。

form.addCheckboxItem()    //チェックボックス
    .setTitle('学習をしたことのある言語')
    .setChoiceValues(generateArray(dataValues,4))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

  form.addMultipleChoiceItem()    //ラジオボタン
    .setTitle('1番得意な言語')
    .setChoiceValues(generateArray(dataValues,4))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

F列「学習のきっかけ」はチェックボックス(※必須)です。

generateArray(dataValues,5)

form.addCheckboxItem()    //チェックボックス
    .setTitle('始めたきっかけ')
    .setChoiceValues(generateArray(dataValues,5))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

G列「学習コンテンツ」はチェックボックス(※必須)です。

generateArray(dataValues,6)

    form.addCheckboxItem()    //チェックボックス
    .setTitle('利用学習コンテンツ')
    .setChoiceValues(generateArray(dataValues,6))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

これ以降は、セミナーの内容が5段階評価で選択出来るようにスケールアイテムを使っています。(※必須)

//スケールアイテム
    form.addScaleItem().setTitle('あなたはどれぐらいプログラミングが好きですか?\n 1:あまり好きではない 〜 5:大好き').setRequired(true);

    form.addScaleItem().setTitle('あなたはどれぐらいプログラミングが得意ですか?\n 1:あまり得意ではない 〜 5:物凄く得意').setRequired(true);

最後は自由に記入できるコメント入力用パラグラフテキストアイテムです。

//長文パラグラフテキストアイテムコメント欄
    form.addParagraphTextItem().setTitle('あなたのおすすめ勉強法やプログラミングの情報を教えて下さい。');

ここまでで実行すると、このようなフォームが作れます。これは目のマークでプレビューを押した画面です。

マイドライブに保存する場合はここまででも良いのですが、指定のドライブに保存したい場合は、プロパティストアというものを使って、フォルダIDをFOLDER_IDという文字列に保存します。

フォルダIDはこちらになります。

このモザイク部分をこちらのコードでXXXが32桁の所に実際のFOLDER_IDに保存します。

//フォームを保存したいドライブのIDを指定して、1番最初に実行する。
function setScriptProperty(){
  PropertiesService.getScriptProperties().setProperty('FOLDER_ID','XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
}

その実行画面です。

この様に何も起こらないので不安になるかと思います。

そこで、FOLDER_IDに格納出来たのか確認するコードを書きました。

//プロパティストアにフォルダIDが格納されたことを確認する
function getScriptProperty(){
  const folderid=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');
  console.log(folderid);
}

実行結果です。

あとはメインのpushButton関数にこの4行のコードを追記します。

プロパティストアからFOLDER_IDを取り出して、フォームをそこに格納し、マイドライブに出来てしまったフォームの方は削除します。

//指定のフォルダに保存する。この4行をコメントアウトするとマイドライブ(ルートディレクトリ)に保存される
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//格納するフォルダIDを取り出す
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームをオブジェクトとして取得
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにFileオブジェクトを追加する
  DriveApp.getRootFolder().removeFile(formFile);//マイフォルダからFileオブジェクトを削除する

コメントにもある様、マイドライブ(ルードディレクトリ)に保存したい場合は、一旦コメントアウトをしておいても状況に寄っては宜しいかもしれません。

ここまでの説明で、もう少し詳しくプロパティストアについて知りたいという方は、

<ねこフォーム2>GASで作成したフォームを指定のフォルダに格納する

をご覧ください。

では、これまでのコードをまとめます。

/**
 * シート「項目データ」全体の値を取得した二次元配列から、指定の列のデータを抜き出し一次元配列を構成する 
 * 
 * @param{Object[][]}シートのデータを二次元配列化とした配列
 * @param{number}配列の列数(0以上のインデックス)
 * @return{Object{}}指定の列(見出しを除く)のデータによる一次元配列
 */
function generateArray(values,column){
  return values.map(record=>record[column]).filter(value=>value);
}


function pushButton() {

  //スプレッドシートのトップから現在のスプレッドシートにアクセスする 
  const ss=SpreadsheetApp.getActiveSpreadsheet();
  

  //フォームのタイトルと説明を取得
  const array=ss.getSheetByName('フォームのタイトルと説明の情報').getDataRange().getValues();
  const formTitle=array[0][1];//タイトル
  const formDescription=array[1][1];//概要

  
  //フォームを指定のタイトルと説明の元、作成する
  const form=FormApp.create(formTitle);  
  form.setDescription(formDescription);
 

 //項目データからフォームに追加するアイテムの内容を取得
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift()

 
  form.addMultipleChoiceItem()    //ラジオボタン
    .setTitle('性別')
    .setChoiceValues(generateArray(dataValues,0))
    .setRequired(true);

  form.addListItem()              //プルダウン
    .setTitle('ご年齢')
    .setChoiceValues(generateArray(dataValues,1))
    .setRequired(true);

  form.addListItem()              //プルダウン
    .setTitle('お住まいの都道府県は?')
    .setChoiceValues(generateArray(dataValues,2))
    .setRequired(true);


  form.addListItem()              //プルダウン
    .setTitle('ご出身の都道府県は?')
    .setChoiceValues(generateArray(dataValues,2))
    .setRequired(true);

  
  form.addListItem()              //プルダウン
    .setTitle('プログラミング歴')
    .setChoiceValues(generateArray(dataValues,3))
    .setRequired(true);


  form.addCheckboxItem()    //チェックボックス
    .setTitle('学習をしたことのある言語')
    .setChoiceValues(generateArray(dataValues,4))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

  form.addMultipleChoiceItem()    //ラジオボタン
    .setTitle('1番得意な言語')
    .setChoiceValues(generateArray(dataValues,4))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);


    form.addCheckboxItem()    //チェックボックス
    .setTitle('始めたきっかけ')
    .setChoiceValues(generateArray(dataValues,5))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);



    form.addCheckboxItem()    //チェックボックス
    .setTitle('利用学習コンテンツ')
    .setChoiceValues(generateArray(dataValues,6))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

    //スケールアイテム
    form.addScaleItem().setTitle('あなたはどれぐらいプログラミングが好きですか?\n 1:あまり好きではない 〜 5:大好き').setRequired(true);

    form.addScaleItem().setTitle('あなたはどれぐらいプログラミングが得意ですか?\n 1:あまり得意ではない 〜 5:物凄く得意').setRequired(true);


    //長文パラグラフテキストアイテムコメント欄
    form.addParagraphTextItem().setTitle('あなたのおすすめ勉強法やプログラミングの情報を教えて下さい。');
  

  //指定のフォルダに保存する。この4行をコメントアウトするとマイドライブ(ルートディレクトリ)に保存される
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//格納するフォルダIDを取り出す
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームをオブジェクトとして取得
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにFileオブジェクトを追加する
  DriveApp.getRootFolder().removeFile(formFile);//マイフォルダからFileオブジェクトを削除する


}


//フォームを保存したいドライブのIDを指定して、1番最初に実行する。
function setScriptProperty(){
  PropertiesService.getScriptProperties().setProperty('FOLDER_ID','XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
}


//プロパティストアにフォルダIDが格納されたことを確認する
function getScriptProperty(){
  const folderid=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');
  console.log(folderid);
}

あとはスプレッドシートのトップ画面のボタンの右上3点リーダーからスクリプトを「pushButton」に割り当てて押すと、あなたが指定したフォルダ、またはマイドライブに保存されます。

お疲れ様でした、ブレイクタイムフォトはこちらになります。

東京都葛飾区にある新緑の水元公園。コロナ前2018年のゴールデンウィークにサイクリングに行きました。

■参考文献の紹介■
初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本を通してじっくり学べます。

サイトマップはこちらから

GASサンプル集に戻る
メインメニューに戻る
これからプログラミングを始める方へ
基本情報技術者へ
自己紹介

←ねこフォーム実践編1(セミナーアンケート)に戻る

ねこフォーム実践編3(就職氷河期世代&大人の発達障害読者アンケートに進む)→

paiza レベルアップ問題集 「STEP: 13 1 はどこにある?」をPythonとGASで解いてみた

この記事を読むことで、PythonとGASでforループとループの中で単純なIF文を使ってリスト(配列)の中で指定の数がある位置を求めることができるようになります。

このコーナーでは、学習コンテンツpaizaラーニングレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。

GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。

1 はどこにある? (paizaランク D 相当)

問題:
N 個の整数 a_1, a_2, …, a_N が与えられます。
a_1, a_2, …, a_N のうち、1 がある位置を先頭から順に改行区切りで出力してください。
a_1 を 1 番目とし、a_1, a_2, …, a_N には少なくとも 1 個は 1 が含まれます。

この記事では、下記の入力例2の場合を例にして、標準入力でリストの要素数N=5とリストを取得した後にリストarrayを取得し、その中に1が含まれている位置を出力します。リスト(配列)の先頭は0から始まります。下記の例では、リストの添字0と4が求まるので、それらに1を加えた1と5を出力するようにコードを書いて行きます。

入力例2
5
1 5 5 5 1

出力例2
1
5

ではまず、Pythonで解いてみます。

今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。

■ Pythonでの解き方 ■

下準備として、paiza.ioにこの様に入力します。
(入力例2をそのままioにコピーしただけ。)

手順として、

1:Nを標準入力で取り込む

2:リストarrayを標準入力で取り込む


3:ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する

で、行います。

リストの添字は0から始まる為、「i+1」と1を加えています。

では、ループのトレースを行います。

i=0の時

array[0]=1でリストの中身が1の条件に該当するので、i=0に1を加えた「1」を出力します。

i=1の時

array[1]=5で条件に該当しないのでIF文は飛ばします。

i=2の時

array[2]=5で条件に該当しないのでIF文は飛ばします。

i=3の時

array[3]=5で条件に該当しないのでIF文は飛ばします。

i=4の時

array[4]=1でリストの中身が1の条件に該当するので、i=4に1を加えた「5」を出力します。

ここまでのトレースのコードです。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する
print('<<<ループに入ります>>>')
for i in range(N):
    print('array['+str(i)+']の中身は「'+str(array[i])+'」です。')
    if array[i]==1:
        print('1見っけ!! i+1=【'+str(i+1)+'】を出力します')
        print(i+1)
    print('------------------')
print('<<<ループを抜けました。>>>')    

このままでは、出力結果である出力例2に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する
#print('<<<ループに入ります>>>')
for i in range(N):
    #print('array['+str(i)+']の中身は「'+str(array[i])+'」です。')
    if array[i]==1:
        #print('1見っけ!! i+1=【'+str(i+1)+'】を出力します')
        print(i+1)
    #print('------------------')
#print('<<<ループを抜けました。>>>')    

スッキリするように、コメントアウトした部分を省いたコードです。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#ループでリストarray[i]の中身を調べ、IF文でarray[i]==1の時に「i+1」を出力する
for i in range(N):
    if array[i]==1:
        print(i+1)

■ GASでの解き方 ■

では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。

スプレッドシートの緑のセルに配列の数の整数5を入力しました。
灰色のセルには配列を入力しました。
黄色いセルには配列の中にある「1」を見つけたらその場所がどこにあるのか出力します。配列の添字は0から始まるため、出力する値は「i+1」です。

※スプレッドシートに表示する場合は、二次元配列としてからの配列に追加をして作成します※

手順はこのようになります。

1:スプレッドシートからアクティブシートにアクセスする

2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する


3:スプレッドシートの灰色のセルから配列arrayを取得する


4:配列arrayが取得出来たことを確認するために出力する


5:配列arrayの中に1を見つけたらその位置「i+1」を格納する配列oneを宣言する


6:ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する


7:ループを抜けてスプレッドシートに出力前の二次元配列oneをログ出力して確認する


8:スプレッドシートの黄色い所に配列arrayの中に含まれている1の位置が格納された二次元配列oneを出力する

手順1: スプレッドシートからアクティブシートにアクセスする

const ss=SpreadsheetApp.getActiveSheet();

ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。

手順2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する

const N=ss.getRange(1,2).getValue();

手順3:スプレッドシートの灰色のセルから配列を取得する

const array=ss.getRange(2,2,1,N).getValues();

手順4:配列が取得出来たことを確認するために出力する

console.log(array);

手順5:配列arrayの中に1を見つけたらその位置「i+1」を格納する配列oneを宣言する

let one=[];

手順6:ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する。
スプレッドシートでは二次元配列として取得されるので、array[0][i]と書いています。
また、配列は添字が0から始まるので「i+1」をしています。

i=0の時

array[0][0]=1でリストの中身が1の条件に該当するので、i=0に1を加えた「1」を出力します。

i=1の時

array[0][1]=5で条件に該当しないのでIF文は飛ばします。

i=2の時

array[0][2]=5で条件に該当しないのでIF文は飛ばします。

i=3の時

array[0][3]=5で条件に該当しないのでIF文は飛ばします。

i=4の時

array[0][4]=1でリストの中身が1の条件に該当するので、i=4に1を加えた「5」を出力します。

ここまでを踏まえて、ループの部分のコードを掲載します。

//ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する
  console.log('<<<ループに入ります。>>>');
  for(let i=0;i<N;i++){
    console.log(`現在の配列one:[[${one}]]`);
    console.log(`i:${i}の時、配列では先頭から${i+1}番目でarray[0][${i}]=${array[0][i]}`);
    if(array[0][i]==1){
      console.log(`1見っけ(=^x^=)!! 配列oneに【${i+1}】を追加`);
      one.push([i+1]);
      console.log(one);
    }
    console.log('------------------------------------------------');
  }
  console.log('<<<ループを抜けました。>>>');

手順7:ループを抜けてスプレッドシートに出力前の二次元配列oneをログ出力して確認する

console.log(one);

手順8:スプレッドシートの黄色い所に配列arrayの中に含まれている1の位置が格納された二次元配列oneを出力する

ss.getRange(4,2,one.length).setValues(one);

実行後のスプレッドシートです。

GASでの全コードはこちらになります。

function loop2no18(){

  //スプレッドシートからアクティブシートにアクセスする
  const ss=SpreadsheetApp.getActiveSheet();

  //スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する
  const N=ss.getRange(1,2).getValue();

  //スプレッドシートの灰色のセルから配列arrayを取得する
  const array=ss.getRange(2,2,1,N).getValues();

  //配列arrayが取得出来たことを確認するために出力する
  console.log(array);

  //配列arrayの中に1を見つけたらその位置「i+1」を格納する配列oneを宣言する
  let one=[];

  //ループ内でarray[0][i]の値が「1」の場合は、その位置「i+1」がoneに二次元配列になるように追加する
  console.log('<<<ループに入ります。>>>');
  for(let i=0;i<N;i++){
    console.log(`現在の配列one:[[${one}]]`);
    console.log(`i:${i}の時、配列では先頭から${i+1}番目でarray[0][${i}]=${array[0][i]}`);
    if(array[0][i]==1){
      console.log(`1見っけ(=^x^=)!! 配列oneに【${i+1}】を追加`);
      one.push([i+1]);
      console.log(one);
    }
    console.log('------------------------------------------------');
  }
  console.log('<<<ループを抜けました。>>>');

  //ループを抜けてスプレッドシートに出力前の二次元配列oneをログ出力して確認する
  console.log(one);


  //スプレッドシートの黄色い所に配列arrayの中に含まれている1の位置が格納された二次元配列oneを出力する
  ss.getRange(4,2,one.length).setValues(one);

}

宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。

大井競馬場メガイルミの噴水

■ 参考文献の紹介■

じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。

初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

←前の問題へ          次の問題へ→

paiza レベルアップ問題集 「STEP: 12 加算された数列の最小値」をPythonとGASで解いてみた

この記事を読むことで、PythonとGASでforループを使って最小値を求められます。
Pythonでは計算結果を新たなリストに追加してmin関数でその最小値を求め、GASでは仮の最小値ans=201をループの中で更新して行って最小値を求めます。

このコーナーでは、学習コンテンツpaizaラーニングレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。

GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。

加算された数列の最小値 (paizaランク D 相当)

問題:
N 個の整数 a_1, a_2, …, a_N が与えられます。
a_i に i を足したとき、N 個の整数の最小値を出力してください。

この記事では、下記の入力例1の場合を例にして、標準入力でリストの要素数N=5とリストを取得して、リストの中の数字と添字の合計を別の配列に格納して、最大値を求めます。

入力例1
5
1 2 3 4 5

出力例1
2

ではまず、Pythonで解いてみます。

今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。

■ Pythonでの解き方 ■

下準備として、paiza.ioにこの様に入力します。
(入力例1をそのままioにコピーしただけ。)

手順として、

1:Nを標準入力で取り込む

2:リストarrayを標準入力で取り込む

3:リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する

4:ループを使ってリストarrayの数値と添字を合計して配列sumArrayに追加する

5:sumArrayの最小値をmin関数を使って求める

で、行います。

リストの添字は0から始まる為、「i+1」と1を加えています。

では、ループのトレースを行います。

i=0の時

array[0]=1とi+1=1を合計して計算結果「2」がsumArrayに追加された

i=1の時

array[1]=2とi+1=2を合計して計算結果「4」がsumArrayに追加された

i=2の時

array[2]=3とi+1=3を合計して計算結果「6」がsumArrayに追加された

i=3の時

array[3]=4とi+1=4を合計して計算結果「8」がsumArrayに追加された

i=4の時

array[4]=5とi+1=5を合計して計算結果「10」がsumArrayに追加された

リストsumArrayから求まった最小値です。

ここまでのトレースのコードです。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する
sumArray=[]

#ループを使ってリストarrayの数値と添字を合計して配列sumArrayに追加する
for i,num in enumerate(array):
    print('追加前のリストsumArray:'+str(sumArray))
    print('sumArrayに「'+str(num)+'」とi:'+str(i)+'+1=「'+str(i+1)+'」の【'+str(num+i+1)+'】を追加する')
    sumArray.append(num+i+1)
    print('追加後のリストsumArray:'+str(sumArray))
    print('-------------------------------------------')
    
#sumArrayの最小値をmin関数を使って求める
print(min(sumArray))

このままでは、出力結果である出力例1に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する
sumArray=[]

#ループを使ってリストarrayの数値と添字を合計して配列sumArrayに追加する
for i,num in enumerate(array):
    #print('追加前のリストsumArray:'+str(sumArray))
    #print('sumArrayに「'+str(num)+'」とi:'+str(i)+'+1=「'+str(i+1)+'」の【'+str(num+i+1)+'】を追加する')
    sumArray.append(num+i+1)
    #print('追加後のリストsumArray:'+str(sumArray))
    #print('-------------------------------------------')
    
#sumArrayの最小値をmin関数を使って求める
print(min(sumArray))

スッキリするように、コメントアウトした部分を省いたコードです。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する
sumArray=[]

#ループを使ってリストarrayの数値と添字を合計して配列sumArrayに追加する
for i,num in enumerate(array):
    sumArray.append(num+i+1)
    
#sumArrayの最小値をmin関数を使って求める
print(min(sumArray))

ioの出力結果です。

■ GASでの解き方 ■

では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。

スプレッドシートの緑のセルに配列の数の整数5を入力しました。
灰色のセルには配列を入力しました。
黄色いセルには配列の値とその添字に1を加えた値のうちの最小値を出力します。
(配列の添字は0から始まるため)

※スプレッドシートに表示する場合は、二次元配列としてからの配列に追加をして作成します※

手順はこのようになります。

1:スプレッドシートからアクティブシートにアクセスする

2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する


3:スプレッドシートの灰色のセルから配列を取得する


4:配列が取得出来たことを確認するために出力する


5:仮の最小値として変数ansを201で初期化する


6:ループ内で使う合計の計算結果を保存する変数tempを宣言する


7:ループ内で「i+1」とarray[0][i]を計算して変数tempに代入。
tempがansよりも小さかったらtempをansに代入する

8:ループを抜けてansに最小値が求まったことをログで確認する

9:ansを二次元配列として取得するans2を宣言して、ansを追加する

10:スプレッドシートに出力前にans2をログ出力して確認する

11:スプレッドシートの黄色い所に最小値の二次元配列ans2を出力する

手順1: スプレッドシートからアクティブシートにアクセスする

const ss=SpreadsheetApp.getActiveSheet();

ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。

手順2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する

const N=ss.getRange(1,2).getValue();

手順3:スプレッドシートの灰色のセルから配列を取得する

const array=ss.getRange(2,2,1,N).getValues();

手順4:配列が取得出来たことを確認するために出力する

console.log(array);

手順5:仮の最小値としてansを201で初期化する

let ans=201;

手順6:ループ内で使う合計の計算結果を保存する変数tempを宣言する

let temp;

手順7:ループ内で「i+1」とarray[0][i]を計算して変数tempに代入。
tempがansよりも小さかったらtempをansに代入して最小値を更新する

スプレッドシートでは二次元配列として取得されるので、array[0][i]と書いています。
また、配列は添字が0から始まるので「i+1」をしています。

i=0の時

array[0]=1とi+1=1を合計して計算結果:temp=2になった。
temp<ansなので、ansの値を更新した。

i=1の時

array[1]=2とi+1=2を合計して計算結果:temp=4になった。
temp>ansなので、ansの値は更新しない。

i=2の時

array[2]=3とi+1=3を合計して計算結果:temp=6になった。
temp>ansなので、ansの値は更新しない。

i=3の時

array[3]=4とI+1=4を合計して計算結果:temp=8になった。
temp>ansなので、ansの値は更新しない。

i=4の時

array[4]=5とi+1=5を合計して計算結果:temp=10になった。
temp>ansなので、ansの値は更新しない。

ここまでのループのトレースをしたコードはこちらです。

console.log('<<<ループに入る>>>');
  //ループ内で「i+1」とarray[0][i]を計算して変数tempに代入。
  //tempがansよりも小さかったらtempをansに代入する
  for (let i=0;i<N;i++){
    console.log(`現在の最小値ans:${ans}`);
    console.log(`i:${i}、i+1=「${i+1}」+array[0][${i}]:「${array[0][i]}」の計算結果をtempに格納`);
    temp=i+1+array[0][i];
    console.log(`temp:【${temp}】`);
    if(temp<ans){
      ans=temp;
      console.log(`ansを${temp}で更新しました。`);
    }
    console.log('--------------------------');
  }
  console.log('<<<ループを抜けた>>>');

手順8:ループを抜けてansに最小値が求まったことをログで確認する

console.log(ans);

手順9:ansを二次元配列として取得するans2を宣言して、ansを追加する

let ans2=[];
ans2.push([ans]);

手順10:スプレッドシートに出力前にans2をログ出力して確認する

console.log(ans2);

手順11:スプレッドシートの黄色い所に最大値の二次元配列ans2を出力する

ss.getRange(4,2).setValue(ans2);

実行後のスプレッドシートです。

GASでの全コードはこちらになります。

function loop2no17(){

  //スプレッドシートからアクティブシートにアクセスする
  const ss=SpreadsheetApp.getActiveSheet();

  //スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する
  const N=ss.getRange(1,2).getValue();

  //スプレッドシートの灰色のセルから配列を取得する
  const array=ss.getRange(2,2,1,N).getValues();

  //配列が取得出来たことを確認するために出力する
  console.log(array);

  //仮の最大値として変数ansを201で初期化する
  let ans=201;

  //ループ内で使う合計の計算結果を保存する変数tempを宣言する
  let temp;

  console.log('<<<ループに入る>>>');
  //ループ内で「i+1」とarray[0][i]を計算して変数tempに代入。
  //tempがansよりも小さかったらtempをansに代入する
  for (let i=0;i<N;i++){
    console.log(`現在の最小値ans:${ans}`);
    console.log(`i:${i}、i+1=「${i+1}」+array[0][${i}]:「${array[0][i]}」の計算結果をtempに格納`);
    temp=i+1+array[0][i];
    console.log(`temp:【${temp}】`);
    if(temp<ans){
      ans=temp;
      console.log(`ansを${temp}で更新しました。`);
    }
    console.log('--------------------------');
  }
  console.log('<<<ループを抜けた>>>');

  //ループを抜けてansに最小値が求まったことをログで確認する
  console.log(ans);

  //ansを二次元配列として取得するans2を宣言して、ansを追加する
  let ans2=[];
  ans2.push([ans]);

  //スプレッドシートに出力前にans2をログ出力して確認する
  console.log(ans2);

  //スプレッドシートの黄色い所に最小値の二次元配列ans2を出力する
  ss.getRange(4,2).setValue(ans2);
}

宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。

新緑の水元公園2018年ゴールデンウィーク撮影

■ 参考文献の紹介■

じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。

初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

←前の問題へ          次の問題へ→

<ねこフォーム8>ねこあつめフォームに「スケールアイテム」と「パラグラフテキストアイテム」を追加する

この記事では、GAS(Google Apps script)でねこあつめフォームに「スケールアイテム(5段階評価)」と「パラグラフテキストアイテム(コメント長文入力)」を追加します。

お世話になっているサイトは、いつも隣にITのお仕事さんの

GASでGoogleフォームに追加できる質問の種類とそのメソッドまとめ

です。

まずは、前回のおさらいをします。

「お名前」と「1番お気に入りのグッズ」と「めあど」はテキストアイテムをコードに記述して、「スプレッドシートから、ラジオボタン、チェックボックス、リストアイテムを取得する」コードを追加しました。

下記のコードを実行すると、このようなフォーム(目のマークのプレビュー画面)を得られます。

function myFunction() {

  //SpreadsheetAppから現在のスプレッドシートにアクセス
  const ss=SpreadsheetApp.getActiveSpreadsheet();

  //シート名「イベント概要」のデータを配列として取得する
  const values=ss.getSheetByName('イベント概要').getDataRange().getValues();
  const formTitle=values[0][1];//タイトル
  const formDescription=values[1][1];//概要
  
  //フォームを作成
  const form=FormApp.create(formTitle);


  //ここでプロパティストアに格納したFOLDER_IDを使って、指定のフォルダにフォームを作成する
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//idにFOLDER_IDを格納する
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームのIDをformFileに格納する
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにフォームを格納する
  DriveApp.getRootFolder().removeFile(formFile);//マイドライブに作成されたフォームを削除する


  //フォームの説明を作成
  form.setDescription(formDescription);

  //テキストアイテムを追加する
  form.addTextItem().setTitle('おなまえ').setRequired(true);//trueにすることで、入力必須にしている。
  form.addTextItem().setTitle('1番お気に入りのグッズ');


  //メールアドレスのテキストアイテムを加える
  const validationEmail=FormApp.createTextValidation().requireTextIsEmail().build();
  form.addTextItem().setTitle('めあど').setRequired(true).setValidation(validationEmail);


  //←シート「項目データ」から、フォームに追加するアイテムの内容を二次元配列として取得する
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift();

  /**
   * シート「項目データ」の値を二次元配列として取得して、指定の列を抜き出し一次元配列を構成する
   * 
   * @param{Object[][]}シート「項目データ」を二次元配列として取得したデータ
   * @param{number} 配列の列数(0以上のインデックス)
   * @return{Object[]} 指定の列の見出しタイトル行を除くデータによる一次元配列
   * 
   */
  function generateArray(values,column){
    return values.map(record=>record[column]).filter(value=>value);
  }
  
  
  //ラジオボタンを加える
  form.addMultipleChoiceItem()
    .setTitle('ねこ種類')
    .setChoiceValues(generateArray(dataValues,0))
    .setRequired(true);

  //チェックボックスを追加する
  form.addCheckboxItem()
    .setTitle('他にあそんだグッズ')
    .setChoiceValues(generateArray(dataValues,1)) 
    .showOtherOption(true)//その他のチェックボックスを作っている
    .setRequired(true); 

  //←リストアイテムを追加する
  form.addListItem()
    .setTitle('ねこちゃんの都道府県')
    .setChoiceValues(generateArray(dataValues,2)) 
    .setRequired(true); 

}

今回の内容に入る前に、ねこあつめ画像で癒されます。

まるこたつで「とびちゃん」がごめん寝してる(=^x^=)

さて、今回は5段階評価などで使う「スケールアイテム」と、長文のコメントを書ける様になる「パラグラフテキストアイテム」を追加します。

それぞれの部品をフォームに追加するコードはこちらになります。

・スケールアイテム のコード

//あなたの「ねこ度」をスケールアイテムで追加する
  form.addScaleItem().setTitle('あなたのねこ度は? 1:低い 〜 5:高い').setRequired(true);//trueにすることで、入力必須にしている。

・パラグラフテキストアイテムのコード

//ご意見ご要望をパラグラフテキストアイテムで追加する
  form.addParagraphTextItem().setTitle('ご意見ご要望').setRequired(true);//trueにすることで、入力必須にしている。

以上になります。
他にも日付を入れるアイテムとかありましたが、実際に良く使われるのは、スケールアイテムやパラグラフテキストアイテムだと思って、そこに絞って追加しました。

最後にこれまでのコードです。
指定のフォルダに保存したい場合は最初に「setScriptProperty」の32桁のXXX…XXXの所にフォルダIDを指定して実行してから、正しく格納されたことを
「getScriptProperty」で確認してからメインの「myFunction」を実行して下さい。

function myFunction() {

  //SpreadsheetAppから現在のスプレッドシートにアクセス
  const ss=SpreadsheetApp.getActiveSpreadsheet();

  //シート名「イベント概要」のデータを配列として取得する
  const values=ss.getSheetByName('イベント概要').getDataRange().getValues();
  const formTitle=values[0][1];//タイトル
  const formDescription=values[1][1];//概要
  
  //フォームを作成
  const form=FormApp.create(formTitle);


  //ここでプロパティストアに格納したFOLDER_IDを使って、指定のフォルダにフォームを作成する
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//idにFOLDER_IDを格納する
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームのIDをformFileに格納する
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにフォームを格納する
  DriveApp.getRootFolder().removeFile(formFile);//マイドライブに作成されたフォームを削除する


  //フォームの説明を作成
  form.setDescription(formDescription);

  //テキストアイテムを追加する
  form.addTextItem().setTitle('おなまえ').setRequired(true);//trueにすることで、入力必須にしている。
  form.addTextItem().setTitle('1番お気に入りのグッズ');


  //メールアドレスのテキストアイテムを加える
  const validationEmail=FormApp.createTextValidation().requireTextIsEmail().build();
  form.addTextItem().setTitle('めあど').setRequired(true).setValidation(validationEmail);


  //←シート「項目データ」から、フォームに追加するアイテムの内容を二次元配列として取得する
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift();

  /**
   * シート「項目データ」の値を二次元配列として取得して、指定の列を抜き出し一次元配列を構成する
   * 
   * @param{Object[][]}シート「項目データ」を二次元配列として取得したデータ
   * @param{number} 配列の列数(0以上のインデックス)
   * @return{Object[]} 指定の列の見出しタイトル行を除くデータによる一次元配列
   * 
   */
  function generateArray(values,column){
    return values.map(record=>record[column]).filter(value=>value);
  }
  
  
  //ラジオボタンを加える
  form.addMultipleChoiceItem()
    .setTitle('ねこ種類')
    .setChoiceValues(generateArray(dataValues,0))
    .setRequired(true);

  //チェックボックスを追加する
  form.addCheckboxItem()
    .setTitle('他にあそんだグッズ')
    .setChoiceValues(generateArray(dataValues,1)) 
    .showOtherOption(true)//その他のチェックボックスを作っている
    .setRequired(true); 

  //リストアイテムを追加する
  form.addListItem()
    .setTitle('ねこちゃんの都道府県')
    .setChoiceValues(generateArray(dataValues,2)) 
    .setRequired(true); 


  //←あなたの「ねこ度」をスケールアイテムで追加する
  form.addScaleItem().setTitle('あなたのねこ度は? 1:低い 〜 5:高い').setRequired(true);//trueにすることで、入力必須にしている。


  //←ご意見ご要望をパラグラフテキストアイテムで追加する
  form.addParagraphTextItem().setTitle('ご意見ご要望').setRequired(true);//trueにすることで、入力必須にしている。


}



//プロパティストアにフォルダIDを格納する
function setScriptProperty(){
  PropertiesService.getScriptProperties().setProperty('FOLDER_ID','XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
}

//プロパティストアにフォルダIDが格納されたことを確認する
function getScriptProperty(){
  const folderid=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');
  console.log(folderid);

}

ねこフォームの基礎はこの記事で最終回にして、次からはフォーム実践編に入リます。長らくご精読ありがとうございました。

■参考文献の紹介■
初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本を通してじっくり学べます。

サイトマップはこちらから

GASサンプル集に戻る
メインメニューに戻る
これからプログラミングを始める方へ
基本情報技術者へ
自己紹介

←前に戻るにゃん

paiza レベルアップ問題集 「STEP: 11 加算された数列の最大値」をPythonとGASで解いてみた

この記事を読むことで、PythonとGASでforループを使って最大値を求められます。
Pythonでは計算結果を新たなリストに追加してmax関数でその最大値を求め、GASでは仮の最大値ans=0をループの中で更新して行って最大値を求めて行きます。

このコーナーでは、学習コンテンツpaizaラーニングレベルアップ問題集をPythonとGASの両方で解いて全コードの解説をしています。
PythonとGASの両方のコードを用いて、全コード及び部分的にも可能な限り詳細に記載いたしました。

GASはスプレッドシートを使っています。
GASはGoogle Apps Scriptと言って、JavaScriptの文法をベースにしているので、JavaScriptの学習中の方にもお役立て出来るかも知れません。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

paizaでの解答はPythonで行いましたが、この記事ではPythonのコードと共に、同じ問題を現在学習中のGASだったらどう解くのか、スプレッドシートでバインドして作ってみました。

加算された数列の最大値 (paizaランク D 相当)

問題:
N 個の整数 a_1, a_2, …, a_N が与えられます。
a_i に i を足したとき、a_1 , … , a_N の最大値を出力してください。

この記事では、下記の入力例1の場合を例にして、標準入力でリストの要素数N=5とリストを取得して、リストの中の数字と添字の合計を別の配列に格納して、最大値を求めます。

入力例1
5
1 2 3 4 5

出力例1
10

ではまず、Pythonで解いてみます。

今回は、paiza.ioを使って解きます。paiza.ioの使い方はこちらから。

■ Pythonでの解き方 ■

下準備として、paiza.ioにこの様に入力します。
(入力例1をそのままioにコピーしただけ。)

手順として、

1:Nを標準入力で取り込む

2:リストarrayを標準入力で取り込む


3:リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する


4:ループを使ってリストarrayの数値と添字を合計して配列sumArrayに追加する


5:sumArrayの最大値をmax関数を使って求める

で、行います。

リストの添字は0から始まる為、「i+1」と1を加えています。

リストはこちらになります。

では、ループのトレースを行います。

i=0の時

array[0]=1とi+1=1を合計して計算結果2がsumArrayに追加された

i=1の時

array[1]=2とi+1=2を合計して計算結果4がsumArrayに追加された

i=2の時

array[2]=3とi+1=3を合計して計算結果6がsumArrayに追加された

i=3の時

array[3]=4とi+1=4を合計して計算結果8がsumArrayに追加された

i=4の時

array[4]=5とi+1=5を合計して計算結果10がsumArrayに追加された

ループを抜けた後に、max関数を使っって、sumArrayの最大値を出力した結果です。

ここまでのトレースのコードです。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する
sumArray=[]

print("リスト:"+str(array)+'\n')

#ループを使ってリストarrayの数値と添字を合計して配列sumArrayに追加する
print('<<<ループに入る>>>')
for i,num in enumerate(array):
    print("array["+str(i)+"]"+"である「"+str(num)+"」と、添字i+1="+str(i+1)+"を合計して配列の末尾に追加する")
    sumArray.append(num+i+1)
    print("現在の配列:"+str(sumArray))
    print('----------------------------------------------')
print('<<<ループを抜けた>>>')

#sumArrayの最大値をmax関数を使って求める
print(max(sumArray))

このままでは、出力結果である出力例1に対して冗長なコードが含まれているので、解答以外のprint文をコメントアウトします。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する
sumArray=[]

#print("リスト:"+str(array)+'\n')

#ループを使ってリストarrayの数値と添字を合計して配列sumArrayに追加する
#print('<<<ループに入る>>>')
for i,num in enumerate(array):
    #print("array["+str(i)+"]"+"である「"+str(num)+"」と、添字i+1="+str(i+1)+"を合計して配列の末尾に追加する")
    sumArray.append(num+i+1)
    #print("現在の配列:"+str(sumArray))
    #print('----------------------------------------------')
#print('<<<ループを抜けた>>>')

#sumArrayの最大値をmax関数を使って求める
print(max(sumArray))  

スッキリするように、コメントアウトした部分を省いたコードです。

#Nを標準入力で取り込む
N=int(input())

#リストarrayを標準入力で取り込む
array=list(map(int,input().rstrip().split(' ')))

#リストarray内の数字と添字を合計した数を格納する配列sumArrayを宣言する
sumArray=[]

for i,num in enumerate(array):
    sumArray.append(num+i+1)

#sumArrayの最大値をmax関数を使って求める
print(max(sumArray))

ioの出力結果です。

■ GASでの解き方 ■

では、同じ問題をGASで解いてみます。
まず、スプレッドシートにこの様に配置しました。

スプレッドシートの緑のセルに配列の数の整数5を入力しました。
灰色のセルには配列を入力しました。
黄色いセルには配列の値とその添字に1を加えた値のうちの最大値を出力します。
(配列の添字は0から始まるため)

※スプレッドシートに表示する場合は、二次元配列としてからの配列に追加をして作成します※

手順はこのようになります。

1:スプレッドシートからアクティブシートをアクセスする

2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する

3:スプレッドシートの灰色のセルから配列を取得する

4:配列が取得出来たことを確認するために出力する

5:仮の最大値として変数ansを0で初期化する

6:ループ内で使う合計の計算結果を保存する変数tempを宣言する

7:ループ内で「i+1」とarray[0][i]を計算してansよりも大きかったらtempをansに代入する

8:ループを抜けてansに最大値が求まったことをログで確認する

9:ansを二次元配列として取得するans2を宣言して、ansを追加する

10:スプレッドシートに出力前にans2をログ出力して確認する

11:スプレッドシートの黄色い所に最大値の二次元配列ans2を出力する

手順1: スプレッドシートからアクティブシートをアクセスする

const ss=SpreadsheetApp.getActiveSheet();

ここで定数ssにSpreadsheetAppから階層を辿ってアクティブシートにアクセスしています。

手順2:スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する

const N=ss.getRange(1,2).getValue();

手順3:スプレッドシートの灰色のセルから配列を取得する

const array=ss.getRange(2,2,1,N).getValues();

手順4:配列が取得出来たことを確認するために出力する

console.log(array);

手順5:仮の最小値としてansを0で初期化する

let ans=0;

手順6:ループ内で使う合計の計算結果を保存する変数tempを宣言する

let temp;

手順7:ループ内で「i+1」とarray[0][i]を計算してansよりも大きかったらtempをansに代入する

スプレッドシートでは二次元配列として取得されるので、array[0][i]と書いています。
また、配列は添字が0から始まるので「i+1」をしています。

i=0の時

array[0]=1とi+1=1を合計して計算結果:temp=2になった。
temp>ansなので、ansの値を更新した。

i=1の時

array[1]=2とi+1=2を合計して計算結果:temp=4になった。
temp>ansなので、ansの値を更新した。

i=2の時

array[2]=3とi+1=3を合計して計算結果:temp=6になった。
temp>ansなので、ansの値を更新した。

i=3の時

array[3]=4とi+1=4を合計して計算結果:temp=8になった。
temp>ansなので、ansの値を更新した。

i=4の時

array[4]=5とi+1=5を合計して計算結果:temp=10になった。
temp>ansなので、ansの値を更新した。

console.log('<<<ループに入る>>>');
  //ループ内で「i+1」とarray[0][i]を計算してansよりも大きかったらtempをansに代入する
  for(let i=0;i<N;i++){
    console.log(`i:「${i+1}」+array[0][${i}]:「${array[0][i]}」を計算する`);
    temp=(i+1)+array[0][i];
    console.log(`tempの計算結果${temp}`);
    if(temp>ans){
      ans=temp;
      console.log(`現在の最大値は${ans}です。`);
    }
    console.log('------------------');
  }
  console.log('<<<ループを抜けた>>>');

手順8:ループを抜けてansに最大値が求まったことをログで確認する

console.log(ans);

手順9:ansを二次元配列として取得するans2を宣言して、ansを追加する

let ans2=[];
ans2.push([ans]);

手順10:スプレッドシートに出力前にans2をログ出力して確認する

console.log(ans2);

手順11:スプレッドシートの黄色い所に最大値の二次元配列ans2を出力する

ss.getRange(4,2).setValue(ans2);

実行後のスプレッドシートです。

GASでの全コードはこちらになります。

function loop2no16(){

  //スプレッドシートからアクティブシートにアクセスする
  const ss=SpreadsheetApp.getActiveSheet();

  //スプレッドシートの緑のセルから整数N(この例の場合は5)を取得する
  const N=ss.getRange(1,2).getValue();

  //スプレッドシートの灰色のセルから配列を取得する
  const array=ss.getRange(2,2,1,N).getValues();

  //配列が取得出来たことを確認するために出力する
  console.log(array);
  
  //仮の最小値としてansを0で初期化する
  let ans=0;

  //ループ内で使う合計の計算結果を保存する変数tempを宣言する
  let temp;


  console.log('<<<ループに入る>>>');
  //ループ内で「i+1」とarray[0][i]を計算してansよりも大きかったらtempをansに代入する
  for(let i=0;i<N;i++){
    console.log(`i:「${i+1}」+array[0][${i}]:「${array[0][i]}」を計算する`);
    temp=(i+1)+array[0][i];
    console.log(`tempの計算結果${temp}`);
    if(temp>ans){
      ans=temp;
      console.log(`現在の最大値は${ans}です。`);
    }
    console.log('------------------');
  }
  console.log('<<<ループを抜けた>>>');

  //ループを抜けてansに最大値が求まったことをログで確認する
  console.log(ans);

  //ansを二次元配列として取得するans2を宣言して、ansを追加する
  let ans2=[];
  ans2.push([ans]);

  //スプレッドシートに出力前にans2をログ出力して確認する
  console.log(ans2);

  //スプレッドシートの黄色い所に最大値の二次元配列ans2を出力する
  ss.getRange(4,2).setValue(ans2);

}

宜しかったらコピペしてアレンジして見て下さい。
お疲れ様でした、ブレイクタイムフォトはこちらになります。

谷根千のまねきねこ(=^x^=)

■ 参考文献の紹介■

じっくり丁寧にPythonを学びたい方向け。
まずはpaizaラーニングなどの学習コンテンツで学んで、基礎をマスターしたら、この本でじっくりと初級から中級レベルを目指せます。

初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本でじっくり学べます。

サイトマップはこちらから

paizaレベルアップ問題集でPythonとGASを解いて見たに戻る
メインメニューに戻る
Python自作サンプル
GASサンプル
基本情報技術者試験

←前に戻る         次に進む→

<ねこフォーム実践1>就職セミナーアンケート

この記事では、GAS(Google Apps script)を使って、おおよそのセミナーや、企業説明会で使える参加者向けのアンケートを作成します。

お世話になっているサイトは、いつも隣にITのお仕事さんの

GASでGoogleフォームを一発で作成するツールを作る

です。

まず、下記のような3枚のスプレッドシートを用意します。

・シート「トップ画面」

ここには、ボタンを設置して、後でこのボタンを押すとフォームが作れるようにします。

・シート「フォームのタイトルと説明の情報」

ここには、作成するフォームのタイトルと説明文を入れます。

シート「項目データ」

ここには、アンケート回答者がラジオボタン、チェックボックス、リストアイテムから選択出来るようスプレッドシートに配置しています。

このデータを二次元配列として取得して、各列ごとに1次元配列に変換して、ラジオボタンなどから選択出来るようにしています。

まず、スプレッドシートのボタンを押すとフォームが作れる関数、「pushButton」を作ります。

シート「フォームのタイトルと説明の情報」を二次元配列arrayとして取得して、array[0][1]をタイトル、array[1][1]をフォームの説明文として取得しています。

また、フォームに氏名とメールアドレスのテキストアイテムを追加します。

メールアドレスは@が含まれているなど、メールアドレスとして正しいかどうかを検証しています。

このメールアドレスとして検証するという部分については、

<ねこフォーム4>ねこあつめフォームに「メールアドレス」を追加する

で詳細に掲載致しました。

//このボタンを押すと、フォームが作成される。
function pushButton() {
  
  //シート「フォームのタイトルと説明の情報」からフォームのタイトルと説明を取得
  const ss=SpreadsheetApp.getActiveSpreadsheet();
  const array=ss.getSheetByName('フォームのタイトルと説明の情報').getDataRange().getValues();
  const formTitle=array[0][1];//タイトル
  const formDescription=array[1][1];//フォームの説明文

  
  //フォームを作成。タイトルにはシート「フォームのタイトルと説明の情報」のvalues[0][1]から取得される
  const form=FormApp.create(formTitle);

  //フォームの説明。フォームの説明文にはシート「フォームのタイトルと説明の情報」のvalues[1][1]から取得される
  form.setDescription(formDescription);


  //以下、フォームの設問の項目
  form.addTextItem().setTitle('氏名').setRequired(true); //氏名は入力必須項目にしている。

  const validationEmail=FormApp.createTextValidation().requireTextIsEmail().build();//eメールアドレスが正しいか検証
  form.addTextItem().setTitle('メールアドレス').setRequired(true).setValidation(validationEmail);
}

では、いよいよスプレッドシートのシート「項目データ」からデータを取得して、フォームを作成して行きます。

まず、シート「項目データ」を二次元配列として取得するために、下記のコードを書きました。

//以下、シート「項目データ」から取得している。
  //シート「項目データ」からフォームの質問の項目を二次元配列として取得し、その二次元配列のタイトル行を削除する
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift()

このコードでは、定数dataValuesにシートを二次元配列として取得したデータを格納して、先頭のタイトル行をshisft()で削除しています。

この二次元配列の各行をフォームのアイテムから選択出来るように一次元配列に変換して、更に空白行を取り除く関数generateArrayを作成しました。

引数に二次元配列のデータとその行を指定して関数generateArrayに送ります。

ここではmapで一次元配列に変換して、filterで空白行を取り除いています。

/**
 * フォームのアイテムの内容をスプレッドシートから取得する関数
 * シート「項目データ」の値を取得した二次元配列から、指定の列のデータを抜き出し一次元配列を構成する。その為、mapを使っている。
 * その際、列の空白データを削除するためにfilterも使っている。 
 * 
 * @param{Object[][]}シートのデータを二次元配列化とした配列
 * @param{number}配列の列数(0以上のインデックス)
 * @return{Object{}}指定の列(見出しを除く)のデータによる一次元配列
 */
function generateArray(values,column){
  return values.map(record=>record[column]).filter(value=>value);
}

関数呼び出し時には、下記のように指定しました。

A列「性別」は、ラジオボタンで、

generateArray(dataValues,0)

と記述し、引数に二次元配列のデータと列数を指定することで「性別」が選択出来ます。

form.addMultipleChoiceItem()    //ラジオボタンはシート「項目データ」の「0列目」から取得している。
    .setTitle('性別')
    .setChoiceValues(generateArray(dataValues,0))
    .setRequired(true);

テキストアイテムで学校名を入力します。

form.addTextItem().setTitle('在学、卒業の学校名').setRequired(true);//入力はテキストアイテム

B列「学部」の呼び出しは、ラジオボタンで、

generateArray(dataValues,1)

です。その他の学部も選択記載出来るようにしています。

form.addMultipleChoiceItem()    //ラジオボタンはシート「項目データー」の「1列目」から取得している
    .setTitle('学部')
    .setChoiceValues(generateArray(dataValues,1))
    .showOtherOption(true)//その他の選択肢

学科・コースはテキストアイテムで入力します。

form.addTextItem().setTitle('学科・コース');

C列「卒業・在学の区分」はラジオボタン(※必須)で、

generateArray(dataValues,2)

です。その他の項目も選択出来ます。

form.addMultipleChoiceItem()    //ラジオボタンはシート「項目データ」の「2列目」から取得している
    .setTitle('卒業・在学の区分')
    .setChoiceValues(generateArray(dataValues,2))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

D列「出身・在住の都道府県」はリストアイテム(※必須)で、

generateArray(dataValues,3)

です。

これはリストアイテムのタイトルを変えて2回呼び出しています。

1回目の呼び出しはお住まい、2回目は出身です。

form.addListItem()  //リストアイテムはシート「項目データ」の「3列目」から取得している  
    .setTitle('お住まいの都道府県は?')
    .setChoiceValues(generateArray(dataValues,3))
    .setRequired(true);


  form.addListItem()   //リストアイテムはシート「項目データ」の「3列目」から取得している
    .setTitle('ご出身の都道府県は?')
    .setChoiceValues(generateArray(dataValues,3))
    .setRequired(true);

E列「当社を知った媒体」はチェックボックス(※必須)で、

generateArray(dataValues,4)

です。

これもその他を選択出来るようにしています。

form.addCheckboxItem()    //チェックボックスはシート「項目データ」の「4列目」から取得している
    .setTitle('当社を知った媒体はどちらでしょうか。')
    .setChoiceValues(generateArray(dataValues,4))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);

これ以降は、セミナーの内容が5段階評価で選択出来るようにスケールアイテムを使っています。(※必須)

//以下、スケールアイテム
  
  form.addScaleItem()
    .setTitle('講師の声の聞き取りやすさ     1: 全く良くない  〜  5: 大変良い')
    .setBounds(1,5)
    .setRequired(true);


  form.addScaleItem()
    .setTitle('講師の説明の分かりやすさ     1: 全く分からない  〜  5: 大変分かりやすい')
    .setBounds(1,5)
    .setRequired(true);


  form.addScaleItem()
    .setTitle('スタッフの身だしなみ     1: 全く良くない  〜  5: 大変良い')
    .setBounds(1,5)
    .setRequired(true);

  form.addScaleItem()
    .setTitle('スタッフの対応    1: 全く良くない  〜  5: 大変良い')
    .setBounds(1,5)
    .setRequired(true);


    form.addScaleItem()
    .setTitle('当社志望度    1: 低い  〜  5: 高い')
    .setBounds(1,5)
    .setRequired(true);

最後は自由に記入できる段落入力アイテムです。

form.addParagraphTextItem().setTitle('ご意見ご要望');//段落テキストアイテム

ここまでで実行すると、このようなフォームが作れます。これは目のマークでプレビューを押した画面です。

マイドライブに保存する場合はここまででも良いのですが、指定のドライブに保存したい場合は、プロパティストアというものを使って、フォルダIDをFOLDER_IDという文字列に保存します。

フォルダIDはこちらになります。

このモザイク部分32桁をこちらのコードでFOLDER_IDに保存します。
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXを実際のフォルダーIDに置き換えて下さい。特定のフォルダに指定する場合は、pushButtonを押すよりも先にこちらを実行して下さい。

//フォームを保存したいドライブのIDを指定して、1番最初に実行する。
function setScriptProperty(){
  PropertiesService.getScriptProperties().setProperty('FOLDER_ID','XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
}

その実行画面です。

この様に何も起こらないので不安になるかと思います。

そこで、FOLDER_IDに格納出来たのか確認するコードを書きました。

//プロパティストアにフォルダIDが格納されたことを確認する
function getScriptProperty(){
  const folderid=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');
  console.log(folderid);

実行結果です。先ほどのフォルダーID32桁が無事に表示されましたので、モザイク処理を施しました。

あとはメインの関数にこの4行のコードを追記します。

プロパティストアからFOLDER_IDを取り出して、フォームをそこに格納し、マイドライブに出来てしまったフォームの方は削除します。

//ここの4行ををコメントアウトすることで、マイドライブに保存が出来る。
  //フォームを指定のドライブに保存する
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//格納するフォルダIDを取り出す
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームをオブジェクトとして取得
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにFileオブジェクトを追加する
  DriveApp.getRootFolder().removeFile(formFile);//マイフォルダからFileオブジェクトを削除する

コメントにもある様、マイドライブ(ルードディレクトリ)に保存したい場合は、一旦コメントアウトをしておいても状況に寄っては宜しいかもしれません。

ここまでの説明で、もう少し詳しくプロパティストアについて知りたいという方は、

<ねこフォーム2>GASで作成したフォームを指定のフォルダに格納する

をご覧ください。

では、これまでのコードをまとめます。

/**
 * フォームのアイテムの内容をスプレッドシートから取得する関数
 * シート「項目データ」の値を取得した二次元配列から、指定の列のデータを抜き出し一次元配列を構成する。その為、mapを使っている。
 * その際、列の空白データを削除するためにfilterも使っている。 
 * 
 * @param{Object[][]}シートのデータを二次元配列化とした配列
 * @param{number}配列の列数(0以上のインデックス)
 * @return{Object{}}指定の列(見出しを除く)のデータによる一次元配列
 */
function generateArray(values,column){
  return values.map(record=>record[column]).filter(value=>value);
}


//このボタンを押すと、フォームが作成される。
function pushButton() {
  
  //シート「フォームのタイトルと説明の情報」からフォームのタイトルと説明を取得
  const ss=SpreadsheetApp.getActiveSpreadsheet();
  const array=ss.getSheetByName('フォームのタイトルと説明の情報').getDataRange().getValues();
  const formTitle=array[0][1];//タイトル
  const formDescription=array[1][1];//フォームの説明文

  
  //フォームを作成。タイトルにはシート「フォームのタイトルと説明の情報」のvalues[0][1]から取得される
  const form=FormApp.create(formTitle);

  //フォームの説明。フォームの説明文にはシート「フォームのタイトルと説明の情報」のvalues[1][1]から取得される
  form.setDescription(formDescription);


  //以下、フォームの設問の項目
  form.addTextItem().setTitle('氏名').setRequired(true); //氏名は入力必須項目にしている。

  const validationEmail=FormApp.createTextValidation().requireTextIsEmail().build();//eメールアドレスが正しいか検証
  form.addTextItem().setTitle('メールアドレス').setRequired(true).setValidation(validationEmail);

  
  //以下、シート「項目データ」から取得している。
  //シート「項目データ」からフォームの質問の項目を二次元配列として取得し、その二次元配列のタイトル行を削除する
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift()
  

  form.addMultipleChoiceItem()    //ラジオボタンはシート「項目データ」の「0列目」から取得している。
    .setTitle('性別')
    .setChoiceValues(generateArray(dataValues,0))
    .setRequired(true);
  
  form.addTextItem().setTitle('在学、卒業の学校名').setRequired(true);//入力はテキストアイテム

  form.addMultipleChoiceItem()    //ラジオボタンはシート「項目データー」の「1列目」から取得している
    .setTitle('学部')
    .setChoiceValues(generateArray(dataValues,1))
    .showOtherOption(true)//その他の選択肢

  form.addTextItem().setTitle('学科・コース');


  form.addMultipleChoiceItem()    //ラジオボタンはシート「項目データ」の「2列目」から取得している
    .setTitle('卒業・在学の区分')
    .setChoiceValues(generateArray(dataValues,2))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);


  
  form.addListItem()  //リストアイテムはシート「項目データ」の「3列目」から取得している  
    .setTitle('お住まいの都道府県は?')
    .setChoiceValues(generateArray(dataValues,3))
    .setRequired(true);


  form.addListItem()   //リストアイテムはシート「項目データ」の「3列目」から取得している
    .setTitle('ご出身の都道府県は?')
    .setChoiceValues(generateArray(dataValues,3))
    .setRequired(true);


  form.addCheckboxItem()    //チェックボックスはシート「項目データ」の「4列目」から取得している
    .setTitle('当社を知った媒体はどちらでしょうか。')
    .setChoiceValues(generateArray(dataValues,4))
    .showOtherOption(true)//その他の選択肢
    .setRequired(true);


  //以下、スケールアイテム
  
  form.addScaleItem()
    .setTitle('講師の声の聞き取りやすさ     1: 全く良くない  〜  5: 大変良い')
    .setBounds(1,5)
    .setRequired(true);


  form.addScaleItem()
    .setTitle('講師の説明の分かりやすさ     1: 全く分からない  〜  5: 大変分かりやすい')
    .setBounds(1,5)
    .setRequired(true);


  form.addScaleItem()
    .setTitle('スタッフの身だしなみ     1: 全く良くない  〜  5: 大変良い')
    .setBounds(1,5)
    .setRequired(true);

  form.addScaleItem()
    .setTitle('スタッフの対応    1: 全く良くない  〜  5: 大変良い')
    .setBounds(1,5)
    .setRequired(true);


    form.addScaleItem()
    .setTitle('当社志望度    1: 低い  〜  5: 高い')
    .setBounds(1,5)
    .setRequired(true);



  form.addParagraphTextItem().setTitle('ご意見ご要望');//段落テキストアイテム
  

  
  //ここの4行ををコメントアウトすることで、マイドライブに保存が出来る。
  //フォームを指定のドライブに保存する
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//格納するフォルダIDを取り出す
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームをオブジェクトとして取得
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにFileオブジェクトを追加する
  DriveApp.getRootFolder().removeFile(formFile);//マイフォルダからFileオブジェクトを削除する
  

}


//フォームを保存したいドライブのIDを指定して、1番最初に実行する。
function setScriptProperty(){
  PropertiesService.getScriptProperties().setProperty('FOLDER_ID','XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
}

//プロパティストアにフォルダIDが格納されたことを確認する
function getScriptProperty(){
  const folderid=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');
  console.log(folderid);

}

あとはスプレッドシートのトップ画面のボタンの右上3点リーダーからスクリプトを「pushButton」に割り当てて押すと、あなたが指定したフォルダ、または上記4行をコメントアウトした場合はマイドライブに保存されます。

お疲れ様でした、ブレイクタイムフォトはこちらになります。

恵比寿ガーデンプレイス、フランスのクリスタルメーカー、バカラのシャンデリア。
カメラはOLYMPUSのミラーレス一眼。

この写真ムービーは、下記の記事でご覧になれます。

恵比寿ガーデンプレイス、バカラのシャンデリア

■参考文献の紹介■
初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本を通してじっくり学べます。

サイトマップはこちらから

GASサンプル集に戻る
メインメニューに戻る
これからプログラミングを始める方へ
基本情報技術者へ
自己紹介

ねこフォーム実践編2プログラミングアンケートに進む→

<ねこフォーム7>ねこあつめフォームに「プルダウンリスト」を追加する

この記事では、GAS(Google Apps script)でねこあつめフォームに「プルダウンリスト」を追加します。
また、ラジオボタンや、チェックボックスも、スプレッドシートからデータを取得してフォームに表示出来るように致します。

お世話になっているサイトは、いつも隣にITのお仕事さんの

GASでGoogleフォームにプルダウンリストの質問を追加する方法

Googleフォームの質問の選択肢をスプレッドシートのデータから生成するGAS関数の作り方

です。

まずは、前回のおさらいをします。
チェックボックスを追加するのに、下記のコードを追加しました。

//←チェックボックスを追加する
  form.addCheckboxItem()
    .setTitle('種類は何系?(チェックボックス)')
    .setChoiceValues(['みけ','とら']) 
    .showOtherOption(true)//その他のチェックボックスを作っている
    .setRequired(true); 

実行して、プレビュー画面です。

前回のコードのまとめです。

function myFunction() {

  //SpreadsheetAppから現在のスプレッドシートにアクセス
  const ss=SpreadsheetApp.getActiveSpreadsheet();

  //シート名「イベント概要」のデータを配列として取得する
  const values=ss.getSheetByName('イベント概要').getDataRange().getValues();
  const formTitle=values[0][1];//タイトル
  const formDescription=values[1][1];//概要
  
  //フォームを作成
  const form=FormApp.create(formTitle);

  //ここでプロパティストアに格納したFOLDER_IDを使って、指定のフォルダにフォームを作成する
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//idにFOLDER_IDを格納する
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームのIDをformFileに格納する
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにフォームを格納する
  DriveApp.getRootFolder().removeFile(formFile);//マイドライブに作成されたフォームを削除する

  //フォームの説明を作成
  form.setDescription(formDescription);

  //テキストアイテムを追加する
  form.addTextItem().setTitle('おなまえ').setRequired(true);//trueにすることで、入力必須にしている。
  form.addTextItem().setTitle('あそんだグッズ');

  //メールアドレスのテキストアイテムを加える
  const validationEmail=FormApp.createTextValidation().requireTextIsEmail().build();
  form.addTextItem().setTitle('めあど').setRequired(true).setValidation(validationEmail);

  //ラジオボタンを加える
  form.addMultipleChoiceItem()
    .setTitle('種類は何系?(ラジオボタン)')
    .setChoiceValues(['みけ','とら'])
    .setRequired(true);

  //←チェックボックスを追加する
  form.addCheckboxItem()
    .setTitle('種類は何系?(チェックボックス)')
    .setChoiceValues(['みけ','とら']) 
    .showOtherOption(true)//その他のチェックボックスを作っている
    .setRequired(true); 

}

今回の内容に入る前に、ねこあつめ画像に癒されます。
紙袋に入った、「赤毛ねこのアンちゃんのお尻」が可愛すぎて反則なぐらいです(=^x^=)

さて、今回はスプレッドシートからデータを取得して、フォームのアイテムに反映させて、リストアイテムも新たに作ります。

スプレッドシートは、この2枚を用意します。

フォームを作成するのに使う「イベント概要」は、今まで通りこのように配置しています。

また、フォームに追加するアイテムは、シート「項目データ」にこのように配置しています。

猫ちゃん達の出身地は47都道府県なので、それを全部コードにベタ打ちするのは大変です。なので、スプレッドシートから取得するように致します。
この都道府県リストは総務省統計局さんの「2-2 都道府県別人口と人口増減率」のExcelからコピーして頂きました。

今回作成するねこあつめフォームの、「なまえ」、「1番お気に入りのグッズ」、「めあど」はプログラムからテキストアイテムを作って、上記のスプレッドシートからは、

・A列(ラジオボタン)・・・ねこ種類「みけ、とら、その他」を選択
・B列(チェックボックス)・・・他にあそんだことのあるグッズ「まるこたつ、ゆたんぽ・・・」などのグッズをチェックします。
・C列(リストアイテム)・・・ねこちゃん達の出身地を「北海道・・・沖縄」まで、プルダウンリストで選択します。

また、スプレッドシートのデータを二次元配列として取得する為、下記のコードを加えます。最初の行はタイトルなので、shift()を使って取り除いています。

//シート「項目データ」から、フォームに追加するアイテムの内容を二次元配列として取得する
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift();

この二次元配列dataValuesと列数を渡すことで、その列のデータを一次元配列として取得する関数を作成しました

/**
   * シート「項目データ」の値を二次元配列として取得して、指定の列を抜き出し一次元配列を構成する
   * 
   * @param{Object[][]}シート「項目データ」を二次元配列として取得したデータ
   * @param{number} 配列の列数(0以上のインデックス)
   * @return{Object[]} 指定の列の見出しタイトル行を除くデータによる一次元配列
   * 
   */
  function generateArray(values,column){
    return values.map(record=>record[column]).filter(value=>value);
  }

関数の呼び出しは、A列の「ねこ種類」の場合は、

generateArray(dataValues,0)

と記述し、引数に二次元配列のデータと列数を指定することで「ねこ種類」が呼び出せます。

B列の「他にあそんだことのあるグッズ」の呼び出しは、

generateArray(dataValues,1)

で、

C列の「全国のねこちゃんたちの都道府県」は

generateArray(dataValues,2)

と記述して、関数を呼び出して二次元配列から一次元配列にします。

このgenerateArray関数は、「map」を使うことで、スプレッドシートのデータが二次元配列の状態で格納されているのを一次元配列にして、フォームで選択出来る形に変換しています。

また、filterを使うことで、列に含まれる空のデータを取り除くことが出来ます。
例えばA列でしたら、「みけ、とら、その他」の後は空白です。
そこでfilterを使って、データがある「みけ、とら」のみを取得してフォームで使うことが出来る様になります。

以上をまとめたコードはこちらです。

function myFunction() {

  //SpreadsheetAppから現在のスプレッドシートにアクセス
  const ss=SpreadsheetApp.getActiveSpreadsheet();

  //シート名「イベント概要」のデータを配列として取得する
  const values=ss.getSheetByName('イベント概要').getDataRange().getValues();
  const formTitle=values[0][1];//タイトル
  const formDescription=values[1][1];//概要
  
  //フォームを作成
  const form=FormApp.create(formTitle);


  //ここでプロパティストアに格納したFOLDER_IDを使って、指定のフォルダにフォームを作成する
  const id=PropertiesService.getScriptProperties().getProperty('FOLDER_ID');//idにFOLDER_IDを格納する
  const formFile=DriveApp.getFileById(form.getId());//作成したフォームのIDをformFileに格納する
  DriveApp.getFolderById(id).addFile(formFile);//指定のフォルダにフォームを格納する
  DriveApp.getRootFolder().removeFile(formFile);//マイドライブに作成されたフォームを削除する


  //フォームの説明を作成
  form.setDescription(formDescription);

  //テキストアイテムを追加する
  form.addTextItem().setTitle('おなまえ').setRequired(true);//trueにすることで、入力必須にしている。
  form.addTextItem().setTitle('1番お気に入りのグッズ');


  //メールアドレスのテキストアイテムを加える
  const validationEmail=FormApp.createTextValidation().requireTextIsEmail().build();
  form.addTextItem().setTitle('めあど').setRequired(true).setValidation(validationEmail);


  //←シート「項目データ」から、フォームに追加するアイテムの内容を二次元配列として取得する
  const dataValues=ss.getSheetByName('項目データ').getDataRange().getValues();
  dataValues.shift();

  /**
   * シート「項目データ」の値を二次元配列として取得して、指定の列を抜き出し一次元配列を構成する
   * 
   * @param{Object[][]}シート「項目データ」を二次元配列として取得したデータ
   * @param{number} 配列の列数(0以上のインデックス)
   * @return{Object[]} 指定の列の見出しタイトル行を除くデータによる一次元配列
   * 
   */
  function generateArray(values,column){
    return values.map(record=>record[column]).filter(value=>value);
  }
  
  
  //ラジオボタンを加える
  form.addMultipleChoiceItem()
    .setTitle('ねこ種類')
    .setChoiceValues(generateArray(dataValues,0))
    .setRequired(true);

  //チェックボックスを追加する
  form.addCheckboxItem()
    .setTitle('他にあそんだグッズ')
    .setChoiceValues(generateArray(dataValues,1)) 
    .showOtherOption(true)//その他のチェックボックスを作っている
    .setRequired(true); 

  //←リストアイテムを追加する
  form.addListItem()
    .setTitle('ねこちゃんの都道府県')
    .setChoiceValues(generateArray(dataValues,2)) 
    .setRequired(true); 

}

このコードを実行した結果です。

シート「イベント概要」からは、フォームのタイトルと説明を取得しました。

シート「項目データ」からは、これらのアイテムを取得しました。

■参考文献の紹介■
初めてGASを学ぶ方向け。
スプレッドシートの基本的な使い方からGASのベースとなるJavaScriptの基礎文法、GASでの初歩的なプログラミングを学べます。

GASに少し慣れて来たら、基礎固めとリファレンスとしてこの本を通してじっくり学べます。

サイトマップはこちらから

GASサンプル集に戻る
メインメニューに戻る
これからプログラミングを始める方へ
基本情報技術者へ
自己紹介

←前に戻るにゃん        次行くにゃん