本サイトはアフィリエイト広告(A8.net/もしもアフィリエイト/アクセストレード等)を利用しています
スプシをCSV出力してドライブ保存するGAS|会計ソフト連携の定番
📂 スプレッドシート

スプシをCSV出力してドライブ保存するGAS|会計ソフト連携の定番

📅 ⏱ 読了 約8分 ✍️ 凛

💡 本記事には広告(アフィリエイトリンク)が含まれる場合があります。

こんにちは、夜勤明けのコーヒー片手にコードを書くのが好きな看護師の凛です。副業を始めてから、毎月スプレッドシートを開いて「ファイル→ダウンロード→CSV→会計ソフトにアップロード」と繰り返す作業が、地味に憂うつでした。ちょっとした手間でも、積み重なるとつい後回しにしてしまう。確定申告のたびにその溜め込みが牙をむくのも、毎年のことでした。だからGASで自動化して、この月イチの面倒ごとを丸ごと手放すことにしたんです。

スプシをCSV出力してドライブ保存するGAS|会計ソフト連携の定番

スプシのCSV書き出しって、そもそも自動化できるの?

できます。しかも、思っているよりずっと短いコードで済みます。

スプレッドシートの中身をGASで読み取って、CSVの文字列に組み立てて、Google Driveにファイルとして保存する。この3ステップを1つの関数にまとめておけば、あとはトリガーに載せるだけで「月初に気づいたらCSVが出力されている」状態になります。私自身、副業と育児と夜勤を掛け持ちしていると、月1回の作業ですら忘れたり後回しにしたりしてしまうので、そもそも「やり忘れる余地」をなくすのが狙いでした。取引先に売上明細をCSVで送る、スプシは触らせずCSVだけ共有する、といった場面でもそのまま使えます。

まずは動くコードを置きます。

GASコード(コピペで動きます)

function exportToCsv() {
  const SHEET_ID = 'ここにスプレッドシートID';
  const FOLDER_ID = 'ここに保存先フォルダID';

  const sheet = SpreadsheetApp.openById(SHEET_ID).getActiveSheet();
  const data = sheet.getDataRange().getValues();

  // CSV形式に変換(カンマ・改行・ダブルクォートを含むセルはクォートで囲む)
  const csv = data.map(row =>
    row.map(cell => {
      const s = String(cell).replace(/"/g, '""');
      return /[,\n"]/.test(s) ? `"${s}"` : s;
    }).join(',')
  ).join('\r\n'); // Windowsでも文字化けしないよう\r\nを使用

  // BOM付きUTF-8で保存(Excelで開いたときの文字化け防止)
  const filename = `export_${Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMMdd')}.csv`;
  const blob = Utilities.newBlob('\uFEFF' + csv, 'text/csv', filename);

  DriveApp.getFolderById(FOLDER_ID).createFile(blob);
  console.log('CSV出力完了: ' + filename);
}

書き換える箇所は2つだけです。スプレッドシートIDは、スプシのURL https://docs.google.com/spreadsheets/d/【ここ】/edit の真ん中の部分。フォルダIDは、Google Driveでフォルダを開いたときのURL https://drive.google.com/drive/folders/【ここ】 の末尾です。この2つを差し込めば、もう動きます。

なぜ改行やBOMをわざわざ指定するの?

コードを見ると、改行に \r\n、先頭に \uFEFF と、見慣れない指定が入っています。ここが実は、CSVで文字化けや崩れを防ぐいちばんの勘所です。私が実際にハマったところなので、3つに分けて深掘りします。

改行コードは \r\n に固定する

最初は \n で書いていたのですが、Windowsで開いたCSVが「全部1行になる」問題が起きました。取引先はWindows環境のことが多いので、\r\n に統一するのが安全です。

Mac・Linuxでファイルを作ると改行コードは \n になります。GASで意図的に \r\n を指定しておくと、どの環境でも正しく改行されます。夜勤明けの朦朧とした頭でExcelを開いたら、全部が1行にびろーんと並んでいた——あのときの絶望感は、いま思い出しても辛い。最初から \r\n にしておいてください。

ファイル名に日付を入れて上書きを防ぐ

export_20260601.csv のように日付をファイル名に含めると、毎回別ファイルとして保存されます。月次の履歴が自動で積み上がるので、「先月のCSVどこ行った?」がなくなる。

上書き防止だけでなく、年間の変化を追うときにも効きます。「6月と7月のデータ、どう変わったんだっけ」という場面でも、フォルダを開けば過去分がずらっと並んでいるので、確定申告の時期に慌てて探す手間が消えます。

BOM(\uFEFF)を先頭に付ける

BOMなしのUTF-8だと、Excelで開いたときに日本語が文字化けします。\uFEFF を先頭に付けるだけで直るので、必ず入れてください。会計ソフト側でBOMがあると読み込めない場合は外してもOKですが、まずはBOMありで試すのがおすすめです。

副業の売上記録や経費メモは日本語が入ることが多いです。文字化けしたCSVを会計ソフトに取り込んでしまい、結局全部手入力し直し——そんな最悪の事態を防ぐためにも、BOMは絶対に入れておきましょう。

動かしてみたけど、うまくいかない場合は?

私が実際に踏んだ落とし穴を、症状別に並べておきます。だいたいはこのどれかです。

ヘッダー行が含まれない

getDataRange().getValues() は1行目からの範囲を取得します。「なぜかヘッダーが出ない」ときは、1行目が空だったり、シートの表示範囲がズレていたりします。sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues() と明示的に指定すると確実です。

権限エラーが出る

初回実行時に「このアプリはGoogleによって確認されていません」という警告が出ます。「詳細」→「(安全ではないページ)に移動」で進めてください。自分のGoogleアカウントで作ったスクリプトなので安全です。

これは「自分で書いたスクリプトをGoogleが公式審査していないだけ」で、危険なわけではありません。知人に見せると「えっ怪しいページじゃないの?」と心配されることもありますが、自作スクリプトでは必ず出るものだと思ってください。

保存先フォルダが見つからない

フォルダIDが間違っているか、スクリプトのGoogleアカウントとフォルダのアカウントが違うと起きます。フォルダURLからIDをコピーし直すと直ることが多いです。

エラーは出ないのに「処理完了」と言われてファイルが見当たらない、というときは、別のフォルダに保存されている可能性があります。Google Driveの検索で export_ で始まるファイル名を探してみてください。

Excelで開くと日付が数値になる

GASでセルの値を取ると、日付型のデータが 1900-01-01 からの通し番号(シリアル値)で返ってくる場合があります。Utilities.formatDate(cell, 'Asia/Tokyo', 'yyyy/MM/dd') で文字列に変換してからCSVに書き込むと、Excelでもちゃんと日付として表示されます。

特定のシートだけ出したいときは?

複数シートのあるスプシで、狙ったシートだけCSVにしたいことはよくあります。getActiveSheet() の代わりに getSheetByName('シート名') を使えば、名前で指定して取得できます。

// 特定のシート名を指定して取得する例
const sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName('売上記録');

私は「売上記録」「経費メモ」「取引先一覧」の3シートを1つのスプシで回していて、確定申告用には「売上記録」と「経費メモ」だけをCSVにしています。必要なシートだけ出すことで、会計ソフトへの取り込みがぐっとスムーズになります。

毎月ほったらかしで出すには?

手動実行だけでなく、月次トリガーを設定すれば完全に手を離せます。

  1. GASエディタ左の時計アイコン「トリガー」をクリック
  2. 「トリガーを追加」
  3. 実行する関数:exportToCsv
  4. イベントのソース:「時間主導型」
  5. 時間ベースのトリガーのタイプ:「月ベースのタイマー」
  6. 日付:「1」(毎月1日)
  7. 時間帯:「午前6時〜7時」
  8. 「保存」

これで毎月1日の朝6時にCSVが自動生成されます。月初に会計ソフトを開いたときには、もうCSVが準備できている状態です。

CSVをそのままメールで送りたいなら

Driveに保存するだけでなく、できあがったCSVを指定アドレスに自動送信することもできます。取引先へ毎月売上明細を送る必要がある場合に便利です。

function exportAndEmailCsv() {
  const SHEET_ID = 'ここにスプレッドシートID';
  const TO_EMAIL = 'partner@example.com';

  const sheet = SpreadsheetApp.openById(SHEET_ID).getActiveSheet();
  const data = sheet.getDataRange().getValues();

  const csv = data.map(row =>
    row.map(cell => {
      const s = String(cell).replace(/"/g, '""');
      return /[,\n"]/.test(s) ? `"${s}"` : s;
    }).join(',')
  ).join('\r\n');

  const filename = `report_${Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMM')}.csv`;
  const blob = Utilities.newBlob('\uFEFF' + csv, 'text/csv', filename);

  GmailApp.sendEmail(
    TO_EMAIL,
    `月次レポート ${Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy年M月')}`,
    '月次レポートをお送りします。添付ファイルをご確認ください。',
    { attachments: [blob] }
  );

  console.log('メール送信完了: ' + filename);
}

月末のトリガーと組み合わせれば「月末にCSVをメール自動送信」が完成します。私は確定申告用に、税理士さんへの月次報告をこの方法で自動化しています。

私の実際の運用フロー

看護師の副業で確定申告が必要になってから、この自動化をずっと使い続けています。

  1. 毎月1日 6:00:GASが自動でCSVを出力(「売上_202605.csv」のような名前でDriveに保存)
  2. 確定申告の時期:専用フォルダを開いて、1〜12月のCSVを会計ソフトにまとめてインポート
  3. 所要時間:年間の集計作業が約2時間から30分に短縮

「CSV書き出しの作業」が月1個減るだけでも、副業を続ける心理的な負担はかなり軽くなります。夜勤の翌朝、ぐったりした状態でコーヒーを一杯飲んでパソコンを開いたら、もうCSVが出来上がっている。その光景が当たり前になったとき、「自動化して本当によかった」と心から思いました。副業を続けられるかどうかは、いかに自分の負担を減らせるかにかかっている気がします。

最後に

コードは丸ごとコピペして、SHEET_IDFOLDER_ID だけ書き換えれば動きます。押さえどころは、改行を \r\n に、先頭にBOM、ファイル名に日付。この3つさえ外さなければ、Excelでも会計ソフトでも素直に開けるCSVになります。

まずは手動実行で1回動かして、狙ったフォルダにファイルができるのを確かめてから、トリガーを設定する流れで進めてみてください。

関連記事(あわせて読みたい)


この記事を書いた人:凛

2児のママで現役ナース。夜勤明けの細切れ時間を副業GASに投じ、月5〜8万円の副収入を継続中。「看護師でもコードは書ける」を合言葉に、家事育児とプログラミングを両立する等身大の情報を発信しています。掲載コードは構文・API仕様・ロジックを確認して載せていますが、お使いの環境に合わせて調整してください。