Volond Apps
222 subscribers
216 photos
28 videos
22 files
994 links
Программирование для души и от лени
Добро пожаловать! У нас есть отличное сообщество любителей Excel и VBA, Google Sheet и Google Apps Script, а также всех тех, кто готов работать с этим программным обеспечением. Присоединяйтесь к нам, чтобы задавать и от
Download Telegram
Уважаемый мной tanaike предложил хорошую идею
цитую "Подивіться, чи не можемо ми створити щось на кшталт "npm для Apps Script" ??"
База даних скриптов Google Apps в формате JSON
В переписке с Эндрю Робертс и вдохновленный еще одним ГУРУ Bruce Mcpherson с
его Apps Script shared library list ( 136 шт Карл!!! )
Воспользовавшись библиотекой IMPORTJSONAPI
Имеем обновляемую таблицу с следущими полями
libraryName,description,siteUrl,publishedDate,projectKey,tags,authors,description
Так же эта тема обсуждаеться тут
Есть объедененный Google Apps Script Library Database(239 шт)
Здесь живет PackageManager
А здесь Search Google Apps Script Libraries
А также У програмі Google Apps Script Slack WorkSpace є новий канал - proj_library_database
Известный французский ученый-компьютерщик Жак Шазарен опубликовал бесплатную электронную книгу, которая выглядит как идеальный ресурс и доступна на французском и английском языках.
Сортировка по украински
const array = ["Володимир","Іван","Богдан","Євген","Андрій"];
function uaSort(s1, s2) {
return s1.localeCompare(s2);
}
var sorted = array.sort(uaSort);
console.log(sorted);

#JS #snippet
This media is not supported in your browser
VIEW IN TELEGRAM
Активная вкладка листа Google Sheet отделяется цветом Используя расширение User JavaScript and CSS
Также можно использовать для кастомизации Stylish и его темы https://userstyles.org/
Код CSS
div.docs-sheet-tab:not(.docs-sheet-active-tab) {
background-color: #484848 !important;
}
ES6 и функциональное программирование
Как создать копию объекта
//ES6 и функциональное програмирование
//Задача: Есть обьект
//Создать копию обьекта
//Выполнить функцию над определеными свойствами обьекта
//Записать результат в Копию под Заданым именем
//И вернуть копию обьекта


const t=()=>{
const q=({id})=>++id
let cnf={name:1,id:1}
const f=(...arg)=>{
let newObj = { ...arg[0]};newObj[arg[1]]=arg[2](arg[0]);return newObj
}
const z=f(cnf,"ddd",q)
console.log(cnf)
console.log(z)
return z
//Профит
//[20-04-12 16:07:28:321 MSK] { name: 1, id: 1 }
//[20-04-12 16:07:28:323 MSK] { name: 1, id: 1, ddd: 2 }

#snippet #JS

}

Ссылки по теме:
ES6: Стрелочные функции
Копирование объектов в JavaScript
Стрелочные функции
arguments
Боже! Как давно я это искал
После "допиливания" надеюсь поможет мне навести порядок в моих скриптах

Получение отформатированных сценариев без комментариев в проекте с использованием скрипта Google Apps

P.S.
1. Хотя почему-то комментарии не удалил при тестовом прогоне хотя это даже к лучшему.
2. Стоит посмотреть как среагирует на среду разработки V.8
Телеграм Бот на Google Script
Telegram GAS BOT
Forwarded from Хабр
#snippet Unpivot a pivot table of any size

/**
* Unpivot a pivot table of any size.
*
* @param {A1:D30} data The pivot table.
* @param {1} fixColumns Number of columns, after which pivoted values begin. Default 1.
* @param {1} fixRows Number of rows (1 or 2), after which pivoted values begin. Default 1.
* @param {"city"} titlePivot The title of horizontal pivot values. Default "column".
* @param {"distance"[,...]} titleValue The title of pivot table values. Default "value".
* @return The unpivoted table
* @customfunction
*/
function unpivot(data,fixColumns,fixRows,titlePivot,titleValue) {
var fixColumns = fixColumns || 1; // how many columns are fixed
var fixRows = fixRows || 1; // how many rows are fixed
var titlePivot = titlePivot || 'column';
var titleValue = titleValue || 'value';
var ret=[],i,j,row,uniqueCols=1;

// we handle only 2 dimension arrays
if (!Array.isArray(data) || data.length < fixRows || !Array.isArray(data[0]) || data[0].length < fixColumns)
throw new Error('no data');
// we handle max 2 fixed rows
if (fixRows > 2)
throw new Error('max 2 fixed rows are allowed');

// fill empty cells in the first row with value set last in previous columns (for 2 fixed rows)
var tmp = '';
for (j=0;j<data[0].length;j++)
if (data[0][j] != '')
tmp = data[0][j];
else
data[0][j] = tmp;

// for 2 fixed rows calculate unique column number
if (fixRows == 2)
{
uniqueCols = 0;
tmp = {};
for (j=fixColumns;j<data[1].length;j++)
if (typeof tmp[ data[1][j] ] == 'undefined')
{
tmp[ data[1][j] ] = 1;
uniqueCols++;
}
}

// return first row: fix column titles + pivoted values column title + values column title(s)
row = [];
for (j=0;j<fixColumns;j++) row.push(fixRows == 2 ? data[0][j]||data[1][j] : data[0][j]); // for 2 fixed rows we try to find the title in row 1 and row 2
for (j=3;j<arguments.length;j++) row.push(arguments[j]);
ret.push(row);

// processing rows (skipping the fixed columns, then dedicating a new row for each pivoted value)
for (i=fixRows;i<data.length && data[i].length > 0 && data[i][0];i++)
{
row = [];
for (j=0;j<fixColumns && j<data[i].length;j++)
row.push(data[i][j]);
for (j=fixColumns;j<data[i].length;j+=uniqueCols)
ret.push(
row.concat([data[0][j]]) // the first row title value
.concat(data[i].slice(j,j+uniqueCols)) // pivoted values
);
}

return ret;
}
Класс для управления Properties
#snippet #GAS
/**
* Класс для управления Properties
* DocumentProperties or ScriptProperties or UserProperties
*
* Creates an instance of Props.
* @param {string} prop
* @memberof Props
* @constructor
* https://developers.google.com/apps-script/reference/properties
* @example
* const testProps=()=>{
* const scrProp=new Props("ScriptProperties");
* scrProp.set("v","1")
* concole.log(scrProp.get("v"))
* }
* @return {} Class Properties
*/
class Props {
constructor(prop) {
this[prop] = PropertiesService['get'+prop]();
this.type=prop
return this;
}

get(name) {
return this[this.type].getProperty(name);
}

getProperties(name) {
return this[this.type].getProperties();
}
type(prop) {
return this.type;
}
set(name, value) {
return this[this.type].setProperty(name, value);
}

forget(name) {
return this[this.type].deleteProperty(name);
}

getKeys() {
return this[this.type].getKeys();
}
has(callback,name) {
return this[this.type].getKeys().some(callback,element);
}

deleteAllProperties(){
this[this.type].deleteAllProperties();
}

setProperties(properties){
this[this.type].setProperties(properties);
}
setProperties(properties, deleteAllOthers){
this[this.type].setProperties(properties, deleteAllOthers);
}
}
Как получить имя запущенной функции в JavaScript?
#snippet
const es6=()=>{console.log(getMyName())}

function getMyName() {
var e = new Error('dummy');
var stack = e.stack
.split('\n')[2]
// " at functionName ( ..." => "functionName"
.replace(/^\s+at\s+(.+?)\s.+/g, '$1' );
return stack
}

Заполнить пустые ячейки данными из предыдущих непустых
#snippet
/**
* Заполнить пустые ячейки данными из предыдущих непустых
* тут формулами https://contributor.pw/post/fill-blank-cells-with-data-from-above-cell/
* но для одного столбца
* @param {Object} obj {arr,columnIndexStart,columnIndexStart}
* @param {Array[[]]} obj.arr - Индекс столбца с которого начинается преобразование
* @param {Number} obj.columnIndexStart - Индекс столбца с которого начинается преобразование
* @param {Number} obj.columnIndexEnd - Индекс столбца перед которого закончится преобразование(В выборку не попадает)
* @returns {Array} Преобразованный массив
* @example
* input Array
* let arr=[
* [1,2,3],
* [,,5],
* [8,9,10],
* [,11,12]
* ]
* return Array
* [ [ 1, 2, 3 ],
* [ 1, 2, 5 ],
* [ 8, 9, 10 ],
* [ 8, 11, 12 ]
* ]
*
*
*
*/
const fillData_ = ({ arr, columnIndexStart = 0, columnIndexEnd }) => {
/*
// tmp.forEach((item,j)=>{ //!!!!!forEach НЕ ВИДИТ undefined элементы

*/


let arrReptValue = arr[0].slice(columnIndexStart, columnIndexEnd)
arr.forEach((row, i, data) => {

let tmp = row.slice(columnIndexStart, columnIndexEnd)

for (j = 0; j < tmp.length; j++) {
if (isEmpty(tmp[j])) {
arr[i][j] = arrReptValue[j]
} else {
arrReptValue[j] = arr[i][j]
}
}
})
return arr
}
const isEmpty = (value) => {
return value === undefined || value === null || value === "";
}
Как удалить пустые столбцы в 2D Array в JS
#snippet #JS #GAS

var csvData = [["", "2", ""], ["", "3", ""], ["", "4", ""], ["1", "3", ""]],
columns = csvData.reduce(
(r, a) => (a.forEach((v, i) => r[i] = r[i] || v), r),
csvData[0].map(_ => false)
);

csvData = csvData.map(a => a.filter((_, i) => columns[i]));

console.log(csvData);
Текущее время смайликами
=join("";{VLOOKUP((HOUR(NOW())-mod(HOUR(NOW());10))/10;{SEQUENCE(10;1;0)\{"0️⃣";"1️⃣";"2️⃣";"3️⃣";"4️⃣";"5️⃣";"6️⃣";"7️⃣";"8️⃣";"9️⃣"}};2)&VLOOKUP(mod(HOUR(NOW());10);{SEQUENCE(10;1;0)\{"0️⃣";"1️⃣";"2️⃣";"3️⃣";"4️⃣";"5️⃣";"6️⃣";"7️⃣";"8️⃣";"9️⃣"}};2)\VLOOKUP((MINUTE(NOW())-mod(MINUTE(NOW());10))/10;{SEQUENCE(10;1;0)\{"0️⃣";"1️⃣";"2️⃣";"3️⃣";"4️⃣";"5️⃣";"6️⃣";"7️⃣";"8️⃣";"9️⃣"}};2)&VLOOKUP(mod(MINUTE(NOW());10);{SEQUENCE(10;1;0)\{"0️⃣";"1️⃣";"2️⃣";"3️⃣";"4️⃣";"5️⃣";"6️⃣";"7️⃣";"8️⃣";"9️⃣"}};2)\VLOOKUP((SECOND(NOW())-mod(SECOND(NOW());10))/10;{SEQUENCE(10;1;0)\{"0️⃣";"1️⃣";"2️⃣";"3️⃣";"4️⃣";"5️⃣";"6️⃣";"7️⃣";"8️⃣";"9️⃣"}};2)&VLOOKUP(mod(SECOND(NOW());10);{SEQUENCE(10;1;0)\{"0️⃣";"1️⃣";"2️⃣";"3️⃣";"4️⃣";"5️⃣";"6️⃣";"7️⃣";"8️⃣";"9️⃣"}};2)})