๐app
GAS โฉ app
SheetMethods - mixin for Sheet objects.
/**
* app methods
* ------------------
* - spreadsheet
* - sheets
* - activeSheet
* - sheetByName()
* - deleteSheetByName()
* - rangeByName()
* - valueOfNamedRange()
* - valuesOfNamedRange(): 2D array
* - dataRangeValuesFromSheet(): 2D array
* - ui
* - alert()
*/
const app = {
// containers
sheet: {}, // for sheet-related functionality
range: {}, // for range-related functionality
// ----------------- spreadsheet -----------------
// ๐ธ app.spreadsheet
spreadsheet: SpreadsheetApp.getActiveSpreadsheet(),
// ----------------- sheet(s) -----------------
// ๐ธ app.sheets
get sheets() { return app.spreadsheet.getSheets() },
// ๐ธ app.activeSheet
get activeSheet() { return app.spreadsheet.getActiveSheet() },
// ๐ธ app.sheetByName()
sheetByName(name) {
const ss = app.spreadsheet;
let sheet = ss.getSheetByName(name);
// if no such sheet, append a new one.
if(sheet === null){
let i = ss.getNumSheets(); // ็ฎๅ็ๆๅนพ้
sheet = ss.insertSheet(name, i); // ๆๅ
ฅๆๅพ้ข (โญ๏ธ will activate automatically)
}
sheet.activate(); // โญ๏ธ activate before returning
sheet.__proto__ = app.sheet.prototype; // โญ๏ธ extend sheet
return sheet;
},
// ๐ธ app.deleteSheetByName()
deleteSheetByName(name) {
const ss = app.spreadsheet;
let sheet = ss.getSheetByName(name);
// if no such sheet, append a new one.
if(sheet === null){
Logger.log(`โ ๏ธ app.deleteSheetByName๏ผๆฒๆใ${name}ใ้ ้ขใ`);
return;
}
return ss.deleteSheet(sheet);
},
// ----------------- range -----------------
// ๐ธ app.rangeByName(name)
rangeByName(name) {
const range = app.spreadsheet.getRangeByName(name);
range.__proto__ = app.range.prototype;
return range;
},
// ----------------- value(s) -----------------
// ๐ธ app.valueOfNamedRange(name)
valueOfNamedRange(name) {
return app.rangeByName(name).getValue();
},
// ๐ธ app.valuesOfNamedRange(name): 2D array
valuesOfNamedRange(name) {
return app.rangeByName(name).getValues();
},
// ๐ธ app.dataRangeValuesFromSheet(sheetName)
// โญ๏ธ ๆณจๆ๏ผdata range ้ฝๆฏๅพ "A1" ้ๅง็ฎโ๏ธ
dataRangeValuesFromSheet(sheetName){
return app.sheetByName(sheetName).getDataRange().getValues();
},
// ----------------- UI -----------------
// ๐ธ app.ui
ui: SpreadsheetApp.getUi(),
// ๐ธ app.alert()
alert(prompt){ app.ui.alert(prompt) },
};
// ๐ธ app.color
app.color = {
gray: '#eeeeee',
lightRed: "#ffcccc",
lightGreen: '#ccffcc',
lightBlue: '#ccccff',
};
// ----------------------------- prototypes -------------------------------------
/**
* common mehtods for Sheet
*
* @example
* sheet.__proto__ = app.sheet.prototype
* sheet.setValues(data)
*/
app.sheet.prototype = {
// ๐ธ sheet.setValues(data)
setValues(data, row=1, col=1){
// โฌ๏ธ require: Array.prototype.isMatrix (getter)
if(!data.isMatrix)
throw new Error(`โ๏ธ app.sheet.prototype.setValues(): data ่ณๆๆ ผๅผๆๅ้ก๏ผ็กๆณๅฏซๅ
ฅ่ฉฆ็ฎ่กจโ๏ธ`);
// ่ณๆ่กจ็ใๅๆธใ่ใๆฌๆธใ
let rows = data.length;
let cols = data[0].length;
// ๅฏซๅ
ฅ้ ้ข
this
.getRange(row, col, rows, cols)
.setValues(data);
return this; // for chaining
},
// โโโโโโโโโโโโโโโโโโ
// โ getting Range โ
// โโโโโโโโโโโโโโโโโโ
// ๐ธ sheet.range()
range(row, col, rows, cols){
const rng = this.getRange(row, col, rows, cols);
Object.setPrototypeOf(rng, app.range.prototype); // extend range
return rng;
},
// ๐ธ sheet.rangeByRect(rect: RangeRect)
// require: RangeRect
rangeByRect(rect){
const range = this.getRange(...rect.toArray());
range.__proto__ = app.range.prototype; // extend range
return range;
},
// ๐ธ sheet.rangeListByRects(rects: [RangeRect])
// require: RangeRect
rangeListByRects(rects){
const alNotations = rects.map(rect => this.rangeByRect(rect).getA1Notation());
return this.getRangeList(alNotations);
},
// โโโโโโโโโโโโโโโโโโโโโโ
// โ formatting Ranges โ
// โโโโโโโโโโโโโโโโโโโโโโ
// ๐ธ sheet.appendConditionalFormatRule()
appendConditionalFormatRule(rule){
var rules = this.getConditionalFormatRules();
rules.push(rule);
this.setConditionalFormatRules(rules);
},
};
/**
* custom prototype for Range
*
* ### methods
*
* - row()
* - col()
* - rows()
* - cols()
* - info()
*
* - inset()
* - nthRow(i)
* - nthColumn(j)
* - firstNRows(n)
* - firstNColumns(n)
* - lastNthRow(i) <-------- #TODO
* - lastNthColumn(j)
* - lastNRows(n) <-------- #TODO
* - lastNColumns(n)
* - cell(i, j)
*
* @example
*
* range.__proto__ = app.range.prototype;
* range.alignCenter();
*/
app.range.prototype = {
// โโโโโโโโโโโโโโ
// โ info โ
// โโโโโโโโโโโโโโ
// GAS doesn't work well with gettersโ
// -------------------------------------
// get row(){ return this.getRow() }, // โ TypeError: this.getRow is not a function
// get col(){ return this.getColumn() },
// get rows(){ return this.numRows() },
// get cols(){ return this.numColumns() },
row(){ return this.getRow() },
col(){ return this.getColumn() },
rows(){ return this.getNumRows() },
cols(){ return this.getNumColumns() },
// ๐ธ range.toString()
// โญ ๆณจๆ๏ผ
// Range ๆ่ชๅทฑ็ toString() (returns "Range")๏ผๆไปฅๅฆๆ่ฆ็จ prototype ็็ๆฌ๏ผๅฟ
้ ็จไธๅ็จๅผ็ขผ๏ผ
// โข range.__proto__.toString.call(range)
// โข use `range.info()` instead
toString(){
return `Range at: (${this.row()}, ${this.col()}), dim: ${this.rows()} โจ ${this.cols()}`;
},
// ๐ธ range.info()
info(){
return `Range at: (${this.row()}, ${this.col()}), dim: ${this.rows()} โจ ${this.cols()}`;
},
// โโโโโโโโโโโ
// โ Range โ
// โโโโโโโโโโโ
// ๐ธ range.inset()
inset({top=0, bottom=0, left=0, right=0}={}){
let row = this.row() + top;
let col = this.col() + left;
let rows = this.rows() - top - bottom;
let cols = this.cols() - left - right;
if (row < 0) throw new Error(`โ app.range.prototype.inset: new range can't start from row = ${row}`);
if (col < 0) throw new Error(`โ app.range.prototype.inset: new range can't start from col = ${col}`);
if (rows < 1) throw new Error(`โ app.range.prototype.inset: new range can't have ${rows} rows`);
if (cols < 1) throw new Error(`โ app.range.prototype.inset: new range can't have ${cols} cols`);
let range = this.offset(row - this.row(), col - this.col(), rows, cols);
range.__proto__ = app.range.prototype;
return range;
},
// ๐ธ range.nthRow(i)
nthRow(i){
let row = this.row() + i - 1;
if (row < 0) throw new Error(`โ app.range.prototype.nthRow(): new range can't start from row = ${row}`);
let range = this.offset(row - this.row(), 0, 1, this.cols());
range.__proto__ = app.range.prototype;
return range;
},
// ๐ธ range.nthColumn(j)
nthColumn(j){
let col = this.col() + j - 1;
if (col < 0) throw new Error(`โ app.range.prototype.nthColumn(): new range can't start from col = ${col}`);
let range = this.offset(0, col - this.col(), this.rows(), 1);
range.__proto__ = app.range.prototype;
return range;
},
// ๐ธ range.firstNRows(n)
firstNRows(n){
let range = this.offset(0, 0, n, this.cols());
range.__proto__ = app.range.prototype;
return range;
},
// ๐ธ range.firstNColumns(n)
firstNColumns(n){
let range = this.offset(0, 0, this.rows(), n);
range.__proto__ = app.range.prototype;
return range;
},
// ๐ธ range.lastNthColumn(j)
lastNthColumn(j){
let range = this.offset(0, this.cols() - j, this.rows(), 1);
range.__proto__ = app.range.prototype;
return range;
},
// ๐ธ range.lastNColumns(n)
lastNColumns(n){
let range = this.offset(0, this.cols() - n, this.rows(), n);
range.__proto__ = app.range.prototype;
return range;
},
// ๐ธ range.cell(i, j)
cell(i, j){
let row = this.row() + i - 1;
let col = this.col() + j - 1;
if (row < 0) throw new Error(`โ app.range.prototype.cell(): new range can't start from row = ${row}`);
if (col < 0) throw new Error(`โ app.range.prototype.cell(): new range can't start from col = ${col}`);
let range = this.offset(row - this.row(), col - this.col(), 1, 1);
range.__proto__ = app.range.prototype;
return range;
},
// โโโโโโโโโโโโโโโ
// โ formatting โ
// โโโโโโโโโโโโโโโ
// ๐ธ range.alignCenter()
alignCenter(){
this
.setVerticalAlignment('middle')
.setHorizontalAlignment('center');
return this; // for chaining
},
};
๐ง ๆฝๅทฅไธญ
// ----------------- URL -----------------
/**
* app.fetch(url) -> JSON object
*/
app.fetch = function fetch(url){
// connect to API endpoint
var response = UrlFetchApp.fetch(url, {
// this setting means your code won't halt โญ๏ธ
// if the request results in an API error.
// Instead, the error response (HTTPResponse) is returned.
'muteHttpExceptions': true
});
// convert response to json object
var json = response.getContentText();
return JSON.parse(json);
};
// ----------------- log -----------------
/**
* app.log(msg)
*/
app.log = function(msg) {
if (!app._logs) app._logs = [];
app._logs.push(msg);
};
/**
* app.printLogs()
*/
app.printLogs = function(){
let sheet = app.sheetByName('็ณป็ตฑ่จๆฏ');
sheet.clear();
let values = app._logs.map(msg => [msg]);
let range = sheet.getRange(1,1,values.length, 1);
range.setValues(values);
};
Sheet โฉ
getDataRange() - from A1 to the last cell with value.
getLastRow() - index of the last row that has content.
Range โฉ
str.replaceWhitespaces() ๅธธ็จไพใๆทจๅใๅฒๅญๆ ผ็ๅผใ
2022.07.28๏ผๅฐ app.sheet/range.prototype, app.color ็ดๆฅๅ ๅ ฅ app ๆชใ
Archive
// ----------------- ๐ app.style -----------------
app.style = {};
app.style.border = {
solid : SpreadsheetApp.BorderStyle.SOLID,
solidMedium: SpreadsheetApp.BorderStyle.SOLID_MEDIUM,
solidThick : SpreadsheetApp.BorderStyle.SOLID_THICK,
dashed : SpreadsheetApp.BorderStyle.DASHED,
dotted : SpreadsheetApp.BorderStyle.DOTTED,
double : SpreadsheetApp.BorderStyle.DOUBLE
};
archived on 2022.07.28
// app.spreadsheet
// app.sheets
// app.activeSheet
// app.sheetByName(sheetName)
// app.deleteSheetByName(sheetName)
// app.rangeByName(rangeName)
// app.valueOfNamedRange(rangeName)
// app.valuesOfNamedRange(rangeName): 2D array
// app.dataRangeValuesFromSheet(sheetName): 2D array
// app.ui
// app.alert(prompt)
const app = {
// containers
sheet: {}, // for sheet-related functionality
range: {}, // for range-related functionality
// ----------------- spreadsheet -----------------
// ๐ธ app.spreadsheet
spreadsheet: SpreadsheetApp.getActiveSpreadsheet(),
// ----------------- sheet(s) -----------------
// ๐ธ app.sheets
get sheets() { return app.spreadsheet.getSheets() },
// ๐ธ app.activeSheet
get activeSheet() { return app.spreadsheet.getActiveSheet() },
// ๐ธ app.sheetByName()
sheetByName(name) {
const ss = app.spreadsheet;
let sheet = ss.getSheetByName(name);
// if no such sheet, append a new one.
if(sheet === null){
let i = ss.getNumSheets(); // ็ฎๅ็ๆๅนพ้
sheet = ss.insertSheet(name, i); // ๆๅ
ฅๆๅพ้ข (โญ๏ธ will activate automatically)
}
sheet.activate(); // โญ๏ธ activate before returning
sheet.__proto__ = app.sheet.prototype; // โญ๏ธ extend sheet
return sheet;
},
// ๐ธ app.deleteSheetByName()
deleteSheetByName(name) {
const ss = app.spreadsheet;
let sheet = ss.getSheetByName(name);
// if no such sheet, append a new one.
if(sheet === null){
Logger.log(`โ ๏ธ app.deleteSheetByName๏ผๆฒๆใ${name}ใ้ ้ขใ`);
return;
}
return ss.deleteSheet(sheet);
},
// ----------------- range -----------------
// ๐ธ app.rangeByName(name)
rangeByName(name) { return app.spreadsheet.getRangeByName(name) },
// ----------------- value(s) -----------------
// ๐ธ app.valueOfNamedRange(name)
valueOfNamedRange(name) {
return app.rangeByName(name).getValue();
},
// ๐ธ app.valuesOfNamedRange(name): 2D array
valuesOfNamedRange(name) {
return app.rangeByName(name).getValues();
},
// ๐ธ app.dataRangeValuesFromSheet(sheetName)
// โญ๏ธ ๆณจๆ๏ผdata range ้ฝๆฏๅพ "A1" ้ๅง็ฎโ๏ธ
dataRangeValuesFromSheet(sheetName){
return app.sheetByName(sheetName).getDataRange().getValues();
},
// ----------------- UI -----------------
// ๐ธ app.ui
ui: SpreadsheetApp.getUi(),
// ๐ธ app.alert()
alert(prompt){ app.ui.alert(prompt) },
};
Last updated