【コピペでOK】GASで自動化!Excel/CSVをスプレッドシートへ自動取り込み&整形する方法

自動化事例

「毎月、取引先から送られてくるExcelやCSVの仕入データを、手作業で集計用のシートにコピペしている…」
「日付や数量の形式がバラバラで、毎回手直しするのが面倒…」

このような定型的なデータ入力作業に、多くの時間を費やしていないでしょうか。手作業によるコピー&ペーストは、時間がかかるだけでなく、入力ミスや変換漏れの原因にもなりかねません。

もし、Googleドライブの特定フォルダにファイルを入れるだけで、自動的にスプレッドシートにデータが取り込まれ、さらにキレイな形式に整形までされたら、どうでしょうか?

この記事では、Googleスプレッドシートと、その拡張機能であるGAS(Google Apps Script)を使って、面倒なCSV/Excelの取り込みとデータクレンジング(データ整形)を自動化する具体的な方法を解説します。

紹介するコードはコピー&ペーストして少し設定を変えるだけで使えるので、プログラミング経験がない方でも大丈夫です。この記事を読み終える頃には、あなたは面倒な手作業から解放され、より創造的な仕事に時間を使えるようになっているはずです。

1. 自動化で何ができる?完成形のイメージ

まず、今回作成する「自動化の仕組み」の全体像と、完成形のスプレッドシートのイメージを掴みましょう。

自動化の全体像

仕組みはとてもシンプルです。

  1. 取引先から受け取ったCSVやExcelファイルを、Googleドライブの特定のフォルダ(例:「受信フォルダ」)に保存します。
  2. GAS(Google Apps Script)が定期的にこのフォルダをチェックし、新しいファイルを見つけます。
  3. ファイルの中身を自動でスプレッドシートに読み込み、データを追記します。
  4. スプレッドシートの関数が、読み込まれたデータを自動で整形(クレンジング)します。

この仕組みを一度作ってしまえば、あとはファイルを所定のフォルダに入れるだけで、面倒な作業はすべて自動で完了します。

完成形のスプレッドシート

自動化の核となるのが、これから作成するGoogleスプレッドシートです。このシートは、役割ごとに3つのシートに分かれています。

  1. ① 生データ取込:ドライブから取り込んだCSV/Excelの生データが、そのまま記録されるシートです。
  2. ② 整形済みデータ:①生データ取込のデータを基に、不要なスペースの削除や形式の統一など、キレイに整形(クレンジング)されたデータが表示されるシートです。基本的に、私たちはこのシートのデータを使います。
  3. ③ 処理ログ:いつ、どのファイルを取り込んだか、といった処理の履歴が記録されるシートです。

2. 【実践】自動化の仕組みを作ってみよう!(基本編)

ここからは、実際に自動化の仕組みを構築していきます。手順通りに進めれば、誰でも完成させることができますので、ぜひ一緒に手を動かしてみてください。

Step 1:Googleドライブとスプレッドシートの準備

1-1. ファイルを格納するフォルダを作成

まず、Googleドライブに、CSV/Excelファイルを保存するためのフォルダを2つ作成します。

  • 受信フォルダ:取引先から受け取ったファイルを置くためのフォルダです。GASはこのフォルダを監視します。
  • 処理済みフォルダ:受信フォルダから処理が終わったファイルを移動させておくための保管庫です。

1-2. スプレッドシートの作成と設定

次に、メインとなるGoogleスプレッドシートを新規作成します。
ここでは例として、取引先からの仕入データを想定します。

  1. Googleスプレッドシートを開き、「新しいスプレッドシートを作成」をクリックします。
  2. ファイル名を「仕入データ自動取込シート」など、分かりやすい名前に変更します。
  3. デフォルトで存在する「シート1」の名前を「①生データ取込」に変更します。
  4. シートを追加し、それぞれ「②整形済みデータ」「③処理ログ」という名前に変更します。
  5. 「②整形済みデータ」シート1行目に、以下のようにヘッダー(見出し)を入力します。
A列B列C列D列E列
仕入日商品コード商品名単価数量

これで、データを受け入れる器の準備が整いました。

Step 2:GAS(自動処理プログラム)の記述

いよいよ、自動化の心臓部となるGASを記述していきます。「プログラム」と聞くと難しく感じるかもしれませんが、今回はコードをコピー&ペーストするだけなのでご安心ください。

2-1. スクリプトエディタを開く

スプレッドシートのメニューからGASの編集画面(スクリプトエディタ)を開きます。
スクリプトエディタの詳しい開き方や基本的な使い方については、こちらの記事で詳しく解説しています。

2-2. コードを貼り付ける

元々書かれているfunction myFunction() { … }という文字をすべて消し、以下のコードをそのままコピーして貼り付けてください。

// ===============================================================
// ▼▼▼ あなたの設定に合わせて、以下の3箇所を変更してください ▼▼▼
// ===============================================================

// 1. CSVやExcelファイルが格納される「受信フォルダ」のID
const SOURCE_FOLDER_ID = 'ここに受信フォルダのIDを貼り付け';

// 2. 処理済みのファイルを移動させる「処理済みフォルダ」のID
const ARCHIVE_FOLDER_ID = 'ここに処理済みフォルダのIDを貼り付け';

// 3. データを取り込むシート名
const RAW_DATA_SHEET_NAME = '①生データ取込'; 

// ===============================================================
// ▲▲▲ 設定はここまで ▲▲▲
// ===============================================================


/**
 * メインの処理を実行する関数
 */
function main() {
  const sourceFolder = DriveApp.getFolderById(SOURCE_FOLDER_ID);
  const archiveFolder = DriveApp.getFolderById(ARCHIVE_FOLDER_ID);
  const files = sourceFolder.getFiles();

  // ログシートを取得(なければ作成)
  const logSheet = getOrCreateSheet('③処理ログ');
  if (logSheet.getLastRow() === 0) {
    logSheet.appendRow(['処理日時', 'ファイル名', 'ファイルID', '処理結果', 'メッセージ']);
  }

  if (!files.hasNext()) {
    console.log('新しいファイルはありませんでした。');
    return;
  }

  while (files.hasNext()) {
    const file = files.next();
    const fileName = file.getName();
    const fileId = file.getId();

    try {
      console.log(`処理開始: ${fileName}`);
      let data;
      
      // ファイルの種類によって処理を分岐
      if (fileName.endsWith('.csv')) {
        data = parseCsvFile(file);
      } else if (fileName.endsWith('.xlsx')) {
        data = parseXlsxFile(file);
      } else {
        console.log(`対象外のファイル形式です: ${fileName}`);
        continue; // 次のファイルへ
      }
      
      if (data && data.length > 1) { // ヘッダー行があるので1より大きいかで判定
        writeDataToSheet(data);
        logSheet.appendRow([new Date(), fileName, fileId, '成功', `${data.length -1}件のデータを取り込みました。`]);
      } else {
        throw new Error('読み込むデータがありませんでした。');
      }

      // ファイルを処理済みフォルダへ移動
      file.moveTo(archiveFolder);
      console.log(`処理完了: ${fileName} を処理済みフォルダへ移動しました。`);

    } catch (e) {
      console.error(`エラー発生: ${fileName} - ${e.message}`);
      logSheet.appendRow([new Date(), fileName, fileId, '失敗', e.message]);
      // エラーが発生したファイルは移動しない(必要に応じてエラー用フォルダへ移動するなどの処理を追加)
    }
  }
}

/**
 * CSVファイルを解析して二次元配列で返す
 * @param {File} file - Google Driveのファイルオブジェクト
 * @return {Array<Array<string>>} - 解析後のデータ
 */
function parseCsvFile(file) {
  // 文字コードをShift_JISと仮定して読み込み(日本の業務システムで多いため)
  const blob = file.getBlob().getDataAsString('Shift_JIS');
  return Utilities.parseCsv(blob);
}

/**
 * XLSX (Excel) ファイルを解析して二次元配列で返す
 * @param {File} file - Google Driveのファイルオブジェクト
 * @return {Array<Array<string>>} - 解析後のデータ
 */
function parseXlsxFile(file) {
  const tempSpreadsheet = SpreadsheetApp.openById(Drive.Files.copy({}, file.getId(), {convert: true}).id);
  try {
    const sheet = tempSpreadsheet.getSheets()[0];
    return sheet.getDataRange().getValues();
  } finally {
    Drive.Files.remove(tempSpreadsheet.getId()); // 一時ファイルを完全に削除
  }
}

/**
 * 指定されたシートにデータを追記する
 * @param {Array<Array<string>>} data - 書き込むデータ
 */
function writeDataToSheet(data) {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const targetSheet = spreadsheet.getSheetByName(RAW_DATA_SHEET_NAME);
  
  // ヘッダーを除いたデータを書き込む (CSV/Excelの1行目はヘッダーと仮定)
  const dataToWrite = data.slice(1); 
  
  if (dataToWrite.length > 0) {
    targetSheet.getRange(
      targetSheet.getLastRow() + 1,
      1,
      dataToWrite.length,
      dataToWrite[0].length
    ).setValues(dataToWrite);
  }
}

/**
 * 指定された名前のシートを取得、なければ作成する
 * @param {string} sheetName - シート名
 * @return {Sheet} - シートオブジェクト
 */
function getOrCreateSheet(sheetName) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getSheetByName(sheetName);
  if (!sheet) {
    sheet = ss.insertSheet(sheetName);
  }
  return sheet;
}

共有ドライブをご利用の場合は、一部設定の変更が必要です

もし、ファイルを格納するフォルダを共有ドライブに作成している場合は、Excelファイルを処理するためにコードの一部修正が必要です。
上記のコードの中からparseXlsxFileという部分を探し、以下のコードに丸ごと置き換えてください。

function parseXlsxFile(file) {
  var opt = {supportsAllDrives:true};
  var meta = Drive.Files.get(file.getId(), opt);
  var id = (meta.mimeType === 'application/vnd.google-apps.shortcut' &&
            meta.shortcutDetails && meta.shortcutDetails.targetId)
            ? meta.shortcutDetails.targetId : file.getId();
  var blob = DriveApp.getFileById(id).getBlob();

  var base = (meta.name || meta.title || file.getName()).replace(/[\\/:*?"<>|]/g, "_");
  var name = "TMP_" + Date.now() + "_" + base;

  var v3 = (typeof Drive.Files.create === "function");
  var tmp = v3
    ? Drive.Files.create({name:name, mimeType:"application/vnd.google-apps.spreadsheet"}, blob, opt)
    : Drive.Files.insert({title:name}, blob, {convert:true, supportsAllDrives:true});

  var ss = SpreadsheetApp.openById(tmp.id), values;
  try {
    values = ss.getSheets()[0].getDataRange().getValues();
  } finally {
    try { v3 ? Drive.Files.update({trashed:true}, tmp.id, null, opt) : Drive.Files.trash(tmp.id); } catch(e) {}
  }
  return values;
}

2-3. Googleの拡張サービスを有効にする

このコードはExcelファイルを扱うために、少し特殊な機能(Drive API)を使います。以下の手順で有効化してください。

  1. スクリプトエディタの左側のメニューから「サービス」の横にある「+」ボタンをクリックします。
  2. 「Drive API」を選択し、「追加」ボタンをクリックします。

2-4. あなたの環境に合わせて設定を変更する

貼り付けたコードの冒頭部分に、あなたの環境に合わせて変更が必要な箇所があります。

// 1. CSVやExcelファイルが格納される「受信フォルダ」のID
const SOURCE_FOLDER_ID = 'ここに受信フォルダのIDを貼り付け';

// 2. 処理済みのファイルを移動させる「処理済みフォルダ」のID
const ARCHIVE_FOLDER_ID = 'ここに処理済みフォルダのIDを貼り付け';

SOURCE_FOLDER_ID と ARCHIVE_FOLDER_ID には、それぞれStep 1-1で作成したGoogleドライブのフォルダのIDを設定します。

フォルダIDの確認方法:

Googleドライブで対象のフォルダを開き、ブラウザのアドレスバーに表示されるURLの末尾部分がIDです。
https://drive.google.com/drive/folders/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx の部分をコピーして貼り付けてください。

Step 3:スクリプトの実行と承認

設定が完了したら、一度手動で動かしてテストしてみましょう。

  1. 受信フォルダに、テスト用のCSVまたはExcelファイルをいくつかアップロードしておきます。
  2. GASの編集画面の上部にある「実行」ボタンをクリックします。
    初回実行時の「承認」については、こちらの記事を参考にしてください。

実行後、スプレッドシートの ①生データ取込 シートにデータが取り込まれ、受信フォルダにあったファイルが処理済みフォルダに移動していれば成功です!

Step 4:データクレンジング(整形)は関数で自動化!

生データの取り込みが自動化できたら、次はそのデータをキレイに整形します。これはGASを使わず、スプレッドシートの関数だけで実現できるため、より簡単です。

4-1. 基本的なデータクレンジング

ここでは、②整形済みデータシートに、①生データ取込シートのデータを参照して整形する関数を入力します。②整形済みデータシートのA2セルに、以下の関数をコピーして貼り付けてください。

=ARRAYFORMULA(
  IF(
    '①生データ取込'!A2:A="",,
    {
      TEXT('①生データ取込'!A2:A, "yyyy-mm-dd"),
      TRIM(SUBSTITUTE(SUBSTITUTE('①生データ取込'!B2:B, " ", " "), CHAR(160), " ")),
      TRIM(SUBSTITUTE(SUBSTITUTE('①生データ取込'!C2:C, " ", " "), CHAR(160), " ")),
      VALUE(ASC('①生データ取込'!D2:D)),
      VALUE(ASC('①生データ取込'!E2:E))
    }
  )
)

この関数の解説

この関数は、①生データ取込シートにデータが追加されるたびに、自動で整形処理を行い②整形済みデータシートに結果を表示してくれます。

  • ARRAYFORMULA: シート全体に数式を自動適用するための強力な関数です。
  • IF(…): もし元のデータが空欄なら、こちらも空欄にする、という処理です。
  • TEXT(…, “yyyy-mm-dd”): 日付形式を「YYYY-MM-DD」に統一します。
  • TRIM(…): 余分な半角・全角スペースを削除します。
  • ASC(…): 全角の英数字・カタカナを半角に変換します。
  • VALUE(…): 文字列として認識されている数字を、計算可能な数値に変換します。
  • SUBSTITUTE(…, “ ”, ” “): TRIMでは消せない「全角スペース」を「半角スペース」に置き換えます。
  • SUBSTITUTE(…, CHAR(160), ” “): 見た目ではわからない特殊なスペース(ノーブレークスペース)を「半角スペース」に置き換えます。これらを組み合わせることで、あらゆる種類の不要なスペースをキレイに除去できます。

4-2. さらに高度なデータクレンジング

今回は基本的な整形のみ紹介しましたが、以下のような、より複雑なデータクレンジングも可能です。それぞれ詳しいやり方を解説した記事がありますので、ぜひ参考にしてみてください。

Step 5:全ての処理を完全自動化する(トリガー設定)

最後に、この一連の流れを定期的に自動実行するように設定します。これを「トリガー」の設定と呼びます。
詳しい設定方法については、こちらの記事をご覧ください。

これで、設定した時間ごとにGASが自動で受信フォルダをチェックし、新しいファイルがあれば取り込みと整形を行う、という仕組みが完成しました!

3. 【発展編】さらに便利にするためのヒント

基本的な自動化は以上で完成ですが、さらに実用性を高めるためのアイデアをいくつかご紹介します。

ヒント1:取引先ごとに異なるフォーマットに対応する

取引先によってCSVの列の順番が違う、ということはよくあります。そんな時は、新たに「変換ルール」シートなどを作成し、取引先ごとの列の対応表を定義しておきます。
GASのコードを少し改造し、このシートの定義を元に列を並べ替える処理を追加することで、様々なフォーマットに柔軟に対応できます。

ヒント2:重複取り込みを防止する

③処理ログシートに記録されたファイルIDをチェックし、すでに取り込み済みのファイルであればスキップする処理を追加すると、同じファイルを誤って二度受信フォルダに入れてしまっても、データが重複するのを防げます。

ヒント3:エラー発生時にメールで通知する

GASには、Gmail経由でメールを送信する機能もあります。try…catchという構文とMailApp.sendEmail()という命令を組み合わせることで、「定義されていないファイルが置かれた」「読み込み中にエラーが発生した」といった場合に、担当者へ自動でメール通知を送ることも可能です。

まとめ:定型業務の自動化で、価値ある仕事に時間を使おう

今回は、GoogleスプレッドシートとGASを使って、日々の面倒なデータ取り込み・整形作業を自動化する方法をご紹介しました。

  • Googleドライブのフォルダとスプレッドシートを準備する
  • GASのコードをコピペして、フォルダIDを設定する
  • データクレンジングはARRAYFORMULAなどの関数で行う
  • トリガーを設定して、定期的に自動実行させる

最初は難しく感じるかもしれませんが、一度設定してしまえば、あとは自動で働き続けてくれる頼もしい相棒になります。

自動化によって生まれた貴重な時間を、分析や改善提案といった、あなたにしかできない付加価値の高い仕事にぜひ活用してください。

※Googleサービスは、Google LLC の商標であり、この記事はGoogleによって承認されたり、Google と提携したりするものではありません。