確定申告の期限が近づいている。暗号通貨ホルダーの皆はもう申告を済ませた人がほとんどだろうが、ギリギリになって慌てている人も多いのではないだろうか。何を隠そう俺もその一人だ。
今回の申告のための損益計算にはCryptactというツールを使用するつもりでいる。
計算自体はどのツールでやっても同じになるはずなのだが、Cryptactは対応している取引所の取引履歴フォーマットが豊富なことが選んだ理由だ。

しかし残念ながら、昔使っていたBTCBOXの取引履歴フォーマットには対応していなかったので、Google Apps Script(GAS)を使ってカスタムファイルのフォーマットの形に整形することにした。


https://tax.cryptact.com/help/custom.html
Googleスプレッドシート上に貼り付けて編集する。ちなみにBTCBOXのファイルはBTC/JPYの取引のみだった。ソースは末尾に記載する。
参考にしたもの
Google Apps Scriptを実例交えて基礎からざっくり学ぶ Advent Calendar 2017
流れ
- BTCBOXのデータを二次元配列で読み込む
- データの中身を”整形したり”、”付け足したり”、”入れ替えたり”、して新しい二次元配列を作る
- データ書き出し
以上
BTCBOXのデータを二次元配列で読み込む
var inputsheet = SpreadsheetApp.getActive().getSheetByName(‘元データ’);
var values = inputsheet.getRange(“A1:I500”).getValues();
今回は読み込み範囲をとりあえず手動で指定してしまった。
データの中身を”整形したり”、”付け足したり”、”入れ替えたり”、して新しい二次元配列を作る
項目名はBTCBOXのフォーマットと全く違うので新しく付ける必要がある。
//項目名を先頭行に付ける
adjusted_data[0] = [‘Timestamp’,’Action’,’Source’,’Base’,’Volume’,’Price’,’Counter’,’Fee’,’FeeCcy’];
元のフォーマットは日付が分割されている(なぜ?)ので’YYYY/MM/DD HH:mm:ss’になるように結合する。シート上のデータの表示形式を”書式なしテキスト”にしておく。
function adjustdate(input_data,output_data) {
for(var i = 0; i<input_data.length -1; i++){
output_data[i+1] = [];
//半角スペースを挟む
output_data[i+1][0] = input_data[i+1][0] + ‘ ‘ + input_data[i+1][1];
}
return output_data;
}
あとは必要な部分は必要な項目を列に配置して、列の入れ換えをすれば完了。特に変なことはしていない(はず)。
データ書き出し
function outputdata(outputsheet,data){
outputsheet.getRange(1,1,data.length,data[1].length).setValues(data);
}
配列の長さで範囲を決めて書き出す。
ソース
以下ソース。汚いけど晒す。
function myFunction() {
//変換元データのシートを読み込む
var inputsheet = SpreadsheetApp.getActive().getSheetByName(‘元データ’);
//変換後の結果データを出力するシートを読み込む
var outputsheet = SpreadsheetApp.getActive().getSheetByName(‘結果データ’);//データを二次元配列にインプットする
var trade_data = inputdata(inputsheet);var adjusted_data = adjustdata(trade_data);
//データを出力する
outputdata(outputsheet,adjusted_data);
}function inputdata(inputsheet) {
/**
「元データ」からデータを読み込む
読み込み範囲は確認して直接指定
**/
var values = inputsheet.getRange(“A1:I578”).getValues();
//読み込んだ二次元配列を返す
return values;
}//データを整形する
function adjustdata(data) {
//整形後データを入れる二次元配列を定義する
var adjusted_data = [[]];
//項目名を先頭行に付ける
adjusted_data[0] = [‘Timestamp’,’Action’,’Source’,’Base’,’Volume’,’Price’,’Counter’,’Fee’,’FeeCcy’];//日付を合わせて1行目に配置
adjusted_data = adjustdate(data,adjusted_data);////任意の単語を列に配置
//Source
var source_name = ‘BTCBOX’;
var source_column = 2;
adjusted_data = inputword(source_name,source_column,data,adjusted_data);
//Base
var base_name = “BTC”;
var base_column = 3;
adjusted_data = inputword(base_name,base_column,data,adjusted_data);
//Counter
var counter_name = “JPY”;
var counter_column = 6;
adjusted_data = inputword(counter_name,counter_column,data,adjusted_data);///元データを列の順番を入れ替えて結果データに入れる。
///出力列、入力列、元データ、結果データを指定して結果データを返す
//Action
adjusted_data = sort(2,1,data,adjusted_data);
//Volume
adjusted_data = sort(4,4,data,adjusted_data);
//Price
adjusted_data = sort(3,5,data,adjusted_data);
//Fee
adjusted_data = sort(6,7,data,adjusted_data);
//FeeCcy
adjusted_data = sort(7,8,data,adjusted_data);return adjusted_data;
}function sort(input_column_num,output_column_num,input_data,output_data) {
//input_dataの任意の列要素をoutput_dataの任意の列要素に入れる。
//1行目が項目欄のため入力開始行を2行目からとし、それに伴い入力回数を減らした。
for(var i = 0; i<input_data.length-1; i++){
output_data[i+1][output_column_num] = input_data[i+1][input_column_num];
}
return output_data;
}//任意の単語を指定の列に入力する
function inputword(word,column_num,input_data,output_data){
for(var i = 0; i<input_data.length-1; i++){
output_data[i+1][column_num] = word;
}
return output_data;
}//二次元配列データをシートに出力する
function outputdata(outputsheet,data){
outputsheet.getRange(1,1,data.length,data[1].length).setValues(data);
Logger.log(data);
}/**
BTCBOXとcryptactでは日付の形式が異なっているので整形を行う。
日付の文字列を結合する。
変換前の書式’YYYY/MM/DD’ ‘HH:mm:ss’
変換後の書式’YYYY/MM/DD HH:mm:ss’
データ例’2016/12/23 12:23:34′
あらかじめ元データの表示形式を「書式なしテキスト」に変更しておく。
**/
function adjustdate(input_data,output_data) {//1行目が項目欄のため入力開始行を2行目からとし、それに伴い入力回数を減らした。
for(var i = 0; i<input_data.length -1; i++){
output_data[i+1] = [];
//半角スペースを挟む
output_data[i+1][0] = input_data[i+1][0] + ‘ ‘ + input_data[i+1][1];
}
return output_data;
}