【GAS】サイドバーのチェックボックス値をスプレッドシートに入力する方法

GAS

どうもcoto.です。

画像や商品、顧客など、たくさんのデータをカテゴリ分けしたりタグ付けしたりって作業ありませんか?今回は、スプレッドシートにサイドバー形式でタグマネージャーを作る方法をご紹介します。

やりたいこと

スプレッドシートで管理するデータは、csvなどにエクスポートして他のソフトにインポートするなど汎用性が高いですよね。

その場合、同じ属性やタグは完全一致の文字列で入れなければなりません。
つまり「犬」というタグをつける場合、「いぬ」でも「イヌ」でもなく「犬」にする必要があります。

しかし、人間ってこういう作業結構苦手で、日を跨いだりいろいろなことを同時進行でやっていたりするとブレが出てきますよね。複数人で作業するならなおさらです。
そこで機械的に ポチポチ選ぶ→決定→(あらかじめ入れてある文言で)登録 ができれば非常に都合が良いわけです。あっているか検証したり統一作業したりするのは時間かかりますしね。

というわけで、今回のコードでできることは↓こんなかんじ。

今回やりたいこと

①スプレッドシートに設置したボタンを押下
②サイドバーが開く
③サイドバーにある項目で該当するものにチェックを入れ、挿入ボタンを押す
④選択されているセルの同一行のC,D列に③でチェックを入れた値が挿入される

コード

サイドバーはHTML制御になるので、.gsの他にHTMLを作る必要があります。

GAS(gs)側のコード

今回の機能に必要なGAS側の関数は2つ。まず一つ目はサイドバーを表示させるためのものです。もともとスプレッドシートのGASにはサイドバーの機能があるのでこれを利用します。イメージとしては、スプレッドシート上に別のウインドウを作成し、別で作ったHTMLを表示するかんじ。

//サイドバーを表示
function Sidebar() {
  var htmlOutput = HtmlService.createTemplateFromFile('sidebar').evaluate().setTitle('タグマネージャ');  //スプレッドシートの右側にhtmlファイル「sidebar」を表示する
  SpreadsheetApp.getUi().showSidebar(htmlOutput);
}

HtmlService.createTemplateFromFile(‘sidebar‘)は別に作成するHTMLファイルの名前、
setTitle(‘タグマネージャ‘)はサイドバーのタイトルを指定しています。

サイドバーのタイトル

もう一つはサイドバーに設置した挿入ボタンの挙動を制御する関数です。

//カテゴリ挿入ボタン用
function insertcategory(text, text2){             
  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var row = ss.getActiveCell().getRow();     //カーソルのある行を取得
  ss.getRange('C'+ row).setValue(text);
  ss.getRange('D'+ row).setValue(text2);
}

カーソルのある行、つまり今A6セルを選択しているならC6とD6に選択値が挿入されます。
もちろんC,D列ではなく別の列に指定しても動きます。

HTML側のコード

実はHTML側のほうであらかた制御しています。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  
  <form name="sampleform">
    <div id="categ">
     <p>
         <input type="checkbox" name="category1" id="animals" value="animals"/><label for="animals">動物</label>
         <input type="checkbox" name="category1" id="plants" value="plants"/><label for="plants">植物</label><br>
     </p>
     <hr size="3" noshade>
  
     <p>
         <input type="checkbox" name="subcategory" id="哺乳類" value="哺乳類"/><label for="哺乳類">哺乳類</label><br>&nbsp;
         <input type="checkbox" name="subcategory" id="犬" value="犬"/><label for="犬">犬</label>
         <input type="checkbox" name="subcategory" id="猫" value="猫"/><label for="猫">猫</label><br>
         <input type="checkbox" name="subcategory" id="樹木" value="樹木"/><label for="樹木">樹木</label><br>&nbsp;
         <input type="checkbox" name="subcategory" id="カエデ" value="カエデ"/><label for="カエデ">カエデ</label>
         <input type="checkbox" name="subcategory" id="杉" value="杉"/><label for="杉">杉</label><br>
     </p>
     <hr size="3" noshade>

    </div>
  </form>
 
  <div id="button">
    <input type="button" value="挿入" onclick="categoryBtn()"/>&nbsp;&nbsp;

    <input type="button" value="クリア" onclick="allclear(false);">
  </div>
    
   
  <script>  
    
 //チェックボックスの値を挿入
   function categoryBtn(){
     //カテゴリー
	  const categoryar = []; //カテゴリーを入れる配列
	   const check = document.getElementsByName("category1");  //body内inputでnameをcategory1に指定したものを読み込む

	   for (let i = 0; i < check.length; i++){                //カテゴリーでチェックが付いた項目のvalueを取得して配列に加える
	  	 if(check[i].checked){      
			 categoryar.push(check[i].value);
		  }
	   }
       var cate = categoryar.join(', ');                    //配列を一続きの文字列にする

     //サブカテゴリー
	  const subar = []; //サブカテゴリーを入れる配列
	    const check2 = document.getElementsByName("subcategory"); //body内inputでnameをsubcategoryに指定したものを読み込む
      
	    for (let i = 0; i < check2.length; i++){ //サブカテゴリーでチェックが付いた項目のvalueを取得して配列に加える
		  if(check2[i].checked){      
			 subar.push(check2[i].value);
		  }
	    }
        var sub = subar.join(', ');                  //配列を一続きの文字列にする


    google.script.run.insertcategory(cate, sub);   //挿入関数に送る


}
      
 //チェックボックスをすべてクリア
   function allclear( tf ) {
     var ElementsCount = document.sampleform.elements.length; // チェックボックスの数
   for( i=0 ; i<ElementsCount ; i++ ) {
      document.sampleform.elements[i].checked = tf;       // ON・OFFを切り替え
     }
  }
    </script>    

    
  </body>
</html>

htmlなので説明不要かもしれませんが↓の1行で1つのチェックボックスを表示します。

 <input type="checkbox" name="category1" id="animals" value="animals"/><label for="animals">動物</label>

nameを同じにしたものを1つのグループとして扱うようにしています。つまり今回はcategory1とsubcategoryという2つのグループがあり、category1でチェックが入ったものをまとめてC列に挿入、subcategoryでチェックが入ったものをまとめてD列に挿入することになります。

また、挿入する値はvalueで指定した文字列です。

チェックをすべて外す「クリア」ボタンの挙動はfunction allclear( tf )で制御しています。必要なければもちろん削除して構いませんが、複数個のチェックボックスがある場合はあった方が絶対に便利だと思います。

ちなみにサイドバーは開いた時点のコードで動くので、修正したのに動かないなー、おかしいなーと思ったら開きなおしてくださいね。

お好みで変えると良い部分

サイドバーを開くタイミング

今回は「サイドバーを開く」ボタンを押すとサイドバーが開くようにしましたが、用途によってシートを開くと自動的に開くようにしてもよいですね。その場合はGASのトリガーを設定します。

挿入値のつなぎ方

複数項目にチェックを入れた場合「樹木, カエデ, 杉」のようになるのは、html中の

var cate = categoryar.join(', ');

で、カンマで並べるようにしているからです。

wordpressなどCSVでインポートするものはこのようにするとひとつなぎの文字列ではなく複数値としてカウントしてくれる場合が多いのでこのようにしていますが、もちろんお好みで変えてください。それぞれを【】で括ったり番号を振ったりできると思います。

すべてにチェックを入れるボタン

すべてのチェックを外す「クリア」ボタンではなくすべての項目にチェックを入れるボタンを設置したい場合は

    <input type="button" value="すべてチェック" onclick="allclear(true);">

のようにallclear(false)をallclear(true)に変えるとそのまま使えます。どちらも設置したい場合もそのままこの一行を任意の場所に入れればボタンができます。

複数行まとめて値挿入

試していないので実際のコードは提案できませんがうまいことやれば「5,7,11行目のCD列に同じ値を入れる」などもできると思います。

重複不可の項目にはラジオボタン

カテゴリーは1つしか選んではいけない、などにしたい場合ラジオボタンを使用すると効果的だと思います。複数人で作業する場合は特に禁則強めで作成するのがおすすめです。あとになって修正するのはほんと途方もないですから。

別ページでそのうちご紹介したいと考えていますが、テキストボックスなども組み合わせるとなお便利に。

項目の境界

今回はカテゴリーとサブカテゴリーの境には hr size=”3″ noshade で線を引いてますがお好みで見た目を装飾してください。

御託

私は主にストックフォトやECショップ商品のタグ付けに利用していますが、顧客の属性登録やコレクションのデータベース登録なんかにも十分役立つのではと思います。

他にも活用方法あったら教えてほしいなー。では。

コメント