【Unity】スプレッドシート(GoogleAppsScript)でJson出力&受け取り側のC#クラス作成機能を作ってみた
マスターデータはExcelで管理してVBA使って自動化することが多いのですが
家ではExcelライセンスがないので、スプレッドシートでできないかなあと
GoogleAppsScript(GAS)を学ぶついでに挑戦しました。
をGASで作ってみました。
GASは全然触ったことないですが、書籍やサイトを見ながら挑戦。
こういうのが出来ます
スプレッドシート
出力されるjsonデータ
{ "datas": [ { "id": 0, "sort_id": 2, "resource_name": "skin_00" }, { "id": 1, "sort_id": 3, "resource_name": "skin_01" }, { "id": 2, "sort_id": 1, "resource_name": "skin_02" }, { "id": 3, "sort_id": 5, "resource_name": "skin_03" }, { "id": 4, "sort_id": 6, "resource_name": "skin_04" }, { "id": 5, "sort_id": 0, "resource_name": "skin_05" } ] }
生成されるクラス
[System.Serializable] public class MasterData_SkinData{ [System.Serializable] public class Data{ public int id; // ユニークID public int sort_id; // 表示順 public string resource_name; // リソース名 } public Data[] datas; }
使い方
上記のスプレッドシートを参考にシートを作成し、
ツール→スクリプトエディタを押下。スクリプトエディタに下記ソースコードを貼り付ければ各種出力メニューが追加されます。
※出力メニューを表示するために一度スプレッドシートを更新(F5押下)が必要になります。
// Open時 function onOpen(){ // メニューに登録 SpreadsheetApp.getUi().createMenu('ExportMasterData') .addItem('マスターデータ出力(単体)', 'exportJson') .addItem('受け取り側クラス生成(単体)', 'createCS') .addItem('マスターデータ出力(全シート)', 'exportJsonAll') .addItem('受け取り側クラス生成(全シート)', 'createCSAll') .addToUi() } // -------------------------------------------------------------------- // 受け取り側CS作成 // -------------------------------------------------------------------- // CSファイル作成 function _createCS(sheet){ var folderId = getCurrentFolderId() var data = getData(sheet) var csText = createCSText(sheet.getName(), data[0], data[1], data[3]) var fileName = "MasterData_" + toCamelCace(sheet.getName()) + ".cs" deleteFile(fileName, folderId ) createFile(csText, fileName, folderId ) } // CSファイル作成(カレントシートのみ) function createCS(){ _createCS( SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()) } // CSファイル作成(全シート分) function createCSAll(){ var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets() for( var i = 0; i < sheets.length; i++ ){ _createCS(sheets[i]) } } // クラステキスト生成 function createCSText(sheetName = "",valiableTypes, valiableNames, comments ){ var csText = "" csText += "[System.Serializable]\n" // sheet名をクラス名にする var className = toCamelCace(sheetName) csText += "public class MasterData_" + className + "{\n" csText += "\t[System.Serializable]\n" csText += "\tpublic class Data{\n" // 変数追加 for( var i = 0; i < valiableNames.length; i++ ){ csText += "\t\tpublic " + valiableTypes[i] + " " + valiableNames[i] + ";\t\t// " + comments[i] + "\n" } csText += "\t}\n" csText += "\tpublic Data[] datas;\n" csText += "}" return csText } // -------------------------------------------------------------------- // Json出力 // -------------------------------------------------------------------- // Json出力 function _exportJson(sheet){ var folderId = getCurrentFolderId() var data = getData(sheet) var jsonText = parseJson(data[0], data[1], data[2]) var fileName = sheet.getName() + ".json" deleteFile(fileName, folderId ) createFile(jsonText, fileName, folderId ) } // Json出力 function exportJson() { _exportJson(SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()) } // Json出力 function exportJsonAll() { var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets() for( var i = 0; i < sheets.length; i++ ){ var sheet = sheets[i] _exportJson(sheet) } } // jsonパース function parseJson(valiableTypes, valiableNames, datas){ var jsonText = "{\"datas\":[" for( var i = 0; i < datas.length; i++ ){ jsonText += "{" for( var j = 0; j < valiableNames.length; j++ ){ var valiableName = valiableNames[j] if( valiableName.indexOf("ignore") !== -1 || valiableName === ""){ continue } jsonText += "\"" + valiableName + "\":" var data = datas[i][j] var valiableType = valiableTypes[j] if( valiableType == "string" ){ jsonText += "\"" + data + "\"" }else{ jsonText += data } if( valiableNames.length == j + 1){ continue } if( valiableNames[j+1].indexOf("ignore") !== -1 || valiableNames[j+1] === ""){ continue } if( j < valiableNames.length - 1){ jsonText += "," } } jsonText += "}" if( i < datas.length - 1){ jsonText += "," } jsonText += "" } jsonText += "]}" return jsonText } // -------------------------------------------------------------------- // Utility // -------------------------------------------------------------------- // 各データ取得 // 返却値 array[0]:変数型配列 // 返却値 array[1]:変数名配列 // 返却値 array[2]:データ2次元配列 // 返却値 array[3]:コメント配列 function getData(sheet){ // データ型取得 var startRow = 1 var startColumn = 2 var values = sheet.getSheetValues(startRow, startColumn, 1, sheet.getLastColumn() - (startColumn - 1)) var valiableTypes = Array.prototype.concat.apply([], values) // 変数名取得 startRow = 2 startColumn = 2 values = sheet.getSheetValues(startRow, startColumn, 1, sheet.getLastColumn() - (startColumn - 1)) var valiableNames = Array.prototype.concat.apply([], values) // コメント取得 startRow = 3 startColumn = 2 values = sheet.getSheetValues(startRow, startColumn, 1, sheet.getLastColumn() - (startColumn - 1)) var comments = Array.prototype.concat.apply([], values) // データ取得 startRow = 4 startColumn = 2 var datas = sheet.getSheetValues(startRow, startColumn, sheet.getLastRow() - (startRow - 1 ), sheet.getLastColumn() - (startColumn - 1)) return [valiableTypes, valiableNames, datas, comments] } // CamelCase変換 function toCamelCace(str){ str = str.charAt(0).toUpperCase() + str.slice(1) return str.replace(/_./g, function(s) { return s.charAt(1).toUpperCase() }) } // ファイル削除 function deleteFile(fileName, folderId){ var folder = DriveApp.getFolderById(folderId) var files = folder.getFiles() while( files.hasNext()){ var file = files.next() if( file.getName().indexOf(fileName) != -1){ DriveApp.getFolderById(folderId).removeFile(file) } } } // ファイル生成 function createFile(jsonData, fileName, folderId){ var contentType = "text/plain" var charSet = "UTF-8" var blob = Utilities.newBlob("", contentType, fileName).setDataFromString(jsonData, charSet) DriveApp.getFolderById(folderId).createFile(blob) } // 同階層のフォルダID取得 function getCurrentFolderId(){ var spreadsheet = SpreadsheetApp.getActiveSpreadsheet() var spreadsheetId = spreadsheet.getId(); var parentFolder = DriveApp.getFileById(spreadsheetId).getParents() var folderId = parentFolder.next().getId(); return folderId }