02_意見集約アプリ

【02_意見集約アプリ】意見集約アプリ〔解説編 Vol.3〕ユーザー毎に編集可能な範囲を変えてテーブル形式のフォームを表示する

記事概要

前の記事では、POST送信されたパスワードを受け取るところまで説明しましたが、そこからパスワードに応じて編集可能範囲が変わるテーブルを表示させる方法を説明します。

今回の記事は「コード.gs」スクリプトの説明をします。コード.gsの中ではテンプレートからPOST送信することで、doPOST関数が発動しました。そこからの説明です。
画像3

編集できる範囲をユーザ毎に分ける事で「他人のデータのうっかり書き換え」を無くす

大勢で意見集約する場合、1)各自の意見を集約係が集めてまとめる。2)共通のファイルに各自書き込んでもらう。 という2つの方法が考えられます。 1)の方法は間違いはなさそうだけど集約係の負担が大きい。それで負担を減らすため、2)の方法は良く取られます。

でもこうした場合によくあるのが、「うっかり他人のデータを書き換えた」というトラブル。こうしたうっかりさんは必ずいます。それをなくすには、ユーザー毎に編集できる範囲を分けてしまうのが良いのですが、GASではこうした事が比較的簡単に実装できます。

たとえば、Aさんが編集するときには、Aさんだけが知っているパスワードを入れて送信すると・・・

画像1

Aさんの範囲だけ編集可能な形でフォームが表示されます!

画像2

Aさんは編集できるところだけを修正して「書込み」ボタンを押すと、原本であるスプレッドシートに自動的に反映される、という訳です。他の範囲が編集される事はありません。

テーブル形式のフォームを作るプログラムを少し修正するだけでこの様なことができます。この記事では、その修正部分をピックアップしてご説明します。

パスワードから、編集可能な列を判定~スプレッドシート関数との連携~

今回ご紹介するプログラムでは、フォームから記入された意見はスプレッドシートの「集約」シートに書きこまれます。

それとは別に、パスワードと編集可能列の対応を書いた「パスワード」シートを別に作っておきます。

A~C列は、パスワードに応じた書き込み列(必須情報)や、割り当てユーザ(参考情報)を記した表です。

E~G列はE2セルにパスワードを入れると、F2セルG2セルに書き込み列と対象者が関数で表示される様にしています。ちなみにF2セルには、

=IFERROR(vlookup(E2,A2:B5,2,false),”-“)

という関数を入れています。

ここでGASを使って、「左側のセルにパスワードを入れる」 ⇒ 「右側のセルに自動表示される編集可能値の列番号を取得」という作業を、以下の様なコードで行います。

//データ記録範囲を指定してパスワードから記載範囲を取得
パスワードのシート.getRange(2行目,5列目).setValue(パスワード);
var 書き込み列 = パスワードのシート.getRange(2行目,6列目).getValue();
パスワードのシート.getRange(2行目,5列目).clearContent();


プログラムは次の様な雰囲気です。

1行目E2セルにパスワードを記入、(setValue
2行目F2セルの値を取得、(getValue
3行目:用が済んだらE2セルを空にしておく(clearContent

 

GASでWEBアプリを作ることの利点は、この様にデータの処理はスプレッドシート側に任せ、スクリプト側はそこからデータを出し入れすることで、データの抽出などを行えることです。

データ処理の内容をスプレッドシートの形で作っておくと、だれでも管理が行えるという利点もあります。

また、データベースでの管理と異なり、セルには行の順序やセルの色などの概念がありますので、これを利用してデータを分かりやすくする事もできます。データベースでは困難である列の追加も自由にできます。

doPOST()関数の終わりでは、以下の様にHTMLオブジェクトに編集可能列番号を示す変数myInpRowを付与し、書き込み列の情報を引き渡した上で、テンプレートをevaluate関数でWEB表示させています。

//★★テンプレートに埋め込む変数値を指定する★★
・・・<中略>・・・
myHTML.myInpRow = 書き込み列;
・・・<中略>・・・
//HTMLファイルをホスティング
return myHTML.evaluate().addMetaTag(・・・スマホ対応のためのメタタグ・・・);

テンプレートで対象ユーザーの列だけを編集可能にしたテーブルを作る

ここからはテンプレート「INDEX.html」 の説明になります。
画像9

このプロジェクトでは、こちらで作成したコードをほぼそのまま利用しています。

1点、インラインコードでHTMLコードを書き出す際、<見出し>として編集不可とするif文の条件を追加修正し、必要な列以外を編集できない様にしています。

該当列 ≠ 編集する列 であればタグは<th(見出し)>

// ◆◆見出しとなる条件を変更◆◆
if (iRow == 0 || iCol != myInpRow-1) {
?><th><?=Cell ?></th><?
}


初期状態で変えたところは上記だけです。

 

書き込みの時も制約を同様に入れています。

まず、google.script.run関数の引数を追加して、スクリプト側でシートに書き込みを行う関数SetSheetに編集する列 myInpRow を渡しています。

 


//—◆◆◆引数を追加◆◆—-
google.script.run.withSuccessHandler(onSuccess).SetSheet(myCells, nRow, nCol, myInpRow);
}

再び コード.js の説明です
画像3

スクリプト側では、関数SetSheetを以下の様に修正します。


//★★★★HTMLから呼び出されて実行する関数★★★★//HTMLテーブルの値myCellsをシートに書き込む関数

//—◆◆◆引数を追加◆◆—-
function SetSheet(myCells, myRows, myCols, myInpRow){
//見出し部分は除外して書き込み
//◆◆書き込み範囲の条件を変更◆◆
if(!(iRow == 0 || iCol != myInpRow-1)){
mySheet.getRange(iRow + 1,iCol + 1,1,1).setValue(myCells[iRow][iCol]);
}
}

setValueをする条件として、

(該当列 ≠ 編集する列 )でないこと(頭の!:=編集列であること)を条件にしています。

以上で、一通りのコードの説明を終えます。具体的なコードは次の記事でご紹介します。