こんにちは。GAS勉強しめがねの谷口(@khtax16)です。
今回、完全に自分のための備忘録です。
↓ 状況の簡単なまとめ
- Googleスプレッドシートに売上データがある
- それをCSVにしたい
- そのCSVをマネーフォワードクラウド会計に仕訳として取り込みたい
というだけなんですが、よくわからないことに、
スプレッドシートを単純にCSV化すると日付データがえらいことになる
問題が発生しました。
当初想定してた解決法とはまったく違うのですが、一応解決はできたので、己のために試行錯誤も含めて残しておきます。
目次
まず店舗の売上がまとまったGoogleスプレッドシートをCSVにしよう!
まずGoogleスプレッドシートにこんな売上データがあったとします。
↓ (1) 売上データ用のシートを作成
サンプルなので超単純です。
- 1日の売上の合計
- うち現金
- うちクレジット
という中身のデータ。たとえばポイントとかもあったら、その分の行を足せばOK。
マネーフォワードクラウド会計でこうしたデータを取り込むには、「仕訳帳」などのインポート可能な形式にしてあげる必要があります。
↓ (2) 売上データを仕訳帳形式に変換するシートももうひとつ作成
この (2) のシートをCSVにして取り込みます。
データ作成から取り込むまでの流れをまとめると以下です。
- 売上データのシートを作成
- 別シートで「仕訳帳シート」を作成し、売上データを仕訳帳の形式に変換
- この「仕訳帳シート」をCSV化して取り込む
で、どうやってCSVにするのかですが、
人様に説明できるほどよくわかってない ので、GASの先輩であるもりパイセンのわかりやすいブログを貼っつけておきます。
『【GAS】スプレッドシートの特定シートからCSVファイルを作成・保存する』
(わかりやすい! ありがとうございます)
スプレッドシートの日付データをCSVにするとおかしな表示になってしまうのだけど???
私の場合、Googleドライブに「import」というインポート用のファイルを放り込むフォルダを作成しまして、それでCSV化まではなんとなくできました。
ただ、できたんですが、下の画像のように CSV上の日付の表示がどうもおかしくなる 問題が発生したんですね。
おわかりになりますでしょうか?
2020/03/01
↓
Sun Mar 01 2020 00:00:00 GMT+0900 (日本標準時)
と英語表示になり、しかも頼んでない日本標準時まで付け加えてくれるというにくい仕様。
ぜんぜんいらないよ。さわらないでいてくれればだいじょうぶ。
この表示のままマネーフォワードクラウド会計にとりこみますと、下の画像のようなエラーが出ます。
これ、二次元配列として取り込んだあと、日付の表示形式を変えればいいのかなと試行錯誤した(後述)んですが、ふと試してみたらめちゃくちゃ簡単な対策で解決したので、そちらを載せておきます。
MF会計の「仕訳帳」で取り込むために、GASでCSVを作成するときの簡単な対応方法 TO_TEXT関数
いやもう言葉にすると初歩的すぎて恥ずかしいレベルなんですが、
「日付を文字列にしとけばそのまま取り込める」
というのがその解決策。
2番目に貼った「仕訳帳」形式にするためのシートの日付(取引日)のセルでは、当初こんな感じで、売上データのシートからそのまま引っ張ってきました。
こうすると、B2セルは「日付」という認識を自動的にしてくれます。
しかし「日付」として認識されると、CSV化したときには上述のように「Sun Mar 01 2020 00:00:00 GMT+0900 (日本標準時)」という表示になってしまうのです。
なので、to_text 関数を使って強制的に文字列にしました。
to_text 関数とは、指定した数値をテキスト値に変換することができる関数です。
こうすることで、CSVにしたときに日付の表示をそのまま残しておくことができました!
(マネーフォワードクラウド会計にも問題なくインポートできました)
おわりに 一応試行錯誤を残しておきます
というわけで、結論としては
「日付を文字列にしとけば、スクリプトで書式指定とかしなくても簡単に取り込めるよ」
というごくあっけない話でした。
以下は完全に余談ですが、最後に試行錯誤したことを一応残しておきます(自分の備忘用)。
まず、日付を「yyyy/MM/dd」、つまり「2020/03/31」みたいな形式で表示するには、
Utilities.formatDate(日付データを入れた変数など, “Asia/Tokyo”, “yyyy/MM/dd”)
を使えばいいらしい、ということが調べてわかりました。
で、私がやってみたのが、
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('◯◯');
var values = sheet.getDataRange().getValues();
var date = [];
for (var i = 1; i < values.length; i++) {
date.push(Utilities.formatDate(values[i][1], "Asia/Tokyo", "yyyy/MM/dd"));
}
みたいな感じで、
- 一旦 getDataRange メソッドで、シートのすべてのデータ(values)を取得する
- 空の配列の変数「date」を定義しておく
- for文で、データ(values)のうち、日付データの列だけをくり返し取得させ、「yyyy/MM/dd」に変換し、同時に push メソッドで変数「date」に放り込んでいく
という処理をさせました。
すると、うまく「yyyy/MM/dd」形式のデータを date には入れられたんですが、入れたあとで、
「いや、別の配列に入れちゃったら意味なくない?」
と気づきます。
なので、最初の変数「values」のうち、日付データの列だけを置換しなければいけないんだろうと思ったんですが、この置換するメソッド(なんか響きがいかがわしいですね)が見つからずひとまず断念。
もうひとつの解として、一旦別の変数(date)に入れたあと、CSVにする直前で日付データの列だけ date に入れた配列で上書きできないかと思ったんですが、これもよくわからず断念(こちらはそもそもできるのかわからない)。
そのあと「文字列にしとけばいいんじゃね?」と上でご紹介したやりかたをふと思いつき、試してみたら圧倒的にこっちが簡単&シンプルだったのでこちらを採用しました。
うーん、配列の勉強はして、なんとなくわかったつもりになっていたけど、動かそうとするとほんとむずい。
スプレッドシートとして処理するほうが理解しやすいんですが、処理速度がだいぶ落ちるようなので、配列に慣れねばいかんですね。
がんばるぞい!
(GASを勉強した影響で、新しくつくるとき「Excelじゃなくスプレッドシートにしとくかな」って程度にはスプレッドシートが好きになってきました。もうちょいがんばりたい)
「役に立った!」「ニヤニヤした」など、もし「こいつ応援してやろうかな」という菩薩のごときお心が芽生えましたら、Amazonか楽天でお買い物するときに、下のリンクを踏んでからお買い物をしていただけますと私にジュース代なんぞが入ります。とても嬉しい。(なぜかメガネの検索画面が出てきますが無視してお好きなものを!)
▷Amazonでお買い物
▷楽天市場でお買い物