見出し画像

Googleスプレッドシート で使えるスピンボタン検証 -1

Excelにはあるけど Googleスプレッドシートには無い機能ってなーんだ?

ぶっちゃけ、いっぱいありすぎですよねw

テーブル機能とか シートの作業グループ、PowerQueryなどなど、数え上げればキリがないくらい Excel には機能が充実しています。

これに関しては Googleスプレドシート使いの mirも認めてまして、一部の作業は まだまだ Excel の方が便利で 抜け出せないままですし、ぶっちゃけプレゼン資料作成は Powerpoint メインから変わってません。(なるべく 意識して Googleスライドも使うようにしてますが)

でも、今回取り上げるのは Excelの中では比較的地味目な スピン機能(スピンボタン)

あまり複雑な機能だと Googleスプレッドシートに手作業で実装するのは、ハードルが高いですし、この辺りの「ちょっと便利だけど無くても不便では無い」軽めなネタが良いかなと。

スピン機能 を GAS関数で Googleスプレッドシートに実装する方法を検証し、満足いくものが作れるのか? どのアプローチがベストなのか?を考えてみたいと思います。



スピン機能(スピンボタン)とは?

Webの入力フォームとかで 数字を入れる際に使う ▲ ▼ ボタンで増減できるアレですね。 Excelでは 昔から機能として存在しており、活用している会社(個人)も多いんじゃないでしょうか?

Excelでの使いどころとしては、Excel方眼紙 で作成した フォーム で数字を入れる箇所 に使い 誤入力防止や 入力の簡便性を向上。

もしくは、データテーブル&関数と組み合わせることで、カチカチと数値を動かして、紙をめくる感覚で 視覚的にわかりやすいデータを表示させたりする、カード型DBっぽい使い方があります。

Excelスピンはサクサク動く

上の画像ですが、下の部分は、VLOOKUP か XLOOKUP (もしくはINDEX)で別シートのデータテーブルから、番号に合致する 横一行分のデータをもってきて、タイトルに応じた値を取得する式で出来ます。

今回の本題ではないので式の説明は省きますが、この表示部分は Googleスプレッドシートでも同じように数式で作れます。


問題となるのが、クリックしている上の上下ボタン部分と連動して変化するA2セルの数字の部分。これがスピンボタンなんですが、残念ながら Googleスプレッドシートにはありません。

個人的には 数値を手入力するか、プルダウンで選択でもいいと思うんですが、どーしても使いたいという 老 害 ユーザー がいたりします。

Excelの機能を大して使えてない人に限って、Excelでは出来るけど Googleスプレッドシートでは出来ないことの文句を言うんですよね。。


ま、愚痴はいいとして今回は Googleスプレッドシートで スピンボタンを実装する為の検証を 4回に分けて記事したいと思います。

今どき「スピ〇」って言ったら スピルだろ!っていわれそうですし、スピン機能ごときで 全4回? と ネタの水増しを疑う方がいるかもしれませんw

でも、4種類のアプローチを通じて GASの基礎 や 関数の応用について 理解が深まると思いますのでお付き合いください。



Q. セルの数字を増減させるスピンボタンを実装したい

・A2セルの数字 スピンボタンで 増減させたい

(以下は追加要件)
・できれば Excelみたいに サクサク動かしたい
・できれば スマホ(アプリ版)でも使えるとよい
・増減の値は カスタムできるとよい。 1ずつ以外に5ずつとか。
・セル固定ではなく、アクティブセルでスピン機能使えたりする?

今回のスピン機能お題の要件

とりあえずは機能として無い スピンボタンを まずは作って、可能であれば追加要件に対応していくって感じでしょうか。

以下の4つの方法で検証してみます。

  1. GAS を 割り当てた スピンボタンを作ってみる

  2. モバイル対応 onEdit で動くスピンボタンを考える

  3. 関数でスピンボタンは出来るのか?

  4. HtmlService使って ダイアログでスピン

満足いくスピン機能は実現できるでしょうか?



A1.GAS を 割り当てた スピンボタンを作ってみる

完成イメージ

まず、今回はネット上でよく見かける GASを使った定番の方法。

  1. GAS を 割り当てた スピンボタンを作ってみる

を試してみましょう。手順としては以下の通り。

今回は簡単なネタなんで、丁寧に書いていきます。

1. スプレッドシートで スピンボタンと連動させるセルを準備
2. スクリプトエディタでコードを書き保存
3. 初回の実行の際の 承認をする
4. エディタ上から試しに実行し動作確認
5. 図形描写で ボタンを作成、ボタンを配置
6. ボタンにスクリプトを割り当て
7. ボタンを押してテストする
8. 完成

GASを割り当てたスピンボタン作成の流れ



A1-1. スプレッドシートで スピンボタンと連動させるセルを準備

まずは、スピンボタンに連動して数字が変化するセルを決めます。スピンボタンを動かすことが優先なので、まずは連動させるセルは固定で良いです。

とりあえず A2セルとして、枠線で目立たせ、フォントを36、太字にすることで目立たせておきましょう。

隣の B2セルは UPとDOWN 2つのボタンを置く予定なので、セルの塗りつぶしで薄いグレーにしてやや縦長にしておきます。

ちなみに上記のように 不要な罫線を消して 白キャンバスとして使いたい場合は、表示メニューから グリッド線のチェックを外せばOK。わざわざ罫線の色を変える必要はありません。



A2-2. スクリプトエディタでコードを書き保存

それではGASを書いていきましょう。

とりあえずは、実行したら A2セルの値を 1増やす、シンプルな アップボタン用のコードを書きます。

メニューの 拡張機能 > Apps Script でエディタを開きます。


モードによっては背景は白になります

function 【関数名】(){
 【ここにコードを書いていく】
}

まずは関数名を myFunction から変えときましょう。

  • どういう関数名にしたらいいの?

  • 日本語でもいいの?

  • spin button みたいに 複数単語を使ってもいいの? 

この辺りの疑問がある方は、「いつも隣にITのお仕事」さん がまとめてくれている、GASにおける コード記述のお作法(ガイドライン)を読みましょう。とても参考になります。

とりあえずは、セルの値を 1増やすGASなので 関数名を spinUp としておきましょう。

ついでに プロジェクト名を変更しておきましょう。

GASは プロジェクトの中に ファイルがあり、ファイルの中に複数の関数(function)を記述できます。

プロジェクト (初期値「無題のプロジェクト」)
 L ファイル (初期値「コード.gs])
   L 関数 (初期値 「myFunction])

意識せずとも使えますが、プロジェクト名は わかりやすい名前にしておきましょう。ここは functionと違って日本語でも問題ないです。

また ファイル名「コード.gs」は、最初のうちは そのままで問題ないです。
ファイルを複数使い分けるようなレベルになってきたら、名前の付け方をルール化していけば良いです。

コードを最初に書く際の基本的な解説も、「いつも隣にITのお仕事」さんが充実しています。ほんと凄いわ。


spinUp の コードを以下のように書きました。

//A2セルの値を 1増やす
function spinUp() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const spinCell = sheet.getRange("A2");
  const value = spinCell.getValue();
  spinCell.setValue(value + 1);
}

解説は後でするので、まずは 保存し実行ボタンを押してみましょう。

※ GASは必ず 保存をする必要があります。



A1-3. 初回の実行の際の 承認をする

初回の実行では色々コードの権限チェックをしているようで、少し待ち時間が長いです。

そして GASから スプレッドシートや その他Google Docsファイル類の操作、読み取りをする場合は、初回に権限の許可をする承認プロセスが必要となります。

今回の場合は GASから スプレッドシートの読み書き をするので、上記のような権限許可の承認プロセスが 初回に発生します。

もちろん スプレッドシートから エディタを開く コンテナバインド スクリプトでも、エディタ内で完結する だけの コードなら 承認プロセスは必要ありません。

ここの流れも 「いつも隣にITのお仕事」さんを参考に。

リンク先に細かく書いてありますが、無料アカウントの場合は 安全でないみたいな表記が出てビビらせてきます。

自分で作ったスクリプト実行するだけなのに、なんか恐ろしい関所を通過しないといけない感じで、ちょっとした初心者殺しですね。

このスクリプト承認は、誰か一人(たとえばオーナー)が実行すればOK
ってわけじゃなく、実行する全ての人が必ず初回に通る試練ってのが厄介なんです。

作成したGASを使ってもらう場合、ユーザーに初回承認の流れを周知する必要があります。



A1-4. エディタ上から試しに実行し動作確認

Chrome(Edgeもだけど)は、タブを掴んでポイって感じで タブを独立させることが出来ます。だから、わざわざ実行して切り替えてシート確認ではなく、上記のようにエディタと シートを並べた状態でテストが出来ます。

実行後にA2の数値が 1増えてますね。成功です。

ここで 少しコードを解説しておきましょう。初歩的な部分です。


const sheet = SpreadsheetApp.getActiveSheet();

開いている状態での実行を前提とした、対象のスプレッドシートの エディタに記述した コンテナバインド型の スクリプトの場合、今開いているシートが アクティブシートです。

SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
と書いても問題ないですが、対象のスプレッドシート内の他のシートは関係ない場合は 直接アクティブシートを取得する上記の書き方がシンプルで良いです。

マクロの記録 を参考にしたのか、getActive() や activate() を使った記述を使ってる人もいますが、あまりお勧めしません。

ちなみに アクティブシートですが、時間トリガー や 対象のスプレッドシート以外の場所に記述された コードから操作する場合は、アクティブなシートという概念がないので、誤作動のもとになります。このような利用の際は、シート名で指定しましょう。


const spinCell = sheet.getRange("A2");

これで A2セルを取得しています。
※ここで取得(get)できるのは、あくまでも Rangeオブジェクト であって セル内の値ではありません。

もちろん 行番号と列番号で  getRange(2,1) として 2行1列目(つまりA2)を指定する書き方でもOK

状況に応じて使い分け出来ると良いです。

ちなみに getRange("R2C1") って書き方もできますが、これを使うことはないでしょうw

注意点として、A1表記の時は 文字列なので ' クォート(もしくは " ダブルクォート)で括る必要があります。 逆に 行番号、列番号で取得する場合は 数値なので クォートで括ってはダメです。

getRange はスプレッドシートで GASを使う際の基本中の基本なんですが、結構間違った説明をしているサイトも多いです。大きくは間違ってないですが、細かいミスがあります。でも Google検索で上位表示という・・・。気をつけましょう。


ちなみに 今回は const ばっかり使ってますが、他に let, var があります。これらは、いずれも 変数を宣言する際に使うものです。

GASは 当初は var しか使えなかったんで、 全て var で変数宣言しているコードを掲載しているサイトが多いんですが、今どきは const , let をメインで使うべきです。

使い分けについては、再代入や再宣言の可否、あとはスコープの違いなんですが、これは多くのJavaScript 系のサイトで 解説されているので、そっち見た方が早いでしょう。


spinCell.setValue(value + 1);

spinCell(A2)に setValue で value + 1 を書き込んでいます。
これによって  A2の値 が +1 されたものに置き換わります。

ここは spinCell.setValue( ++value) と書くこともできますが、この書き方はちょっとわかりづらいですよね。

そもそも、 なぜ value++ ではなく、 ++value なのか?

これは説明すると長くなるので、以下のサイトを参考にしてください。
直接 使う場合の前置き、後置きの挙動の違いがわかるかと思います。

  let value = spinCell.getValue();
  value++; //++value でも一緒
  spinCell.setValue(value);

ちなみに、こう記述すれば value++ , ++value どっちでも良いです。

でも 普通に +1 ってすりゃいいですね。
他にも

value +=1 

といった 書き方もあります。



条件を考慮してコードを精査

・増減の値は カスタムできるとよい。

という要件を考慮すれば +1 をそのまま使うのではなく、以下のよう 変数 numを宣言しておいて、 value + num と書いておいた方が汎用性があります。

//A2セルの値を 1増やす
function spinUp() {
  const num = 1;
  const sheet = SpreadsheetApp.getActiveSheet();
  const spinCell = sheet.getRange("A2");
  const value = spinCell.getValue();
  spinCell.setValue(value + num);
}

 減ボタン用のコードは、マイナスすればよいので以下になります。

//A2セルの値を 1減らす
function spinDown() {
  const num = 1;
  const sheet = SpreadsheetApp.getActiveSheet();
  const spinCell = sheet.getRange("A2");
  const value = spinCell.getValue();
  spinCell.setValue(value - num);
}

これをそれぞれ 増ボタン、減ボタンに割り当てれば良いんですが・・・。なんか重複する部分多くて無駄が多い感じですよね?

これを 共通部分を spin関数としてまとめて、Up と Down は引数で制御する形にして 簡略化 & メンテナンス しやすくしてみましょう。



【スピンボタン用コード 完成版】

//図形をボタンとして使う GASスピン

//設定値
const sheet = SpreadsheetApp.getActiveSheet();
const num = 1; //増減値
const spinCellAdd = "A2"; //対象のセル

//▲ボタン用 増
function spinUp(){
  spin(num);
}

//▼ボタン用 減
function spinDown(){
  spin(-num);
}

//基本動作となる関数
function spin(x) {
  const spinCell = sheet.getRange(spinCellAdd);
  spinCell.setValue(spinCell.getValue() + x);
}

設定値(対象シート、増減値、対象セル)を 関数の外に出して、グローバル変数としています。

さらに、コードの共通部分を spin という関数にして spin(x) で、xという引数を持たせています。

増関数 spinUp の中では spin(num) として、spin の引数にそのまま num を指定することで numを加算

一方 減関数 spinDown は spin(-num) で -num を spinの引数に指定することで num 分を 減算させています。

これでコードが完成しました。

この時点で先ほどと同じように 保存、実行して 動きをテストする必要がありますが 解説は省略します。



A1-5. 図形描写で ボタンを作成、ボタンを配置

Googleスプレッドシートで 図形や 線を入れる場合は、挿入 > 図形描写 から作成します。


Googleスプレッドシートの図形描写は・・・

図形関連は、正直 Googleスプレッドシートはクソ仕様だと思います。
Excelに比べてすごーく不満。

図形描写で作成した オブジェクトは、スプレッドシート上では コピーすら出来ないし、編集も サイズ変更と 設置場所の移動しかできず、色を変えたり 枠線の太さを変えたりといった、ちょっとした修正をするにも 再度図形描写の ダイアログを表示して行う必要があります。

ついでに言うと、ハイパーリンクを付与することも出来ません。

さらに、スプレッドシート上でのサイズ変更は図形描写上のサイズ変更とは別扱いという仕様。

せっかく調整したのが・・・

頑張って シート上で いい感じのサイズに調整しても、少し色を変えようと図形描写で 色を編集・保存すると シート側での調整がリセットされます。

つまり、同じサイズの図形をコピーする場合も、図形描写側で 適切なサイズにしておく必要があるってことです。

シートとの位置関係が見えない 図形描写の画面で サイズをいい感じにするってのが、結構手探りな作業なんですよね・・・。

というわけで 今回のように ボタンを上下で2つ作る場合は、

・図形描写を開きまずは Upボタンとして ▲ の図形を いい感じに作成。
・保存して終了すると スプレッドシート上に表示される
・設置場所のセルに置く。
・編集で再び図形描写を開き サイズをいい感じに修正
 (シート側での確認と修正を何度か繰り返す)
・いい感じに完成したら、次は Downボタン。
・完成した▲を 編集で 図形描写を開き 図形描写画面で コピー
・この図形描写は 保存して終了。
・メニューから 挿入 >図形描写 で新しい図形描写を立ち上げ
・先ほどコピーした▲を貼付け
・回転させ 下向きの ▼ とする(サイズは調整されてるのでそのまま)
・色を変えて 保存して終了
・シート上で位置を調整
(シート上では 2つの図形を揃える機能はないので 目視 で位置調整 ※ガイド線は出る)
・完成

この程度の ▲ を反転させた 2つのボタンを作るだけで 結構な工数ですw

Excelだったら 無料の オンライン版でも シート上で直接図形を挿入し編集できますし、タブレットとの相性のよい「描画」も若干不安定ですが便利に使えます。

実際のシートの上に別レイヤーを重ねてるような感じなんでしょうか?

この点はExcelが、かなーり羨ましい。GoogleWorkspace の図形描写関連は抜本的な見直しがあっても良いと思います。



A1-6. ボタンにスクリプトを割り当て

エディタで作成したスクリプトは、Googleスプレッド上の 図形や挿入した画像に割り当てることが可能で、GAS実行ボタンとして利用できます。

スクリプトを割り当てる際は、関数名を入れるだけです。
今回であれば ▲の図形に spinUp▼に spinDown ですね。
割当の際は、関数の後ろの() はつけません

残念ながら、各図形から実行の際に 引数をもたせることができないので、1つの関数でボタン毎に違う動作をさせることはできません

HTMLみたいに 図形に id とか value 要素を付与できると 面白そうなんですけけどね。

だらかGASの場合は、ボタン毎に関数(function)を用意してあげる必要があります。

ここが面倒です。

ただ、今回のようにほぼ同じ動き( up か down で A2セルの数値を プラスかマイナスかってだけの違い)の場合は、同じようなコードを2回書くのではなく、基本形の関数を作って、そこに引数を渡して実行する関数を用意してあげるとスマートです。



A1-7. ボタンを押してテストする

実際に動かしてみましょう。

もったり

うーん、とりあえず動くけど もったりしてますね。
このGAS特有のもったり感は、結構ストレスを感じそうです。

そして、中央上部に表示される「スクリプトを実行しています」が、かなりウザい!ひどいと3つくらい表示されてます。


実はこれでも、かなりクリック速度に気を使ってますw
なぜならExcelと同じ感覚で連打しちゃうと・・・

うげー

図形をダブルクリックしたと検知され、図形の編集画面(図形描写)が開いてしまいました。これはユーザーに使わせるの微妙だなと。



【余談】Googleスプレッドシートの図形描写のイライラを解消する方法

今回の流れでは 図形作成・調整の煩雑さ、シート上でコピーできない問題、さらに クリック連打で 編集画面が開くという 図形描写のクソ仕様に、作成時から利用時まで イライラさせられっぱなしでした。

一応、これらをズバっと解消・ズバッと解決する方法があります。
(平成キッズは 「かいけつ」と言えば ゾロリでしょうが、昭和世代は  怪傑ズバットですね)

その方法は、ExcelやPowerpointといった MSオフィスツールで 作成した図形をコピペしちゃう方法。

ものすごーく本末転倒というか、そもそも Excel持ってないから Googleスプレッドシート使ってるって人も多いでしょうが、両方使える人は結構コレが楽だったりします。

もちろん、色や枠線の変更は Excel側でやっておく必要がありますが、これだと Googleスプレッドシート側では (背景透明の)画像扱いなので、普通にコピペが可能だし、ダブルクリックで 図形描写が開くこともありません。(スクリプトは 画像にも割り当て可能です)

注意点としては、あくまでも パソコンで インストールアプリの オフィスソフトからのみコピペ可能という点。残念ながら Web版の オフィスからはコピペ出来ません

もちろん ネット上の フリー素材をGASボタンに使う方法もありますね。


そして、もう一つの方法。こちらは図形のコピーが簡単に出来ない問題の解決策。

Androidアプリ版で 図形をコピペする という スプシハックです。
(〇〇ハックって言葉はあんま好きじゃないですがw)

なぜか Androidアプリ版だと、シート上で図形がコピーができます。コピーした図形は勝手に画像に変換されたりもなく、PC側から 図形描写で開いて編集もできますし、割り当てたスクリプトも引き継いでいます。

これは残念ながら Androidアプリ限定で、iPhone(iOS)版のスプレッドシートアプリだと使えません。タップしても 選択肢が「削除」しかないという謎仕様。

いずれも 完全なる解決とはいえませんが、図形描写でイライラが溜まってる人はお試しを。



さて、とりあえずはサクサクとはいきませんでしたが、スピンボタンとして一応は動きました

最後に、その他の要件への対応可否を確認しておきましょう。

その他 要件を満たせるかの確認


・できれば スマホ(アプリ版)でも使えるとよい NG

残念ながら、これは出来ません。2023年1月現在、スマホアプリ版では 図形(画像)からスクリプトは実行できません

一応、スマホのブラウザで PC版を表示させて 図形をタップすることで、GASを実行させることは可能です。(使いにくいですが)


・増減の値は カスタムできるとよい OK

これは num を 変えればよいだけですね。

シート上のセル から読み込んだ数値を num として使う方法もありますが、さらに遅くなりそうなんで エディタ上での設定変更としておきます。


・セル固定ではなく、アクティブセルでスピン機能使えたりする?

これは コードと構成を少し変えれば可能です。

//アクティブセルをスピン

//設定値
const sheet = SpreadsheetApp.getActiveSheet();
const num = 1; //増減値
//const spinCellAdd = "A2"; //対象のセル (使わない)

//▲ボタン用 増
function spinUp(){
  spin(num);
}

//▼ボタン用 減
function spinDown(){
  spin(-num);
}

//基本動作となる関数
function spin(x) {
  const spinCell = sheet.getActiveRange(); // ← ここを変更
  spinCell.setValue(spinCell.getValue() + x);
}

const spinCell = sheet.getActiveRange();

こう変えることで、選択しているセルをスピンで増減させることが出来ます。需要があるのかはわかりませんが・・・。


出来たこと、出来なかったこと、その他の注意点をまとめておきます。


A1.GASを割りあてた スピンボタンで、実現できたこと & 注意点

・A2セルの数字 スピンボタンで 増減させたい → OK

(以下は追加要件)
・できれば Excelみたいに サクサク動かしたい → ×
・できれば スマホ(アプリ版)でも使えるとよい → ×
・増減の値は カスタムできるとよい。      → OK
・セル固定ではなく、アクティブセルでスピン機能使えたりする? → OK

(その他の注意点)
・ユーザー毎に初回はスクリプトの承認が必要

・連打すると 図形描写の編集画面が開いてしまう

A1.GASでスピンボタンを作ってみる まとめ

結構 できないこと、マイナス点が多いですね。

とにかく、サクサク動かない上に、実行してますの表示が次から次へと出てくるのが微妙。

さらには ユーザー毎に 初回承認が必要だし、連打すると 図形描写がババーンと立ち上がるし。。

ぶっちゃけ 実用的ではありません!

↓ サクサク動かないのを逆手にとって、こんな感じで 9つの数値を全てスピンボタンで揃えて タイムを競うゲームは面白いかもw

急ぎたいけどクリックが早すぎると 図形描写が開くチキンレースww




今回は ボタンに GASを割り当てる方法で、Googleスプレッドシートにスピン機能を実装してみました。が、まとめの通り実務に使うには微妙です。

より良い方法を求めて、次回は onEdit を組み合わせたスピンを検証してみましょう。



■このシリーズの次の記事


この記事が気に入ったらサポートをしてみませんか?