メむンコンテンツぞスキップ
芋出し画像

【チェックボックス3】スプレッドシヌト䞊で実甚的な ラゞオボタン 【GAS】

    チェックボックスネタも最埌です。小ネタの぀もりが蚈3回になっおしたいたした。䞀応、今回が最埌になりたす。

    前回の蚘事



    Googleスプレッドシヌトで ラゞオボタン を䜜りたい

    これたでのチェックボックスシリヌズで、スプレッドシヌト䞊の リヌゞョンずいう考え方、そしお範囲に察しおの チェックボックス のチェック状態 刀定方法 が理解できたかず思いたす。

    これらの孊びを応甚しお、今回は Googleスプレッドシヌトには 暙準機胜ずしおは甚意されおいない 「実甚的な」ラゞオボタン颚 を チェックボックス ず GAS で䜜っおみたしょう。 



    それっおGoogleスプレッドシヌト䞊で必芁

    ラゞオボタンは Excelだず 機胜ずしお存圚したす。

    画像
    ActiveXコントロヌル ずか IE時代だな

    開発 > 挿入 > フォヌムコントロヌルもしくは ActiveXコントロヌルから オプションボタン を遞択すれば OK。

    名前は オプションボタン ずなっおいたすが、チェックボックスずは 別に甚意されおおり、ちゃんずにラゞオボタン の芋た目 〇 にポッチずいうボタンになっおたすね。

    でも、Excelで ラゞオボタンが必芁だったのは、か぀お

    オヌナヌ偎でアンケヌトを Excelで䜜成
    ↓
    そのExcelファむルを ナヌザヌに メヌル等 で配垃、
    もしくは NASなど共有ドラむブに眮いお コピヌしおもらう
    ↓
    ナヌザヌ偎で ポチポチず Excelファむル䞊で ラゞオボタンやチェックボックスで回答遞択、䞊曞き保存
    ↓
    これを再床 ファむルずしお回収、もしくは 印刷した玙を回収
    ↓
    オヌナヌ偎で集蚈䜜業 基本目芖、手䜜業

    こんなこずをやっおたからです。

    いたどき、こんなアナログなこずしおないですよね 

    画像
    時代は倉わったのよヌ

    いたなら チェックボックス や ラゞオボタンを䜿うような アンケヌト等は、Googleフォヌム や Microsoft Forms で行うべきです。

    回収や集蚈を考えれば、こっち䜿った方が 数倍䟿利。

    じゃあ、スプレッドシヌト䞊で わざわざ GASを䜿っお、 チェックボックスをラゞオボタン化 しおも 意味ないんじゃね

    はい。意味はありたせん

    「 スプレッドシヌトで䜜成した質問項目から Googleフォヌムを自動䜜成する【GAS】」みたいな蚘事の方が、よっぜど実甚性がありたす。

    これはもうね、自己満足ずいうか 自分の䞖界ずいうか、たずえるなら 空を駆けるひずすじの流れ星 です。

    GASによる スプレッドシヌト操䜜の緎習にはなるかず思いたすし、䞀郚の謎の勢力は スプレッドシヌトでアンケヌト䜜りたがるんですよね

    た、知っおるずなんかの圹には立぀かもしれたせん。


    「実甚的な」ラゞオボタン颚っおなんだ

    では、タむトルになぜ「実甚的な」ず付けたのか

    これは、GASによる チェックボックスの ラゞオボタン化 を玹介しおいるサむトの内容が、どれも 実甚的じゃないからです。申し蚳ないですが、ざっず調べお感じたこず

    そもそも、このネタを取り䞊げおるサむト自䜓が倚くないんですが、ほがどのサむトも

    1. ラゞオボタンの範囲をコヌド内で 盎接指定しおいる
     getRange("A5:A9") ずいった感じで
    2. チェックのON/OFF を setValue(s) の true,falseで制埡しおいる

    こんなやり方なんですよね。

    これだず以䞋のようなケヌス

    画像

    質問ラゞオボタン化したいグルヌプが耇数ある堎合は、チェックが入った行、列番号を取埗しおず 質問のセル䜍眮に合わせた 分岐凊理が必芁になっちゃいたす。

    しかも 䞊蚘のような堎合は、チェックボックスの 間に 遞択肢の文字列セルがあっお そのたた 範囲に察しお setValue(false) は䜿えたせん。

    1぀のシヌトに ポツンず 1箇所だけ ラゞオボタンのグルヌプがあるなんおケヌスはあたり無いですよね 限界集萜じゃないんだから。

    シヌト䞊にアンケヌトみたいな圢で ラゞオボタンを䜜るずしたら、䞊蚘のような 耇数質問があっお 耇数のラゞオボタングルヌプを䜜る必芁が出おくるず思いたす。これに察応できないず実甚的ずは蚀えたせん

    最初に曞いた通り、そもそも スプレッドシヌト䞊の ラゞオボタン化が実甚的じゃないんで、そこたで熱くならなくおもよいんですが

    ちなみにラゞオボタン颚 ずしたのは、芋た目を倉えるこずはできないからです。

    画像
    四角いチェックをたヌるく玍められない

    本来 画像のように

    チェックボックスは ☐ ず ☑
    ラゞオボタンは  〇 ず ⊿
    ※環境䟝存文字なんで 化けちゃうかも

    こんな感じでチェックボックス、ラゞオボタンは  ビゞュアル的なお玄束定矩がありたす。でも、さすがにチェックボックスの圢状を GASで倉えるこずは出来たせん。

    あくたでも、ラゞオボタン的な機胜遞択できるのは1぀の項目のみで、項目を遞択し盎すず他の項目は未遞択ずなるだけをGASで実珟しおいるので、「颚」ずしおいたす。ずはいえ、䜕床も登堎するずりザいから 以降は 「颚」は省略



    実甚的なラゞオボタン をどう実珟するか

    じゃあ、どのようにすれば 耇数質問チェックボックスグルヌプがあったり、チェックボックスの途䞭に文字列が入るケヌスでも察応できる「実甚的な」ラゞオボタンが䜜れるか

    前回たで孊んだこずを応甚すればOKです。前提条件はただ䞀぀

    「質問ごずに リヌゞョンになっおいる」

    これだけです。

    その前提の䞊で、

    ・チェックボックスが ONずなった時に、そのチェックボックスのセルが属するリヌゞョンを取埗する

    ・リヌゞョン内の 今チェックONずなったカレントセル以倖を、チェックボックス専甚メ゜ッド uncheck でチェックOFFにする

    こんな感じの流れで、リヌゞョン内の察象セルに察しお、チェックボックス以倖に圱響を䞎えない チェックボックス専甚メ゜ッドの uncheck を適甚ずすればよいわけです。



    0. 最もシンプルな ラゞオボタン コヌド

    実甚的なラゞオボタンを実珟する 䞀番簡単なコヌドはコレ ↓

    function onEdit(e){
      const range = e.range;
      if(!range.isChecked()) return; //線集セルが チェックON以倖なら終了
      range.getDataRegion().uncheck();
      range.check();
    }

    ちょヌシンプルですね。

    もちろん onEdit のシンプルトリガヌなんで ゚ディタで蚘述、保存するだけで  スクリプトの承認は必芁なし。 オヌナヌでもナヌザヌGoogleログむンは必芁でも 䜿えたす。

    前回たでに登堎したメ゜ッドばかりなので、特に解説も䞍芁でしょう。
    䞀点だけ !range.isChecked()  の郚分を説明するず、

    range.isChecked()  range線集されたセルのチェックボックス刀定
    ! (論理吊定 刀定結果を 反転

    線集されたセルが チェックボックス ON → true 反転で false
    線集されたセルがチェックボックス OFF → false反転で true
    線集されたセルがチェックボックス以倖 → null 反転で true

    !論理吊定は、ちょうど 土日曎新のシリヌズ 自䜜関数でも登堎したしたね。  null も falseず芋なされるので 反転するず trueになりたす。

    true なら return ずしお、その時点で終了ずなりたす。 反転埌が false の時぀たり セルがチェックONずなった時のみ、その埌のリヌゞョンに察する check,uncehck の凊理が動くわけです。

    画像
    うごかしおみよう
    画像
    こっちの配眮でも

    実際の動䜜です。

    うん、ちゃんずに質問リヌゞョン単䜍で ラゞオボタンずしお機胜はしおるけど・・・。

    なんか動きがカッコ悪い

    䞀床 オフになっおからチェックが戻るっおのが、なんか埮劙ヌ。

    実は 凊理の䞭で「リヌゞョン内の 今チェックONずなったカレントセル以倖」、この刀別・取埗がちょっず面倒なんですよね。

    ここを リヌゞョン党郚を䞀床チェックOFFにしお、今チェックを入れたカレントセル のみ チェックONに戻す。

    この流れにするず非垞に簡単なんで、たずは簡単な方のコヌドでやっおみたした。

    VBAなら Application.ScreenUpdating = False 入れお、時を止めたいずころですが、残念ながら GASには画面曎新を止めるメ゜ッドがありたせん。逆に匷制的に曎新させる方法はある

    このコヌドで十分っお人もいるでしょうが、もうちょい思考しお カレントセル以倖を適甚範囲ずするコヌドにしおみたしょう。


    チェックボックスを 実甚的なラゞオボタン にする 2぀の GAS

    チェックが䞀床倖れお再床぀くずいう埮劙な挙動を回避する為に、今チェックを入れた カレントセルを陀いお uncheckを実行する  2぀のアプロヌチを考えたした。

    1. リヌゞョン内のセルを1぀ず぀ 厳密なチェックボックス刀定

    2. リヌゞョンを カレントセル以倖の最倧4぀の 範囲に分割

    たずは 1からやっおみたしょう。



    1. リヌゞョンのセルを1぀ず぀ 厳密なチェックボックス刀定

    これは前回の GASによる 厳密なチェックボックス ON/OFF刀定の応甚です。

    ■刀定から 凊理たでの流れ
    1. 範囲リヌゞョンを取埗
    2. getDataValidations で デヌタ入力芏制を 二次元配列で取埗
    3. 二次元配列から 䞀぀ず぀ dataValidation を取り出すルヌプ凊理
    4. 入力芏制が蚭定されおいない堎合 dataValidationは  null ずなる。null 以倖が察象
    5. getCriteriaType で CHECKBOX 刀定。チェックボックスのみが察象
    6. チェックボックスである 単䜓セルを リヌゞョン内から取埗
    7. 単䜓セルに察しおの isCheckedが true か぀ カレントセル以倖か
    8. そのセルを uncheck しお終了

    ※ ラゞオボタンなので、既にチェックされおいるセルはあっおも  1぀ずいう想定

    コヌドにするずこんな感じ

    ラゞオボタン コヌド その1 (刀定方匏)

    //汎甚性のある ラゞオボタンコヌド3
    function onEdit(e){
      const range = e.range;
      if(!range.isChecked()) return;
    
      //線集されたセルの A1衚蚘のアドレスを取埗
      const add = range.getA1Notation();
    
      //1.範囲リヌゞョンを取埗
      const region = range.getDataRegion();
      //2.getDataValidations で デヌタ入力芏制を 二次元配列で取埗
      let dataValidations = region.getDataValidations();
    
    
      //3.二次元配列から 䞀぀ず぀ dataValidation を取り出すルヌプ凊理
      //瞊方向ルヌプ
      for(i=0; i<dataValidations.length; i++){
        //暪方向ルヌプ
        for(j=0; j<dataValidations[0].length; j++){
          const dataValidation = dataValidations[i][j];
    
          //4.入力芏制が蚭定されおいない堎合 dataValidationは  null ずなる。null 以倖が察象
          if(dataValidation != null){
            //5.getCriteriaType で CHECKBOX 刀定。チェックボックスのみが察象
            if(dataValidation.getCriteriaType() == SpreadsheetApp.DataValidationCriteria.CHECKBOX){
              //6.チェックボックスである 単䜓セルを リヌゞョン内から取埗
              const cell = region.getCell(i+1,j+1);
              //7.単䜓セルに察しおの isCheckedが true か぀ カレントセル以倖か
              if(cell.isChecked() === true && cell.getA1Notation() != add){
                //8.そのセルを uncheck しお終了
                cell.uncheck();
                return;
              }
            }
          }
        }
      }
    }

    長めですけど、前回のコヌドがそのたた䜿えたすね。
    これも 前回の蚘事を読んでいただければ解説は十分かず思いたす。

    凊理速床を䞊げる為に、カレントセル以倖の チェックONが 1぀芋぀かった時点で、そのセルに察しお uncheckしお終了ずしおいたす。

    ※ラゞオボタンずしお䜿っおいるので、チェックを付ける段階で 事前に範囲内にチェックONのセルが2぀以䞊あるこずは無いずいう想定です。

    画像

    ややモッタリした動きではありたすが、ちゃんずに 今チェックを付けたセル以倖に uncheckが適甚されおたすね。 さすがに倧量デヌタのラゞオボタンっおケヌスはないので この皋床の凊理速床なら蚱容範囲かず思いたす。

    セルを1぀ず぀刀定する方法でのラゞオボタン化は実珟できたした。



    2. リヌゞョンを カレントセル以倖の最倧4぀の 範囲に分割

    2぀目は 1぀ず぀セルのチェックボックス刀定をするのではなく、最初から リヌゞョンをカレントセル以倖の区画に分割しお、その区画に察しお uncheck をいおしたう方法です。


    リヌゞョンを分割っおどうやるの

    画像

    リヌゞョンを分割ずいうのは、こんな感じです。範囲は四角である必芁があるので 1セルを陀いた残りは 最倧4぀に分割されたす。

    この1぀の塊ではない 耇数の範囲Windowsだず Ctrlキヌ抌しながら遞択できるは GAS䞊では RangeList ずいう扱いになりたす。

    前回も少し觊れたしたが、リファレンスに蚘茉がある通り RangeListに察しおも check, uncheck メ゜ッドは䜿えたす。これでいけそうですね

    RangeListは sheetクラスのメ゜ッドで 通垞は A1衚蚘の配列で指定したすが、今回のようなケヌスは行、列の番号がそのたた䜿える R1C1衚蚘 で指定した方が簡単でしょう。

    画像
    R1CでもOK

    必芁ずなる 行、列の番号は 以䞋のように e.range  および region からget系メ゜ッドで 取埗できたす。

    ぀たり このような4぀に分割した範囲 の䜍眮情報行・列は、

    画像

    ↓ こんな感じに取埗できるわけです。

    画像

    たずえば 䞊の画像だず リヌゞョン内で チェックされた カレントセルを陀いた 「① 範囲 䞊」は、

    r3c2:r5c8
    ぀たり `r${startRow}c${startCol}:r${row-1}c${lastCol}`

    このように衚せたす。

    最倧4぀の範囲の r1c1衚蚘を生成しお、配列にプッシュしおいけば、ラゞオボタンずしお チェックを倖す uncheckの察象ずなる RangeList が生成できそうですね

    ただし、カレントセルのリヌゞョン内の 䜍眮 によっおは 䞊郚が無いずか巊郚がないずいったケヌスがあるので、そこを ifで 捌く必芁がありたす。



    䜙談テンプレヌトリテラルを䜿っおみよう

    ちなみに 文字列内に倉数を入れ蟌むのに 䜿っおいるのが、バッククォヌトを䜿った テンプレヌトリテラル ずいう蚘述法です。

     `r${startRow}c${startCol}:r${row-1}c${lastCol}`
    ` ← これがバッククォヌト

    バッククォヌトは  Shift + @マヌクのあるキヌ で打おたす。

    バッククォヌト内は、普通の改行や シングルクォヌト、ダブルクォヌトもそのたた 䜿えお、さらに  ${倉数や匏} ずいった圢で 倉数 や 関数、数匏なんかも + で連結せず 文字列内に 入れ蟌めちゃいたす。 

    トラファルガヌ・ロヌ の「ルヌム」内で「シャンブルズ」䜿えるみたいな、たさに チヌト領域ですね。

    もちろん

    "r" + startRow + "c" + startCol + ":r" + (row-1) + "c" + lastCol 

    でも同じ結果が埗られたすが、Googleスプレッドシヌト でGASを䜿っおいるず、このバッククォヌトを䜿った テンプレヌトリテラルでの蚘述が必芁になる時がありたす。

    䟋えば Query関数を GASで 生成しお setValue(たたは setFormula)しようずするず、匏内に ダブルクォヌトもシングルクォヌトもあったりしお、じゃあ党䜓をどう括るんじゃぃっおなりたす。 こんな時は バッククォヌトの出番ですね。

    あずは、なんずなく + で繋げるより 玄人っぜいかっこいいっおのもあるかなず  芚えおおいお損はないです


    ラゞオボタン コヌド その2 (分割方匏)

    分割凊理をしたうえで uncheckする流れをコヌドにするずこんな感じ。

    function onEdit(e){
      const range = e.range;
      if(range.isChecked() != true ) return;
    
      const sheet = range.getSheet();
    
      //チェックを入れたセルの行、列
      const row = range.rowStart;
      const col = range.columnStart;
    
      //チェックを入れたセルの リヌゞョン の開始セルの行、列、終了セルの行、列を取埗
      const region =range.getDataRegion(); 
      const startRow = region.getRow();
      const startCol = region.getColumn();
      const lastRow = region.getLastRow();
      const lastCol = region.getLastColumn();
    
      //察象を栌玍する タヌゲット配列
      const target =[]; 
    
      //範囲1 侊
      if(row > startRow){
        target.push(`r${startRow}c${startCol}:r${row-1}c${lastCol}`);
      }
    
      //範囲2 例
      if(row < lastRow){
        target.push(`r${row+1}c${startCol}:r${lastRow}c${lastCol}`);
      }
    
      //範囲3 å·Š
      if(col > startCol){
        target.push(`r${row}c${startCol}:r${row}c${col-1}`);
      }
      
      //範囲4 右
      if(col < lastCol){
        target.push(`r${row}c${col+1}:r${row}c${lastCol}`);
      }
    
      //レンゞリストのチェックを倖す
      sheet.getRangeList(target).uncheck();
    }

    圓然ですが、動きずいうかシヌト䞊の挙動は その1の刀定型方匏ず倉わらないです。モッタリ感も同じくらいですね

    画像

    これは RangeList に察する uncheck の動きが、結局は 範囲に察しお順番に実行されおいるからです。䞊列で䞀気に凊理されおるわけではないんですね。

    ラゞオボタンではないですが、以䞋のようなケヌスで詊しおみるず動きがわかりたす。



    おたけ2぀方匏 それぞれの動きを比范しおみよう

    せっかくなんで、2぀の方匏の凊理を比べおみたしょう。

    刀定方匏の方のコヌドは、return の蚘述を削陀しお 1぀ uncheckしおも終わらず凊理が継続されるように倉曎しおいたす。

    画像
    その1 刀定方匏
    画像
    その2 分割方匏

    刀定方匏のほうは、䞀぀䞀぀凊理しおるのがわかりたすね。目芖できるレベルの動きは、

    「ピ、ピ、ピ、ピピピピ 、テテヌン、テテヌン」

    っお感じで、欜ちゃんの仮装倧賞 っぜいかも

    䞋の分割方匏も、䞊、䞋、巊、右の 順でブロックごずに凊理されおいるのが、なんずなくわかりたす。

    チェックボックスが倚い堎合は、分割方匏のほうがマシっおくらいでしょうか、もうちょい サクサクな動きだずよいんですが・・・。

    せっかくなんで 最初のシンプルな コヌドも詊しおみたしょう。

    画像
    0. シンプル匏

    うヌん、この 党郚倖しおカレントセルだけチェック入れなおす、最初のシンプルなコヌドが 結局䞀番早いかも

    もちろんラゞオボタンずしお䜿うなら、こんなに耇数のチェックボックスが既にチェックされた状態っおこずは無いでしょうが。

    ずくにチェックした箇所が䞀旊消えお埩掻しおもきにならない
    → 0.シンプル方匏で

    質問ごずの チェックボックスの数は倚くない
    → 1.刀定方匏で

    䞀぀の質問の䞭にチェックボックスが倚数ある
    → 2.分割方匏で

    こんな棲み分けでしょうか。あずは 䜿う人の お奜みで䜿える堎面があったら 掻甚ください

    っおたずめたけど、「実甚的」ず謳ったわりに、あんた実甚的じゃなかったんじゃねっお蚀われそう・・・。



    チェックボックス の䞀括 ON/OFF、今回の ラゞオボタン化を通じお、 GASの理解が深たれば幞いです。

    ずりあえずは、 䞀番最初に玹介した GASを䜿わない

    • Ctrl + A の リヌゞョン遞択

    • スペヌスキヌでの チェックボックス 䞀括ON/OFF

    この2぀はガチ䟿利なんで、これだけ芚えお掻甚するでもいいかも。

    次回、番倖線っおこずで チェックボックスの小ネタをもう少しだけ。GASが続いたんで、GASを䜿わないネタ を幟぀か玹介したいず思いたす。

    意倖ずGASなしでも色々出来るずいう驚きず発芋があるかも



    ■このシリヌズの次の蚘事


     
     

    mir

     
     
    元Excel職人・VBA䜿いから、Googleスプレッドシヌト職人・GAS䜿いにゞョブチェンゞ。謎解き感芚で お題課題を解決しおいくような蚘事を曞こうかなず。その他、AIやらGeminiやらGoogleWorkspaceネタ党般

    あなたぞのおすすめ