Google SpreadsheetにはCSVデータの取り込み機能が備わっていますが、1つ2つのCSVデータの取り込みならば標準で備わっている読み込みの機能を使用すれば良いでしょう。しかし、定期的にドライブにあるCSVのファイルを読み込むであったり、大量にあるCSVデータを一気に取り込むなどはスクリプトで作成しなければなりません。Google DriveにあるCSVファイルを取り込むためには、結構面倒な様々なAPIを利用しなければいけませんので、敷居は高いですが、既に多くの方が挑戦し、利用できるスクリプトがあります。
今回は、そんなスクリプトをベースにしつつ、自分にとって使いやすい形で少々いじったものを使ってみました。
今回想定しているケースですが以下の通りです。
//CSVインポートする為のメインの関数
function importFromCSV() {
//事前準備
var sheet = SpreadsheetApp.getActiveSpreadsheet();
//シート上に記述してあるCSVが入っているフォルダのIDを取得
var csvFolderkey = sheet.getSheetByName('startup').getRange('A11').getValue();
if(csvFolderkey == ""){
Browser.msgBox("CSVファイルの解凍先フォルダのIDが記入されていません");
return 0;
}
//特定のフォルダ内のCSVファイルを取得
var files = DriveApp.searchFiles("'"+csvFolderkey+"' in parents");
var csvFile = "";
while (files.hasNext()) {
//Shift_JISにてCSVをそのままで取り込む
csvFile = csvFile + files.next().getBlob().getDataAsString("Shift_JIS");
}
//CSVToArrayにて成形してシートに記述(書き込み先シートはtestという名称)
var csvData = CSVToArray(csvFile, ",");
var sheetman = sheet.getSheetByName('test');
//CSVToArrayで配列となったデータをsetValuesで一気に書き込み
for (var i = 0; i < csvData.length; i++) {
sheetman.getRange(i+1, 1, 1, csvData[i].length).setValues(new Array(csvData[i]));
}
Browser.msgBox("CSVデータのインポートが完了しました。");
}
//CSVデータを整形して配列で返す関数(特に変更していません)
function CSVToArray( strData, strDelimiter ){
// Check to see if the delimiter is defined. If not,
// then default to comma.
strDelimiter = (strDelimiter || ",");
// Create a regular expression to parse the CSV values.
var objPattern = new RegExp(
(
// Delimiters.
"(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
// Quoted fields.
"(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
// Standard fields.
"([^\"\\" + strDelimiter + "\\r\\n]*))"
),
"gi"
);
// Create an array to hold our data. Give the array
// a default empty first row.
var arrData = [[]];
// Create an array to hold our individual pattern
// matching groups.
var arrMatches = null;
// Keep looping over the regular expression matches
// until we can no longer find a match.
while (arrMatches = objPattern.exec( strData )){
// Get the delimiter that was found.
var strMatchedDelimiter = arrMatches[ 1 ];
// Check to see if the given delimiter has a length
// (is not the start of string) and if it matches
// field delimiter. If id does not, then we know
// that this delimiter is a row delimiter.
if (
strMatchedDelimiter.length &&
(strMatchedDelimiter != strDelimiter)
){
// Since we have reached a new row of data,
// add an empty row to our data array.
arrData.push( [] );
}
// Now that we have our delimiter out of the way,
// let's check to see which kind of value we
// captured (quoted or unquoted).
if (arrMatches[ 2 ]){
// We found a quoted value. When we capture
// this value, unescape any double quotes.
var strMatchedValue = arrMatches[ 2 ].replace(
new RegExp( "\"\"", "g" ),
"\""
);
} else {
// We found a non-quoted value.
var strMatchedValue = arrMatches[ 3 ];
}
// Now that we have our value string, let's add
// it to the data array.
arrData[ arrData.length - 1 ].push( strMatchedValue );
}
// Return the parsed data.
return( arrData );
}
Googleのサービスは基本的に「UTF-8」の文字コードを使うのが基本になっているようで、現実日本社会に於いて用いられている多くのCSVをそのままGoogleのチュートリアルの通りインポートすると確実に文字化けします。
ということで今回のような現実の日本の事務の世界では(そうでなくても、UTF-8以外が主流ですが)以下のようなコードのポイントがあります。
今回のコードは各CSVデータにカラム行があったとしてもベタで読み込み、ベタで書き込みをしています。そのため、本来ならば精査しなければならないカラム行の精査もしていないため、カラム行があってもそのまんま続けてデータが書き込まれてしまいます。カラム行がなければそれでも良いのですが、そうでない場合には、CSVデータの精査を行う・配列データを加工するルーチンを用意する必要性があります。