以前、こちらの記事でレンタル器材のサイズ判定を自動化しました。
この時は足のサイズが24cm以下ならS、25cm~26cmならM、27cm以上ならLといった形で単純に判定していました。
でも…
現実ってそんなに簡単に行きませんよね。
各サイズ潤沢に用意してあれば、この方法でもOKなのですが、実際には数に限りがあります。
例えば以下の様な例。
保有しているレンタルフィン
- S:7
- M:5
- L:3
当日のゲストが本来適切なサイズ
- S:4
- M:6
- L:1
こんな時、みなさんならどうしますか??
多くの場合、大は小を兼ねる、本来であればMサイズの人に、少し大きいですがLサイズのフィンを渡すのでは無いでしょうか。
なぜか女性だけにゲストが偏った日など、起きがちな現象ですよね。
サイズが合わないフィンを渡すなんて、お店としてケシカラン!!
という議論は一旦無しにしましょう(笑)
さすがに足のサイズ24cmの人にLサイズを渡すのはどうかと思いますが…
ということで、今回はそんな、より現場に即したサイズ判定を実現してみたいと思います!
完成イメージ
- 足のサイズからフィンのサイズを判定する
- 保有レンタル器材が不足する場合には、ワンサイズ大きなフィンを渡す
- 2サイズUPは無し
※D・E列は挙動確認用なので、気にしないでください
実装
今回も、関数だけでは実現できないので、GoogleAppsScriptのお世話になります。
GASは以前もご紹介しましたが、Googleが提供するスプレッドシートなどのアプリケーションの、複数の作業を自動化したり、いくつかのGoogleのアプリケーションを連携したり、と様々なことを可能にするプログラミング言語のことだと思って下さい。
ちなみにこれを編集するためには、スプレッドシートで『ツール』→『スクリプトエディタ』とクリックして行くと編集画面が出現します。
実現したいことを紐解く
今回の想定する挙動を棚卸ししてみます。
- 最終行を取得する
- サイズのしきい値、各サイズの保有数を定義する
- カウント用変数を準備する
- 第一ループ
- しきい値からサイズを判定
- 保有数がカウントを上回っていれば当該サイズで決定。カウント+1
- 保有数がカウントを下回っていれば一旦保留
- Lサイズの場合には、それより上が無いので足りなければサイズ欄を赤く塗る
- 第二ループ
- サイズ欄が空白なら実行
- しきい値からサイズを判定
- ワンサイズ大きなフィンの保有数がカウントを上回っていれば当該サイズで決定。カウント+1
- 保有数がカウントを下回っていれば、サイズ欄を赤く塗る
以上です。
1行ずつ解説付きで行きますね。
えいっ!
//関数開始
function fin_size() {
//最終行を入力するBoxを表示し、入力値を『last』に格納。※1
var last = Browser.inputBox('最終行を入力してください。');
//今開いているシートを『sheet』に指定
var sheet = SpreadsheetApp.getActiveSheet();
//Sサイズの最大値+1を取得(今回はI2セルに記入して指定。ここで直接書いてしまっても可)
var sMax = sheet.getRange(2 , 9).getValue();
//Mサイズの最大値+1を取得(今回はI3セルに記入して指定。ここで直接書いてしまっても可)
var mMax = sheet.getRange(3 , 9).getValue();
//Sサイズの保有数を取得(今回はH2セルに記入して指定。ここで直接書いてしまっても可)
var sHave = sheet.getRange(2 , 8).getValue();
//Mサイズの保有数を取得(今回はH3セルに記入して指定。ここで直接書いてしまっても可)
var mHave = sheet.getRange(3 , 8).getValue();
//Lサイズの保有数を取得(今回はH4セルに記入して指定。ここで直接書いてしまっても可)
var lHave = sheet.getRange(4 , 8).getValue();
//Sサイズのサイズ確定数カウント用変数準備
var sCount = 0;
//Mサイズのサイズ確定数カウント用変数準備
var mCount = 0;
//Lサイズのサイズ確定数カウント用変数準備
var lCount = 0;
//不足している場合にセルを塗る色を指定(赤)
var rgb = "#ff0000";
//第一ループ。ループ回数カウント用変数『i』の初期値2。これが最終行と等しくなるまで→各行で繰り返し
for(var i=2;i<=last;i++){
//シートに記入するための変数を準備&初期化
var size = "";
//その行の人の、足のサイズを示すセル(今回はB列)から数値を取得
var foot = sheet.getRange(i , 2).getValue();
//もし足のサイズがSサイズのしきい値未満なら
if(foot<sMax){
//もし<Sサイズの保有数>-<Sサイズ確定者数>が0より大きければ(不足していないなら)
if(sHave - sCount > 0){
//シート記入用変数『size』にSを代入
size = "S";
//Sサイズ確定者を+1
sCount++;
//不足判定終わり
}
//もし足のサイズがMサイズのしきい値未満なら
}else if(foot<mMax){
//もし<Mサイズの保有数>-<Mサイズ確定者数>が0より大きければ(不足していないなら)
if(mHave - mCount > 0){
//シート記入用変数『size』にMを代入
size = "M";
//Mサイズ確定者を+1
mCount++;
//不足判定終わり
}
//ここまでの条件に一致しなければ(Mサイズのしきい値以上なら)
}else{
//もし<Lサイズの保有数>-<Lサイズ確定者数>が0より大きければ(不足していないなら)
if(lHave - lCount > 0){
//シート記入用変数『size』にLを代入
size = "L";
//Lサイズ確定者を+1
lCount++;
//不足判定終わり
}
//サイズ判定終わり
}
//その行のサイズ欄に『size』を記入(サイズが未定なら空白になる)
sheet.getRange(i , 3).setValue(size);
//第一ループ終わり
}
//第二ループ。ループ回数カウント用変数『i』を初期化し、初期値2。これが最終行と等しくなるまで→各行で繰り返し
for(var i=2;i<=last;i++){
//シートに記入するための変数を初期化
var size = "";
//その行のサイズ欄の値を『done』に取得
var done = sheet.getRange(i , 3).getValue();
//もし『done』が空白なら→保有数が不足し、保留だったら
if(done == ""){
//その行の人の、足のサイズを示すセル(今回はB列)から数値を取得
var foot = sheet.getRange(i , 2).getValue();
//もし足のサイズがSサイズのしきい値未満なら
if(foot<sMax){
//もし<Mサイズの保有数>-<Mサイズ確定者数>が0より大きければ(不足していないなら)
if(mHave - mCount > 0){
//シート記入用変数『size』にMを代入
size = "M";
//Mサイズ確定者を+1
mCount++;
//一致しない場合(不足している場合)
}else{
//その行のサイズ欄を赤く塗る
sheet.getRange(i , 3).setBackground(rgb);
//不足判定終わり
}
//もし足のサイズがMサイズのしきい値未満なら
}else if(foot<mMax){
//もし<Lサイズの保有数>-<Lサイズ確定者数>が0より大きければ(不足していないなら)
if(lHave - lCount > 0){
//シート記入用変数『size』にLを代入
size = "L";
//Lサイズ確定者を+1
lCount++;
//一致しない場合(不足している場合)
}else{
//その行のサイズ欄を赤く塗る
sheet.getRange(i , 3).setBackground(rgb);
//不足判定終わり
}
//ここまでの条件に一致しなければ(Mサイズのしきい値以上なら)
}else{
//その行のサイズ欄を赤く塗る
sheet.getRange(i , 3).setBackground(rgb);
//サイズ判定終わり
}
//その行のサイズ欄に『size』を記入(サイズが未定なら空白になる)
sheet.getRange(i , 3).setValue(size);
//空白判定終わり
}
//第二ループ終わり
}
//関数終わり
}
※1:最終行の取得について
最終行の自動取得はなかなか複雑になりがちです。
また、絶対に行をキッチリ詰めて記入されていれば、ループにforではなくwhileを使う方法もありますが、申込み元などを見やすくするために、空白行を設けている場合もあるかと思います。
これに自動対応することも可能かと思われますが、そのコードによって全体が複雑化すること、最終行を毎回入力するぐらいであれば手間にならないだろうということ、を鑑み、入力方式にしています。
これを応用することで、BCやウエットスーツのサイズ判定にも使用出来るのではないかと思います!
BCの場合は身長だけでなく体重も重要な要素になるので、もう少し複雑になりそうですね。
ウエットスーツの場合は男女別があることと、スーツのサイズが豊富なので、こちらも相当複雑になるでしょう。
もちろんフィン同様、サイズが完璧に合わないものを渡すことに問題もあるので、本来であればピッタリのサイズが不足しているのであれば、知人のお店などから借りるのがベストですが…
BCやウエットの場合も、機会があれば考えてみたいと思います!
宣伝
こんな便利ツール作って欲しい、みたいなオーダーがあれば、お引き受けしたいなと思います。
※ダイビングショップ運営に関わるものに限ります。
今回の様に関数だけでなくGoogleActionScriptを導入する場合には8000円/件
標準の関数のみで実現出来る物であれば3000円/件
GoogleFormとの連携が必要なものであれば+1000円/件
でいかがでしょうか!?