【GAS】Googleスプレッドシートで在庫管理システムを作成する(旧版)

在庫管理

※この記事は旧版です。

★最新版では列を自由に追加できるようになりました。最新版はこちら

入庫する.gs

/**
 * 入庫処理をする(入荷商品の入荷数を在庫管理表に加算する)。
 */
function nyuko() {
  // 処理開始ダイアログ
  const question = Browser.msgBox("入庫します。在庫数が更新されます。", Browser.Buttons.OK_CANCEL);
  if (question == "cancel") {
    return;
  }

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const zaikoSheet = ss.getSheetByName('在庫管理表');
  const nyukaSheet = ss.getSheetByName('入荷データ');
  const nyukaRirekiSheet = ss.getSheetByName('入荷履歴');

  //「在庫管理表」のデータ取得
  const zLastRowNumber = zaikoSheet.getRange(zaikoSheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  const zaikoData = zaikoSheet.getRange(1, 1, zLastRowNumber, 2).getValues();

  //「入荷データ」のデータ取得
  const nLastRowNumber = nyukaSheet.getLastRow();
  const nyukaData = nyukaSheet.getRange(1, 1, nLastRowNumber, 3).getValues();

  //「入荷履歴」の最終行取得
  const rLastRowNumber = nyukaRirekiSheet.getLastRow();


  // 入庫対象のデータ(商品名と入荷数)を取得する
  let nyukoList = [];
  let nyukoRowsNumbers = [];
  const today = new Date();
  for (let i = 0; i < nLastRowNumber; i++) {
    const rowData = nyukaData[i].flat();
    // 入荷日が今日以前か判定
    if (rowData[2] != "" && rowData[2] <= today) {
      // 入荷数が0以上の数値か判定
      if (isFinite(rowData[1]) && rowData[1] >= 0) {
        // 入庫対象としてリストに追加する
        nyukoList.push([rowData[0], rowData[1], rowData[2]]);
        nyukoRowsNumbers.push(i + 1);
      } else {
        continue;
      }
    }
  }
  if (nyukoList.length == 0) {
    Browser.msgBox("入庫対象はありません。");
    console.log("入庫対象はありません。");
    return;
  }


  // 入庫する(対象商品の入荷数を在庫管理表に加算する)
  let shinShohinList = [];
  const zaikoShohinList = zaikoSheet.getRange(1, 1, zLastRowNumber, 1).getValues().flat();
  for (let i = 0; i < nyukoList.length; i++) {
    if (zaikoShohinList.indexOf(nyukoList[i][0]) != -1) {
      const idx = zaikoShohinList.indexOf(nyukoList[i][0]);
      const zQuantityBefore = zaikoData[idx][1];
      zaikoData[idx][1] = zQuantityBefore + nyukoList[i][1];
      console.log(nyukoList[i][0] + "の在庫数:" + zaikoData[idx][1] + "(現在庫" + zQuantityBefore + " + 入庫数" + nyukoList[i][1] + ")");
    } else {
      console.log("新商品:" + nyukoList[i][0] + "の在庫数:" + nyukoList[i][1]);
      shinShohinList.push([nyukoList[i][0], nyukoList[i][1]]);
    }
  }
  // 在庫管理表を更新する
  if (zaikoData.length != 0) {
    zaikoSheet.getRange(1, 1, zLastRowNumber, 2).setValues(zaikoData);
  }
  // 新商品データがあれば在庫管理表に追加する
  if (shinShohinList.length != 0) {
    zaikoSheet.getRange(zLastRowNumber + 1, 1, shinShohinList.length, 2).setValues(shinShohinList);
  }


  // 入庫対象を削除する(削除前に入荷履歴に転記)
  nyukaRirekiSheet.getRange(rLastRowNumber + 1, 1, nyukoList.length, 3).setValues(nyukoList);
  const reversedNyukoRowsNumbers = nyukoRowsNumbers.reverse();
  for (let i = 0; i < reversedNyukoRowsNumbers.length; i++) {
    nyukaSheet.deleteRow(reversedNyukoRowsNumbers[i]);
  }

  // 処理終了ダイアログ
  Browser.msgBox("入庫が完了しました。");
  console.log("入庫が完了しました。");


}

出庫する.gs

/**
 * 出庫処理をする(出荷商品の出荷数を在庫管理表から減算する)。
 */
function shukko() {
  // 処理開始ダイアログ
  const question = Browser.msgBox("出庫します。在庫数が更新されます。", Browser.Buttons.OK_CANCEL);
  if (question == "cancel") {
    return;
  }

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const zaikoSheet = ss.getSheetByName('在庫管理表');
  const shukkaSheet = ss.getSheetByName('出荷データ');
  const shukkaRirekiSheet = ss.getSheetByName('出荷履歴');

  //「在庫管理表」のデータ取得
  const zLastRowNumber = zaikoSheet.getLastRow();
  const zaikoData = zaikoSheet.getRange(1, 1, zLastRowNumber, 2).getValues();

  //「出荷データ」のデータ取得
  const sLastRowNumber = shukkaSheet.getLastRow();
  const shukkaData = shukkaSheet.getRange(1, 1, sLastRowNumber, 3).getValues();

  //「出荷履歴」の最終行取得
  const rLastRowNumber = shukkaRirekiSheet.getLastRow();


  // 出庫対象のデータ(商品名と出荷数)を取得する
  let shukkoList = [];
  let shukkoRowsNumbers = [];
  const today = new Date();
  for (let i = 0; i < sLastRowNumber; i++) {
    const rowData = shukkaData[i].flat();
    // 出荷日が今日以前か判定
    if (rowData[2] != "" && rowData[2] <= today) {
      // 出荷数が0以上の数値か判定
      if (isFinite(rowData[1]) && rowData[1] >= 0) {
        shukkoList.push([rowData[0], rowData[1], rowData[2]]);
        shukkoRowsNumbers.push(i + 1);
      } else {
        continue;
      }
    }
  }
  if (shukkoList.length == 0) {
    Browser.msgBox("出庫対象はありません。");
    console.log("出庫対象はありません。");
    return;
  }


  // 出庫する(対象商品の出荷数を在庫管理表に加算する)
  const zaikoShohinList = zaikoSheet.getRange(1, 1, zLastRowNumber, 1).getValues().flat();
  for (let i = 0; i < shukkoList.length; i++) {
    if (zaikoShohinList.indexOf(shukkoList[i][0]) != -1) {
      const idx = zaikoShohinList.indexOf(shukkoList[i][0]);
      const zQuantityBefore = zaikoData[idx][1];
      zaikoData[idx][1] = zQuantityBefore - shukkoList[i][1];
      console.log(shukkoList[i][0] + "の在庫数:" + zaikoData[idx][1] + "(現在庫" + zQuantityBefore + " - 出庫数" + shukkoList[i][1] + ")");
    }
  }
  // 在庫管理表を更新する
  if (zaikoData.length != 0) {
    zaikoSheet.getRange(1, 1, zLastRowNumber, 2).setValues(zaikoData);
  }


  // 出庫対象を削除する(削除前に出荷履歴に転記)
  shukkaRirekiSheet.getRange(rLastRowNumber + 1, 1, shukkoList.length, 3).setValues(shukkoList);
  const reversedShukkoRowsNumbers = shukkoRowsNumbers.reverse();
  for (let i = 0; i < reversedShukkoRowsNumbers.length; i++) {
    shukkaSheet.deleteRow(reversedShukkoRowsNumbers[i]);
  }

  // 処理終了ダイアログ
  Browser.msgBox("出庫が完了しました。");
  console.log("出庫が完了しました。");


}

コメント

  1. Tokyo49ers より:

    初めまして

    Youtubeで検索してやってきました。

    Googleスプレッドシートで在庫管理をしたく、こちらのページを参考にしてみたのですが、

    どこを変更したら応用できるのかがわからない状態です。

    具体的には、出庫データに数量だけではなく商品価格なども連動させて出荷履歴を作り、日々の売上一覧表を作成したいのですが、どのようにしたら良いでしょうか?

    お返事お待ちしております。

    • shogo shogo より:

      返信が遅くなり申し訳ないです。
      商品価格の列を追加に応じてプログラムを修正する必要ありますね。
      列を追加したい旨のの問い合わせがいくつかありましたので
      その方法を解説する動画をできる限り早く撮ってアップいたしますので、
      良ければ見て下さいm(_ _)m

  2. 小澤 量 より:

    ありがとうございます。
    ありがたく使わせていただこうとトライしております。

    自分の表でトライしており、

    if (nyukoList.length == 0) {
    Browser.msgBox(“入庫対象はありません。”);
    console.log(“入庫対象はありません。”);
    return;
    }

    でひっかかっておりますが、
    あらためて、スクリプトを勉強しようと思います。

    • shogo shogo より:

      コメントありがとうございます。
      応用がきくスクリプトになっていますのでぜひ色々といじってみてください^^
      ちなみに上記は入庫対象のデータが存在しない場合(nyukoList.length == 0)はプログラムの処理を終了しています(return)。
      問い合わせがいくつか来てましたのでソースコード解説を入れた動画を撮ろうと思います。
      ぜひまた見て下さい。

  3. 阿部 より:

    コメント失礼します。
    ご質問なのですが、こちらのプログラムを応用したいのですが、プログラムのどのあたりを変更すれば対応出来るのか、ご教授いだだけませんでしょうか。
    具体的には、入荷データ、出荷データに数量だけではなく入荷先や出荷先などを追加して入出荷履歴を残したいのです。E列F列G列を追加をしたいです。
    お忙しいところ申し訳ありませんが、宜しくお願い致します。

    • shogo shogo より:

      コメントありがとうございます。
      在庫管理表の問い合わせがいくつかありましたので、
      ソースコードの解説など応用に役立てていただけるような動画をこれから撮ろうと思っています。
      できるだけ早くYouTubeにアップする予定ですので良ければ見て下さい。