update 1904130940

This commit is contained in:
Val
2019-04-13 09:40:56 -04:00
parent 589ebfe105
commit fe919ee973
7 changed files with 1185 additions and 0 deletions

View File

@@ -0,0 +1,504 @@
/**
* Updated: 2019-04-12
*/
/** Descriptions **/
function RangeDescription(value, row, column, desc) {
/*
* arguments: [value[, row[, column[, desc]]]]
*
* value -> any type
* row -> integer (>0)
* column -> integer (>0)
* desc -> object containing full range description to override default settings
*
*/
var tag = 'range',
sheetName = '',
row = (row && typeof row == 'number') ? row : 1,
column = (column && typeof column == 'number') ? column : 1,
height = 1, width = 1,
mustMerge = true, // options: true, false, 'vertically', 'across'
wrapStrategy = SpreadsheetApp.WrapStrategy.CLIP,
numberFormat = '@',
background = '#efefef',
validation = null,
value = (value) ? value : '',
protection = false, // options: true, false, 'warning'
unprotected = false;
if (desc) {
if (isPropDefined(desc, 'tag')) tag = desc.tag;
if (desc.hasOwnProperty('sheetName') && typeof desc.sheetName == 'string') sheetName = desc.sheetName;
if (desc.hasOwnProperty('row') && typeof desc.row == 'number') row = desc.row;
if (desc.hasOwnProperty('column') && typeof desc.column == 'number') column = desc.column;
if (desc.hasOwnProperty('height') && typeof desc.height == 'number') height = desc.height;
if (desc.hasOwnProperty('width') && typeof desc.width == 'number') width = desc.width;
if (isPropDefined(desc, 'mustMerge')) mustMerge = desc.mustMerge;
if (isPropDefined(desc, 'wrapStrategy')) wrapStrategy = desc.wrapStrategy;
if (isPropDefined(desc, 'numberFormat')) numberFormat = desc.numberFormat;
if (isPropDefined(desc, 'background')) background = desc.background;
if (isPropDefined(desc, 'validation')) validation = desc.validation;
if (isPropDefined(desc, 'value')) value = desc.value;
if (isPropDefined(desc, 'protection')) protection = desc.protection;
if (isPropDefined(desc, 'unprotected')) unprotected = desc.unprotected;
}
function Border() {
var top = null, left = null, bottom = null, right = null,
vertical = null, horizontal = null,
color = null, style = null;
if (desc && isPropDefined(desc, 'border')) {
var border = desc.border;
if (isPropDefined(border, 'top')) top = border.top;
if (isPropDefined(border, 'left')) left = border.left;
if (isPropDefined(border, 'bottom')) bottom = border.bottom;
if (isPropDefined(border, 'right')) right = border.right;
if (isPropDefined(border, 'vertical')) vertical = border.vertical;
if (isPropDefined(border, 'horizontal')) horizontal = border.horizontal;
if (isPropDefined(border, 'color')) color = border.color;
if (isPropDefined(border, 'style')) style = border.style;
}
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
this.vertical = vertical;
this.horizontal = horizontal;
this.color = color;
this.style = style;
}
function Alignment() {
var vertical = 'middle', horizontal = 'center';
if (desc && isPropDefined(desc, 'alignment')) {
var alignment = desc.alignment;
if (isPropDefined(alignment, 'vertical')) vertical = alignment.vertical;
if (isPropDefined(alignment, 'horizontal')) horizontal = alignment.horizontal;
}
this.vertical = vertical;
this.horizontal = horizontal;
}
function Font() {
var family = 'Inconsolata',
color = null,
size = 10,
weight = 'normal',
style = 'normal',
line = 'none';
if (desc && isPropDefined(desc, 'font')) {
var font = desc.font;
if (isPropDefined(font, 'family')) family = font.family;
if (isPropDefined(font, 'color')) color = font.color;
if (isPropDefined(font, 'size')) size = font.size;
if (isPropDefined(font, 'weight')) weight = font.weight;
if (isPropDefined(font, 'style')) style = font.style;
if (isPropDefined(font, 'line')) line = font.line;
}
this.family = family;
this.color = color;
this.size = size;
this.weight = weight;
this.style = style;
this.line = line;
}
function Indent() {
var left = 0, right = 0;
if (desc && isPropDefined(desc, 'indent')) {
var indent = desc.indent;
if (isPropDefined(indent, 'left')) left = indent.left;
if (isPropDefined(indent, 'right')) right = indent.right;
}
this.left = left;
this.right = right;
}
// Meta
this.tag = tag;
// Range
this.sheetName = sheetName;
this.row = row;
this.column = column;
this.height = height;
this.width = width;
this.mustMerge = mustMerge;
// Appearance
this.wrapStrategy = wrapStrategy;
this.numberFormat = numberFormat;
this.background = background;
this.border = new Border;
this.alignment = new Alignment;
this.font = new Font;
this.indent = new Indent;
// Data
this.validation = validation;
this.value = value;
// Protection
this.protection = protection;
this.unprotected = unprotected;
}
function SheetDescription(height, width, sheetName) {
/*
* arguments: [height[, width[, sheetName]]]
*
* height -> integer (>0) || array of integers(>0) representing different row heights
* width -> integer (>0) || array of integers(>0) representing different column widths
* sheetName -> string
*
*/
if (!height) height = 1;
if (!width) width = 1;
var rowHeight = 21, columnWidth = 100;
if (Array.isArray(height)) {
if (height.every(function(n) { return typeof n == 'number'; })) {
rowHeight = height;
height = height.length;
}
}
if (Array.isArray(width)) {
if (width.every(function(n) { return typeof n == 'number'; })) {
columnWidth = width;
width = width.length;
}
}
this.sheetName = (sheetName && typeof sheetName == 'string') ? sheetName : '';
// Dimensions
this.height = height;
this.width = width;
this.rowHeight = rowHeight;
this.columnWidth = columnWidth;
this.frozenRows = 0;
this.frozenColumns = 0;
// Body
this.range = new RangeDescription(undefined, undefined, undefined, sheetName);
this.range.height = height;
this.range.width = width;
this.range.mustMerge = false;
this.hasGridlines = false;
// Protection
this.protection = false;
/* must be either false or object (may be ommitted or deleted)
* object: {
* warning = boolean
* unprotected = array of unprotected ranges
* }
*/
}
/** Builders **/
function buildRange(desc) {
/*
* arguments: desc
*
* desc -> object containing full range description
*
*/
var ss = SpreadsheetApp.getActive(),
sheet = (desc.sheetName) ? ss.getSheetByName(desc.sheetName) : ss.getActiveSheet(),
range = sheet.getRange(desc.row, desc.column, desc.height, desc.width),
cell = sheet.getRange(desc.row, desc.column);
var value = desc.value;
if (value && typeof value == 'string') {
var left = desc.indent.left,
right = desc.indent.right;
if (left || right) {
polyfills__String_repeat();
var lI = (left) ? ' '.repeat(left) : '',
rI = (right) ? ' '.repeat(right) : '';
value = lI + value + rI;
}
}
if (desc.mustMerge) {
switch (desc.mustMerge) {
case 'vertically': range.mergeVertically(); break;
case 'across': range.mergeAcross(); break;
default: range.merge();
}
} else range.breakApart();
range
.setBorder(
desc.border.top, desc.border.left,
desc.border.bottom, desc.border.right,
desc.border.vertical, desc.border.horizontal,
desc.border.color, desc.border.style
)
.setWrapStrategy(desc.wrapStrategy)
.setNumberFormat(desc.numberFormat)
.setHorizontalAlignment(desc.alignment.horizontal)
.setVerticalAlignment(desc.alignment.vertical)
.setBackground(desc.background)
.setFontColor(desc.font.color)
.setFontFamily(desc.font.family)
.setFontSize(desc.font.size)
.setFontLine(desc.font.line)
.setFontWeight(desc.font.weight)
.setFontStyle(desc.font.style)
.setDataValidation(desc.validation);
cell.setValue(value);
}
function buildRanges(descArr) {
/*
* arguments: descArr
*
* descArr -> array of objects containing full range descriptions
*
*/
if (Array.isArray(descArr)) {
for (var i = 0; i < descArr.length; i++) buildRange(descArr[i]);
}
}
function buildSheet(desc, rangeArr, isNew) {
/*
* arguments: desc[, rangeArr[, isNew]]
*
* desc -> object containing full sheet description
* rangeArr -> function to run after
* isNew -> boolean (false by default)
*/
if (!isNew) isNew = false;
var ss = SpreadsheetApp.getActive();
var sheet, index, unprotected1 = [], unprotected2 = [];
var sheetName = (desc.sheetName) ? desc.sheetName : undefined,
height = desc.height,
width = desc.width,
rowHeight = desc.rowHeight,
columnWidth = desc.columnWidth,
frozenRows = desc.frozenRows,
frozenColumns = desc.frozenColumns;
if (isNew) {
(sheetName) ? ss.insertSheet(sheetName) : ss.insertSheet();
sheet = ss.getActiveSheet();
} else {
sheet = (sheetName) ? ss.getSheetByName(sheetName) : ss.getActiveSheet();
}
index = sheet.getIndex() - 1;
shrinkSheet(sheet);
sheet.setHiddenGridlines(!desc.hasGridlines);
if (height > 1) sheet.insertRowsAfter(1, height - 1);
if (width > 1) sheet.insertColumnsAfter(1, width - 1);
if (Array.isArray(rowHeight)) {
for (var r = 0; r < rowHeight.length; r++) {
sheet.setRowHeight(r + 1, rowHeight[r]);
}
} else {
sheet.setRowHeights(1, height, rowHeight);
}
if (Array.isArray(columnWidth)) {
for (var c = 0; c < columnWidth.length; c++) {
sheet.setColumnWidth(c + 1, columnWidth[c]);
}
} else {
sheet.setColumnWidths(1, width, columnWidth);
}
if (frozenRows && frozenRows < height) sheet.setFrozenRows(frozenRows);
if (frozenColumns && frozenColumns < width) sheet.setFrozenColumns(frozenColumns);
if (rangeArr && Array.isArray(rangeArr)) {
for (var r = 0; r < rangeArr.length; r++) {
var rng = rangeArr[r];
if (sheetName) rng.sheetName = sheetName;
if (rng.unprotected) {
unprotected1.push(sheet.getRange(rng.row, rng.column, rng.height, rng.width));
if (unprotected1.length == 1) sheet.setCurrentCell(sheet.getRange(rng.row, rng.column));
}
}
buildRanges(rangeArr);
}
var protection = ss.getProtections(SpreadsheetApp.ProtectionType.SHEET)[index];
if (protection) protection.remove();
if (desc.hasOwnProperty('protection') && desc.protection) {
protection = sheet.protect();
if (desc.protection.hasOwnProperty('warning') && desc.protection.warning) {
protection.setWarningOnly(true);
} else {
var owner = ss.getOwner();
protection.addEditor(owner);
protection.removeEditors(protection.getEditors());
}
var hasUnprotected = isPropDefined(desc.protection, 'unprotected');
if (hasUnprotected || unprotected1.length) {
if (hasUnprotected && desc.protection.unprotected.length) {
unprotected2 = desc.protection.unprotected;
}
var unprotected = unprotected1.concat(unprotected2);
if (unprotected.length) protection.setUnprotectedRanges(unprotected);
}
}
}
function buildValidation(desc, showArrow, allowInvalid) {
/*
* arguments: desc[, showArrow[, allowInvalid]]
*
* desc -> array of description entities, where index 0 is purpose and others are arguments
* showArrow -> boolean, if true dropdown arrow will appear in dropdown type of validation
* allowInvalid -> boolean, if true will allow validation override
*
*/
if (desc) {
var validation = SpreadsheetApp.newDataValidation(),
purpose = desc[0];
(showArrow == undefined || showArrow == null) ? showArrow = true : showArrow = showArrow;
(allowInvalid == undefined) ? allowInvalid = false : allowInvalid = allowInvalid;
switch (purpose) {
// Dates
case 'date': validation.requireDate(); break;
case 'date =': validation = validation.requireDateEqualTo(date(desc[1])); break;
case 'date >': validation = validation.requireDateAfter(date(desc[1])); break;
case 'date >=': validation = validation.requireDateOnOrAfter(date(desc[1])); break;
case 'date <': validation = validation.requireDateBefore(date(desc[1])); break;
case 'date <=': validation = validation.requireDateOnOrBefore(date(desc[1])); break;
case 'date <=>': validation = validation.requireDateBetween(date(desc[1]), date(desc[2])); break;
case 'date <>': validation = validation.requireDateNotBetween(date(desc[1]), date(desc[2])); break;
// Numbers
case 'number =': validation = validation.requireNumberEqualTo(desc[1]); break;
case 'number !=': validation = validation.requireNumberNotEqualTo(desc[1]); break;
case 'number >': validation = validation.requireNumberGreaterThan(desc[1]); break;
case 'number >=': validation = validation.requireNumberGreaterThanOrEqualTo(desc[1]); break;
case 'number <': validation = validation.requireNumberLessThan(desc[1]); break;
case 'number <=': validation = validation.requireNumberLessThanOrEqualTo(desc[1]); break;
case 'number <=>': validation = validation.requireNumberBetween(desc[1], desc[2]); break;
case 'number <>': validation = validation.requireNumberNotBetween(desc[1], desc[2]); break;
// Text
case 'text =': validation = requireTextEqualTo(desc[1]); break;
case 'text +': validation = requireTextContallowInvalidns(desc[1]); break;
case 'text -': validation = requireTextDoesNotContallowInvalidn(desc[1]); break;
// Misc
case 'checkbox':
if (desc[1]) {
if (desc[2]) validation = validation.requireCheckbox(desc[1], desc[2]);
else validation = validation.requireCheckbox(desc[1]);
} else validation = validation.requireCheckbox();
break;
case 'formula': validation = validation.requireFormulaSatisfied(desc[1]); break;
case 'emallowInvalidl': validation = validation.requireTextIsEmallowInvalidl(); break;
case 'url': validation = validation.requireTextIsUrl(); break;
case 'list': validation = validation.requireValueInList(desc[1], showArrow); break;
case 'range': validation = validation.requireValueInRange(desc[1], showArrow); break;
}
validation = validation.setAllowInvalid(allowInvalid).build();
return validation;
}
}
/** Misc **/
function shrinkSheet(sheet) {
/*
* arguments: sheet
*
* sheet -> sheet object
*
*/
var u;
var maxRows = sheet.getMaxRows(),
maxColumns = sheet.getMaxColumns(),
frozenRows = sheet.getFrozenRows(),
frozenColumns = sheet.getFrozenColumns();
if (frozenRows) sheet.setFrozenRows(0);
if (frozenColumns) sheet.setFrozenColumns(0);
if (maxRows > 1) sheet.deleteRows(2, maxRows - 1);
if (maxColumns > 1) sheet.deleteColumns(2, maxColumns - 1);
desc = new SheetDescription;
sheet.setRowHeight(1, desc.rowHeight);
sheet.setColumnWidth(1, desc.columnWidth);
sheet.setHiddenGridlines(false);
buildRange(new RangeDescription(u, u, u, {
sheetName: sheet.getName(),
font: { color: new RangeDescription().background }
}));
}