GASでくじ引きプログラムを作成

GAS

1~43の数字のくじ引きで、過去の抽選で出現した数字の出現回数を考慮したくじ引きプログラムを作成してみる

やりたいこと

  • 1~43の数字のくじ引きを行う
  • 全期間の1~43の出現回数を考慮したくじ引きをする
  • 過去50回の1~43の出現回数を考慮したくじ引きをする

プログラム作成前の準備

①スプレッドシートの作成(ここでは「抽選」というタイトルを設定)

②抽選シートを作成する
 ・抽選結果を表示する箇所(A2:A7とC2:C7)
 ・メッセージを表示する箇所
 ・抽選ボタン
 を作成する

③過去のデータシートを作成する
・過去の抽選結果を入力する

プログラミングを作成する

プログラム

//メイン処理:抽選処理を行う
function randomSelect(){
  //スプレッドシートを操作できるようにする
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  //"過去のデータ"のシートを取得する
  const dataSheet = ss.getSheetByName("過去のデータ");
  //"抽選"のシートを取得する
  const drawSheet = ss.getSheetByName("抽選");
  //"乱数"のシートを取得する
  const randomNumberSheet = ss.getSheetByName("乱数"); 
  //"乱数"のシートを取得する
  const lastRow = dataSheet.getLastRow();
  let drawAllNo
  let drawAfter50

  //"抽選"のシートのA2:C7(抽選結果表示範囲)を空欄にする
  drawSheet.getRange("A2:C7").setValue("");
  //"抽選"のシートのF2に「抽選中です」を入力する
  drawSheet.getRange("F2").setValue("抽選中です");

  //"過去のデータ"のシートの抽選番号1~6の列の最終行まで(全期間)の値を一次元配列で取得する
  let dataAllNo = dataSheet.getRange(2, 3, lastRow - 1, 6).getValues().flat();
  //自作関数「drawData(argDataNo, argRandomNumberSheet)」を呼び出し、
  //戻り値(全期間から抽選した6個の数字)をdrawAllNoに代入する
  drawAllNo = drawData(dataAllNo, randomNumberSheet);

  //"過去のデータ"のシートの抽選番号1~6の列の最終行から50回分の値を一次元配列で取得する
  let dataAfter50No = dataSheet.getRange(lastRow - 49, 3, 50, 6).getValues().flat();
  //自作関数「drawData(argDataNo, argRandomNumberSheet)」を呼び出し、
  //戻り値(過去50回分から抽選した6個の数字)をdrawAfter50に代入する
  drawAfter50 = drawData(dataAfter50No, randomNumberSheet);

  let rowCnt = 0
  //以下の処理を6回繰り返す
  for(let drawNoIndex = 0; drawNoIndex < 6; drawNoIndex++){
    //A列の2 + rowCnt行目に全期間の抽選結果を入力する
    drawSheet.getRange(2 + rowCnt, 1, 1, 1).setValue(drawAllNo[drawNoIndex]);
    //C列の2 + rowCnt行目に過去50回分の抽選結果を入力する
    drawSheet.getRange(2 + rowCnt, 3, 1, 1).setValue(drawAfter50[drawNoIndex]);
    //rowCntを+1する
    rowCnt++;
  }

  //"乱数"のシートのA1をクリアする
  argRandomNumberSheet.getRange("A1").clear();

  //"抽選"のシートのF2に「抽選結果を表示しました」を入力する
  drawSheet.getRange("F2").setValue("抽選結果を表示しました");
}

//抽選を行う
function drawData(argDataNo, argRandomNumberSheet) {
  let drawNo = [];
  let randomIndex
  //filterNoListにargDataNoを代入する
  let filterNoList = argDataNo;
  //以下の処理を6回繰り返す
  for(let drawCnt = 0; drawCnt < 6; drawCnt++){
    //自作関数「getRandomIndex(argLength, argRandomNumberSheet)」を呼び出し、
    //戻り値(0~"filterNoListの要素の数"内のランダムな1つの数字)をrandomIndexに代入する
    randomIndex = getRandomIndex(filterNoList.length, argRandomNumberSheet);
    //drawNoにrandomIndexを追加する
    drawNo.push(filterNoList[randomIndex]);
    //filterNoにfilterNoList[randomIndex](抽選番号)を代入する
    let filterNo = filterNoList[randomIndex];
    //filterNoListにfilterNoList[randomIndex](抽選番号)を含まないデータを代入する
    filterNoList = filterNoList.filter(function(value){
      return value != filterNo;
    });
  }
  
  //抽選結果を返す
  return drawNo
}

//0~"引数argLength"から1つの数字をランダムに取得する
function getRandomIndex(argLength, argRandomNumberSheet){
  let randomNumber
  //"乱数"のシートのA1セルに「"=RANDBETWEEN(0," + argLength - 1 + ")"」を入力する
  argRandomNumberSheet.getRange("A1").setValue("=RANDBETWEEN(0," + (argLength - 1) + ")");
  //"乱数"のシートのA1セルから"=RANDBETWEEN(0," + argLength - 1 + ")"でランダム表示された数字を取得する
  randomNumber = argRandomNumberSheet.getRange("A1").getValues();
  //ランダムで表示された数字を返す
  return randomNumber;
}

解説

2行目の「randomSelect()」を実行することで抽選が行われる
52行目に抽選処理を行う「drawData(argDataNo, argRandomNumberSheet)」
75行目に乱数を取得する「getRandomIndex(argLength, argRandomNumberSheet)」
の3つの自作メソッドを記載している

randomSelect()

「randomSelect()」はメイン処理で、主に

  • 抽選シートの抽選結果の削除、メッセージの変更
  • 過去のデータシートから全期間と過去50回分の抽選番号を取得する
  • 過去のデータシートから取得した抽選番号を「drawData(argDataNo, argRandomNumberSheet)」に渡す
  • 「drawData(argDataNo, argRandomNumberSheet)」から取得した抽選結果を抽選シートに表示する
  • 乱数シートのA1セルのクリア
  • メッセージの変更

という流れで処理が記載されている

12行目では過去のデータシートに抽選結果を追加することを想定し、「const lastRow = dataSheet.getLastRow();」で過去のデータシートの最終行を取得
22行目では全期間(過去のデータシートの2行目から”最終行 – 1″の行数分)の抽選番号を取得している
「let dataAllNo = dataSheet.getRange(2, 3, lastRow – 1, 6).getValues().flat();」
28行目では過去50回分(過去のデータシートの”最終行 – 49″行目から50行分)の抽選番号を取得している
「let dataAfter50No = dataSheet.getRange(lastRow – 49, 3, 50, 6).getValues().flat();」

25行目と31行目で「drawData(argDataNo, argRandomNumberSheet)」を呼び出し、全期間からと過去50回分からの抽選結果を取得している

35行目のfor文で抽選結果を表示している
【for文の条件】
・”drawNoIndex”に0を代入
・”drawNoIndex”が6未満の場合処理をする
・実行処理が完了したら”drawNoIndex”に1を足す
【実行処理】
抽選シートのA列の2 + rowCnt行目に全期間の抽選結果を入力する
「drawSheet.getRange(2 + rowCnt, 1, 1, 1).setValue(drawAllNo[drawNoIndex]);」
抽選シートのC列の2 + rowCnt行目に過去50回分の抽選結果を入力する
「drawSheet.getRange(2 + rowCnt, 3, 1, 1).setValue(drawAfter50[drawNoIndex]);」
rowCntを+1する
「rowCnt++;」

for文が繰り返されるたびに「drawSheet.getRange(2 + rowCnt, 1, 1, 1).setValue(drawAllNo[drawNoIndex]);」の「2 + rowCnt」で2行目から1行ずつ下に移動し、「drawAllNo(drawNoIndex)」でセルに抽選結果(要素番号0から1ずつ足している)を入力している

drawData(argDataNo, argRandomNumberSheet)

「drawData(argDataNo, argRandomNumberSheet)」は

  • 「getRandomIndex(argLength, argRandomNumberSheet)」を呼び出し、0から配列argDataNoの要素数までのランダムな数字を取得する
  • argDataNo[ランダムな数字]を抽選結果に追加する
  • argDataNo[ランダムな数字]の値をargDataNoから削除する

以上の処理を6回繰り返し、呼び出し元に抽選結果を返す

getRandomIndex(argLength, argRandomNumberSheet)

「getRandomIndex(argLength, argRandomNumberSheet)」は

  • 乱数シートのA1セルにRANDBETWEEN関数を入力する
  • RANDBETWEEN関数で入力された数字を取得する
  • 取得した数字をdrawData(argDataNo, argRandomNumberSheet)からの呼び出しに返す

という処理を行っている

RANDBETWEEN関数は「RANDBETWEEN(下限, 上限)」という構文で、下限から上限の数字をランダム1つ表示される

作成したプログラムを抽選ボタンから実行する設定をする

①抽選シートの抽選ボタンを右クリックする

②抽選ボタンの「︙」をクリックする

③「スクリプトを割り当て」をクリック

④自作関数名を入力する(ここではメイン処理の「randomSelect」)

⑤「確定」をクリック

作成したプログラムを実行する

抽選ボタンをクリックする

全期間と過去50回に抽選結果が表示されていれば完成!