Volond Apps
222 subscribers
216 photos
28 videos
22 files
994 links
Программирование для души и от лени
Добро пожаловать! У нас есть отличное сообщество любителей Excel и VBA, Google Sheet и Google Apps Script, а также всех тех, кто готов работать с этим программным обеспечением. Присоединяйтесь к нам, чтобы задавать и от
Download Telegram
/**
* Как разбить массив на заданные куски
* splitEvery(3, [1, 2, 3, 4, 5, 6, 7]); //=> [[1, 2, 3], [4, 5, 6], [7]]
* Number → [a] → [[a]]
* @param {*} n
* @param {*} row
* @returns
*/
function splitEvery(n, row) {
return (row) => {
var result = [];
var idx = 0;
while (idx < row.length) {
result.push(row.slice(idx, idx += n));
}
return result
}
}

#snippet
Как разбить 2D масив на заданные куски
/**
* Как разбить 2D масив на заданные куски
* Number → [a] → [[a],[b]]
* @param {*} n
* @param {*} range
* @returns
*/
function splitEveryMap(n, range) {
const sp = splitEvery(n)
return range.map(sp).flat(1)
}
#snippet #JS
Вытягиваем код Вашего проекта в таблицу

/**
* Returns an array of function names and their code
* In the current project
* Arrow functions do not fall into this array
* ....................................................
* Возвращает массив имен функций и их кода
* В текущем проекте
* Функции-стрелки в этот массив не попадают
*
* @return {Array}
* @customfunction
*/
function getFunction(){
const nameFn=Object.keys(this)
return (nameFn.map(el=>[el,this[el]]))
}

#snippet #GAS
О сортировке замолвите слово
function compareNumbers(a, b) {
if (a === b) return 0;
if (a > b) return 1;
/* else */
return -1;
}

function compareNumbers1(a, b) {
if (+a === +b) return 0;
if (+a > +b) return 1;
/* else */
return -1;
}
let nums = ["7", "3", "1", "5", "8", "11", "6", "4", "2"];
nums.sort()
console.log(nums)
nums.sort(compareNumbers);
console.log(nums);
/* 〕[
'1', '11', '2',
'3', '4', '5',
'6', '7', '8'
]
*/
nums.sort(compareNumbers1);
console.log(nums);
/*
[
'1', '2', '3',
'4', '5', '6',
'7', '8', '11'
]
*/
Собираем диапазоны в один,
по именам листов указанных в диапазоне
/**
* Собираем диапазоны в один,
* по именам листов указанных в диапазоне
* @param {String} sheetNames NameSheet
* @returns {Array}
* @customfunction
*/
function UNION(sheetNames){
const getSheetDataRange=(name)=>{
const data=SpreadsheetApp.
getActiveSpreadsheet().
getSheetByName(name[0]).
getDataRange().
getValues();
data.shift();
return data
}
const data=sheetNames.map(getSheetDataRange).flat(1)
return data
}
#customformula
/**
* https://t.me/google_spreadsheets_chat/112103
* Собираем несколько диапазонов в один,
* замена =INDIRECT() в массиве.
* Диапазоны могут быть разной размерности.
* @param {string} ranges NameSheet!A1Notation range
* @returns {Array}
* @customfunction
*/
function indirects(ranges){
var ss = SpreadsheetApp.getActiveSpreadsheet();

if(ranges.map){
return [].concat.apply([], ranges.map(function(i){
return ss.getRange(i).getValues()}));}
else {
return ss.getRange(ranges).getValues(); }
}
#customformula
/**
* v8 работает только в ES6
* Собираем несколько диапазонов в один,
* замена =INDIRECT() в массиве.
* Диапазоны могут быть разной размерности.
* @param {String} ranges NameSheet!A1Notation range
* @returns {Array}
* @customfunction
* @example
*/
function UNIONRANGES(ranges){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var getValues=(A1Not)=>ss.getRange(ranges).getValues()

return ranges.map?ranges.map(getValues).flat(1):getValues(ranges)

}
#customformula
Настраиваем книжную ориентацию в Google Slides
#GoogleSlides
Объединяем свойства объектов JS
const a={a:1,b:2}
const c={c:3}
const d={b:3,e:4}

// Создаст новый объект g
const g=Object.assign(a,d,c)
console.log(g)//{ a: 1, b: 3, e: 4, c: 3 }
console.log(a)//{ a: 1, b: 3, e: 4, c: 3 }
😱 "а" МУТИРОВАЛ (изменился)
‼️ А так правильно ‼️
 const g=Object.assign({},a,d,c)
const f={...a,...d,...c}
console.log(f) //{ a: 1, b: 3, e: 4, c: 3 }
console.log(a)
// :) { a: 1, b: 2 }
#JS
Получаем id файла Google
**
* Получаем id файла Google
* из ссылки(URL) скопированной из
* адресной строки браузера
*
* @param {*} url
* @returns
*/
function getIdFromUrl(url){ return url.match(/[-\w]{25,}/);}
#GAS #JS
Forwarded from volond
Деструктуризация разделения строки по разделителю
// Деструктуризация разделения строки по разделителю
//вариант а
const key='a^b'
const ssID_src = key.split("^")[0];
const sheet_src = key.split("^")[1];
//вариант б
const [хssID_src,sheet_src]=key.split("^")
console.log(хssID_src)
console.log(sheet_src)
#GAS #JS
/**
* Получаем лист с активной книги по имени листа
* Get a sheet from the active book by sheet name
* @param {*} {sheetName}
* @returns {SpreadsheetApp.sheet}
*/
const getSheetFromActiveBookBySheetName=({sheetName})=>{
const ss = SpreadsheetApp.getActive();
return ss.getSheetByName(sheetName);
}
#GAS #JS
/**
* Перестановка столбцов в масиве array
* согласно
* правил переданных в масиве cols
* @param {*} array
* @param {*} cols
*
*/
const filtered = (array, cols) => [].concat(...[array.map(row => [].concat(...cols.map(y =>
row[y - 1])))]);
/*
Object.assign

Object.assign — это фантастическое новое дополнение, которое очень помогает сохранять вещи иммутабельными
(или, по крайней мере, делать только эфемерные мутации к промежуточным объектам).
Но знаете ли вы, что их можно устанавливать и для значений массивов в том числе?


const original = [0,1,2,3];
const copy = Object.assign([], original, { 2: 42 }); // [0,1,42,3]

console.log(original);
// [ 0, 1, 2, 3 ]

console.log(copy);
// [ 0, 1, 42, 3 ]
Деструктуризация
Парочка простых примеров:
// можно деструктурировать массивы
const [a, b] = [1,2]; // a = 1, b = 2

// можно деструктурировать ключи в объектах
const { a } = { a: 3 }; // a = 3

// даже параметры функций
function foo({ a }) {
console.log(a);
}

foo({ a: 4 }); // выведет 4
Переименование
Одна из фишек деструктуризации, о которой вы, возможно, не знаете — это возможность переименования по ходу дела. Если вы использовали ES6 модули, вы можете знать, как работает оператор импорта при переименовании импортированных объектов и, возможно, задавались вопросом, почему так не получается делать при деструктуризации. Ну, там на самом деле просто чуток другой синтаксис:

// простое переименование для избежания коллизий или просто для красоты.
const first = 5;
const { first: second } = { first: 3 };

console.log(second); // выведет 3

// переименовать для другого API с использованием расширенного использования присваивания
function verifyUser({ userId: id }) {
return User.update({ id, verified: true });
}
В сочетании с параметрами по умолчанию
Параметры по умолчанию позволяют вам указывать значения параметрам, которые не были переданы пользователем, но что если вы собирались деструктуризовать их, когда они приходят? Не проблема… У нас есть левая сторона присваивания (a.k.a. lvalue) с параметрами по умолчанию, так что вы можете использовать деструктуризацию и здесь!

function defaults({ a, b } = { a: 1, b: 2 }) {
console.log('a', a);
console.log('b', b);
}

defaults();
// a 1
// b 2

defaults({ a: 42, b: 32 });
// a 42
// b 32

// Будьте осторожны с множественными параметрами!
// Вся правая сторона будет заменена вашими аргументами.
defaults({ a: 87 });
// a 87
// b undefined

У самой деструктуризации также есть параметры по умолчанию, так что мы можем смешать оба варианта!


function defaults({ a = 1, b = 2 } = {}) {
console.log('a', a);
console.log('b', b);
}

defaults();
// a 1
// b 2

defaults({ a: 42, b: 32 });
// a 42
// b 32

// множественные параметры? Нет проблем, просто укажите то, что вы хотите изменить
defaults({ a: 87 });
// a 87
// b 2
Сравниваем значение с сегодня
function myFunction() {
var ss=SpreadsheetApp.getActive().getSheets()[0]
var d = new Date();
const dr=ss.getRange(1,1,ss.getDataRange().getLastRow(),ss.getDataRange().getLastColumn()).getValues()
const t=dr.filter(el=> Utilities.formatDate(el[0], "GMT+1", "dd/MM/yyyy")===Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy"))
console.log(t)

}
Как Получить границы непрерывных диапазонов в масиве?
const isNext=(el,i,arr)=>arr[i+1]!==(el+1)
var inp= [2,3,4,6,7,9,11,12,13]
var res=[]
const returnDiapz=(arr)=>{
var s=arr.splice(0,arr.findIndex(isNext)+1)
res.push([Math.min(...s),Math.max(...s)])
return arr.length?returnDiapz(arr):res;
}