Volond Apps
221 subscribers
216 photos
28 videos
22 files
994 links
Программирование для души и от лени
Добро пожаловать! У нас есть отличное сообщество любителей Excel и VBA, Google Sheet и Google Apps Script, а также всех тех, кто готов работать с этим программным обеспечением. Присоединяйтесь к нам, чтобы задавать и от
Download Telegram
Forwarded from volond
https://xfanatical.com/blog/print-google-sheet-as-pdf-using-apps-script/
Возможные улучшения:
Экспорт листов как отделных таблиц Google или xlsx
Оправка через Gmail/Телеграмм/Вайбер
Генерация имени по шаблонным правилам


#GAS #SheetAPI #export #PDF
Объединить несколько PDF-файлов в один PDF-файл

Источник:

Задать вопрос


У меня такая же проблема, и я временно использую RestFul API для слияния PDF-файлов:
https://www.convertapi.com/pdf-to-merge

function merge() {
var folder = DriveApp.getFolderById('<ID FOLDER>'); // folder with files pdf
var files = folder.getFiles(); // get all files pdf

var formData = {};
var index = 0;
while(files.hasNext()) {
var file = files.next();
formData['Files[' + index + ']'] = file.getBlob();
index++;
}

var options = {
'method' : 'post',
'payload' : formData,
'muteHttpExceptions': true
};

var response = UrlFetchApp.fetch('https://v2.convertapi.com/pdf/to/merge?Secret=<YOUR SECRET>', options);

if(response.getResponseCode() == 200) {
var contentText = JSON.parse(response.getContentText());
var blob = Utilities.base64Decode(contentText.Files[0].FileData);
folder.createFile(Utilities.newBlob(blob, 'application/pdf', 'merge.pdf'));
}
}

Так что это больше, чем просто объединение данных из каждого файла. Фактически используемые данные для каждого файла «упакованы» с пометками и другим кодом (аналогично HTML и другим форматам документов). Фактически вам нужно декодировать каждый PDF-файл, объединить необходимые части, а затем перекодировать с новой «упаковкой». Для этого требуется практическое знание спецификаций и структуры PDF-файла, который можно бесплатно получить в Adobe здесь .

Я использовал эту информацию, чтобы написать сценарий, достаточный для моих нужд. Однако он не учитывает все возможности, поэтому, в частности, слияние любых документов, требующих PDF-1.4 и выше, потребует довольно большой работы.
https://pastiebin.com/601c57a966040
••••••••••
Обсудить:
Forwarded from DidacticСardsBot
Номер телефона

Источник:



Регулярное выражение для валидации номера телефона:


^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$

Ориентировано на российские мобильные + городские с кодом из 3 цифр (например, Москва).

Зеленый свет для:
+79261234567
89261234567
79261234567
+7 926 123 45 67
8(926)123-45-67
123-45-67
9261234567
79261234567
(495)1234567
(495) 123 45 67
89261234567
8-926-123-45-67
8 927 1234 234
8 927 12 12 888
8 927 12 555 12
8 927 123 8 123

••••••••••
Обсудить:
Forwarded from DidacticСardsBot
Отображение данных из GitHub API в Google Таблицах с помощью Apps Script и Oauth

Источник:



В этом посте показано, как подключить Google Sheet к API GitHub с помощью Oauth и Apps Script. Цель состоит в том, чтобы получить данные и информацию из GitHub и отобразить их в вашей таблице Google для дальнейшего анализа и визуализации.

Если вы управляете командой разработчиков или являетесь техническим менеджером проекта, то это может быть действительно полезным способом анализа и визуализации статистики кодирования вашей команды или проекта в сравнении с целями, такими как количество коммитов, языки, вовлеченные люди и т. Д. С течением времени. .
••••••••••
Обсудить:
function ins(){
var ss= SpreadsheetApp.getActive()
var sheet=ss.getActiveSheet()
var data=sheet.getDataRange().getValues()
for (i=data.length;i>1;i--){
console.log(i)
sheet.insertRowsAfter(i, 1);

}
}
function insAndCopy(){
var ss= SpreadsheetApp.getActive()
var sheet=ss.getActiveSheet()
var data=sheet.getDataRange().getValues()
for (i=data.length;i>1;i--){

var range = sheet.getRange(i,1,1,data[0].length);
sheet.insertRowsAfter(i, 1);
range.copyTo(sheet.getRange(i+1, 1, 1, data[0].length), {contentsOnly:false});
range.copyFormatToRange(sheet.getRange(i+1, 1, 1, data[0].length), {contentsOnly:false});

}
}
JavaScript-массивы: пересечение, разность и объединение в ES6

Источник:
Пересечение даст нам элементы, которые объединяют оба массива, в этом случае результат должен быть [1,5].

let intersection = arrA.filter(x => arrB.includes(x));


Разность будет выводить элементы из массива A, которых нет в массиве B. Результат будет [3,4].


let difference = arrA.filter(x => !arrB.includes(x));


В этом случае вы получите массив, содержащий все элементы arrA, которых нет в arrB, и наоборот, так что результат должен быть [2,3,4,6,7].


let difference = arrA.filter(x => !arrB.includes(x)).concat(arrB.filter(x => !arrA.includes(x)));


Объединение должно быть самым простым из них всех, в конце концов, результатом должны быть все элементы из A, все из B или оба, как это [1,2,3,4,5,6,7].

let union = [...arrA, ...arrB];


Но есть проблема в том, что мы получим дублированные элементы, так что теоретически это не объединение. Для этого мы можем использовать new Set():

let union = [...new Set([...arrA, ...arrB)];

••••••••••
Google Apps Script - новый день - новая функция
Источник:
Наряду с сервисом контента, теперь вы можете получить закодированную jSon версию скрипта любого модуля.


function doGet(e) {
return ContentService
.createTextOutput(JSON.stringify(mcpher.getMySource ( e )))
.setMimeType(ContentService.MimeType.JSON); ;
}

Код , который на это реагирует:


/**
* Returns a modules source code
* @param {parameters} e the argument to doGet(e). should have module parameter specified
* @param {scriptappinstance} sap an instance of scriptapp
* @return {object} The result.
*/
function getMySource(e) {
var results = {error : "missing module parameter"};
if (e.hasOwnProperty("parameter")) {
if (e.parameter.module) {
try {
var results =
{ code :
{ module : e.parameter.module, code : ScriptApp.getResource(e.parameter.module).getDataAsString() }
};
}
catch (err) {
var results = { error : "could not open module " + e.parameter.module} ;
}
}
}
return results;
}

function testGetSource() {
Logger.log( getMySource ( {parameter: { module: "cRest" }}));
}



Попробуйте и убедитесь. Итак, теперь вы можете получить исходный код любого модуля, создав doGet (), как указано выше, и скопировав код getMySource.

Я реализую это для сайтов Google и в других местах и опубликую здесь позже с результатами. Больше не нужно поддерживать исходный код в виде Gist и Apps Script!
••••••••••
Обсудить:
#GAS #ScriptApp
Forwarded from DidacticСardsBot
Function.caller

Источник:



Не стандартно
Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

function myFunc() {
if (myFunc.caller == null) {
return 'Эта функция была вызвана из верхнего уровня!';
} else {
return 'Эта функция была вызвана из ' + myFunc.caller;
}
}

••••••••••
Обсудить:
Object.assign VS Object Spread
Источник:

var assingDestruction(){
const obj = { foo: 1, bar: 1 };
console.log({ ...obj, baz: 1 })
}


Оператор распространения объекта {...obj}
похож на оператор Object.assign(), так какой из них следует использовать?
Оказывается, ответ немного более подробный, чем вы могли ожидать.


Краткий обзор Object Spread
Различия в сравнении Object.assign()



Операторы покоя / распространения объекта синтаксически аккуратны и предлагают преимущества в производительности Object.assign(). Если вы используете Node.js 8 или выше, попробуйте эти новые операторы и сделайте свой код более лаконичным.

••••••••••
Обсудить:
Краткий обзор Object Spread

Источник:



Основная идея оператора распространения объекта - создать новый простой объект,
используя
собственные свойства существующего объекта.
Таким образом
{...obj}
создается новый объект с теми же свойствами и значениями, что и obj.
Для
простых старых объектов JavaScript вы по сути создаете копию obj.


const obj = { foo: 'bar' };
const clone = { ...obj }; // `{ foo: 'bar' }`
obj.foo = 'baz';
clone.foo; // 'bar'

Например Object.assign(), оператор распространения объекта не копирует унаследованные свойства или информацию о классе.
Это
делает копирование символов ES6 .


class BaseClass {
foo() { return 1; }
}

class MyClass extends BaseClass {
bar() { return 2; }
}

const obj = new MyClass();
obj.baz = function() { return 3; };
obj[Symbol.for('test')] = 4;

// Does _not_ copy any properties from `MyClass` or `BaseClass`
const clone = { ...obj };

console.log(clone); // { baz: [Function], [Symbol(test)]: 4 }
console.log(clone.constructor.name); // Object
console.log(clone instanceof MyClass); // false

Вы также можете смешивать другие свойства с оператором распространения объекта.
Порядок имеет значение:
оператор распространения объекта перезапишет свойства, определенные до него, но не после него.


const obj = { a: 'a', b: 'b', c: 'c' };
{ a: 1, b: null, c: void 0, ...obj }; // { a: 'a', b: 'b', c: 'c' }
{ a: 1, b: null, ...obj, c: void 0 }; // { a: 'a', b: 'b', c: undefined }
{ a: 1, ...obj, b: null, c: void 0 }; // { a: 'a', b: null, c: undefined }
{ ...obj, a: 1, b: null, c: void 0 }; // { a: 1, b: null, c: undefined }
••••••••••
Обсудить:
Различия в сравнении Object.assign()

Источник:



Функция Object.assign() по сути взаимозаменяема с оператором распространения объекта для приведенных выше примеров.
Фактически, в
спецификации распространения объекта явно указано, что
{ ...obj } это эквивалентно Object.assign({}, obj).

const obj = { a: 'a', b: 'b', c: 'c' };
Object.assign({ a: 1, b: null, c: void 0 }, obj); // { a: 'a', b: 'b', c: 'c' }
Object.assign({ a: 1, b: null }, obj, { c: void 0 }); // { a: 'a', b: 'b', c: undefined }
Object.assign({ a: 1 }, obj, { b: null, c: void 0 }); // { a: 'a', b: null, c: undefined }
Object.assign({}, obj, { a: 1, b: null, c: void 0 }); // { a: 1, b: null, c: undefined }

Так почему бы вам использовать то или другое?

Одно из ключевых отличий заключается в том, что оператор распространения объекта
всегда возвращает вам POJO.
Object.assign()Функция изменяет свой первый параметр на месте:

class MyClass {
set val(v) {
console.log('Setter called', v);
return v;
}
}
const obj = new MyClass();

Object.assign(obj, { val: 42 }); // Prints "Setter called 42"

Другими словами, Object.assign()
модифицирует объект на месте и может запускать сеттеры ES6 .

Если вы предпочитаете использовать неизменяемые методы, явным победителем станет оператор распространения объекта.
С Object.assign(), вам нужно будет убедиться, что вы всегда передаете пустой объект {}в качестве первого аргумента.

Еще одно связанное отличие состоит в том,
что распространение
определяет новые свойства,
Object.assign()
устанавливает их .
Например, Object.assign()вызывает
сеттеры ,
которые определены Object.prototype, а оператор распространения - нет.

Object.defineProperty(Object.prototype, 'myProp', {
set: () => console.log('Setter called');
});

const obj = { myProp: 42 };

Object.assign({}, obj); // Prints "Setter called"

const newObj = { ..obj }; // Does **not** print "Setter called"

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

const obj = {};

Object.defineProperty(obj, 'myProp', {
set: () => console.log('Setter called');
});
Object.assign(obj, { myProp: 42 }); // Prints "Setter called"

А как насчет производительности?
Вот пара простых тестов. Похоже, что распространение объекта происходит быстрее, если вы передаете пустой объект в качестве первого параметра Object.assign(), но в остальном они взаимозаменяемы.

Вот эталон, использующийся Object.assign()с назначением на месте:

const Benchmark = require('benchmark');

const suite = new Benchmark.Suite;

const obj = { foo: 1, bar: 2 };

suite.
add('Object spread', function() {
({ baz: 3, ...obj });
}).
add('Object.assign()', function() {
Object.assign({ baz: 3 }, obj);
}).
on('cycle', function(event) {
console.log(String(event.target));
}).
on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
}).
run({ 'async': true });
В этом случае они похожи:

Object spread x 3,170,111 ops/sec +-1.50% (90 runs sampled)
Object.assign() x 3,290,165 ops/sec +-1.86% (88 runs sampled)
Fastest is Object.assign()

Однако, как только вы добавляете пустой параметр Object.assign()объекта, оператор распространения объекта будет работать быстрее:

suite.
add('Object spread', function() {
({ baz: 3, ...obj });
}).
add('Object.assign()', function() {
Object.assign({}, obj, { baz: 3 });
})
Вот результат:

Object spread x 3,065,831 ops/sec +-2.12% (85 runs sampled)
Object.assign() x 2,461,926 ops/sec +-1.52% (88 runs sampled)
Fastest is Object spread
••••••••••
Обсудить:
Задал вопрос в google
Удалить пустые элементы из массива в JavaScript
Прозрел
Хотя вопрос удаления пустых столбцов пока на повестке дня
Volond Apps
Вообще-то тема библиотек интересна! ‼️Хотелось бы обсудить, услышать мнение сообщества эту тему.‼️ 1. Да с одной стороны Google предложил такую функциональность, с другой сам же не советует как плохую практику 1.📛Предупреждение: скрипт, использующий библиотеку…
"exports IITF": {
"prefix": "expFn",
"body": [
"(function (global, factory) {",
" typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :",
" typeof define === 'function' && define.amd ? define(['exports'], factory) :",
" (factory((global.${1} = {})));",
"}(this, (function (exports) {'use strict';",
"/**",
" * A function that always returns `false`. Any passed in parameters are ignored.",
" *",
" * @func",
" * @memberOf R",
" * @since v0.9.0",
" * @category Function",
" * @sig * -> Boolean",
" * @param {*}",
" * @return {Boolean}",
" * @see R.T",
" * @example",
" *",
" * R.F(); //=> false",
" */",
"${2:example}",
"exports.${3} = ${4};",
"Object.defineProperty(exports, '__esModule', { value: true });",
"})));"
],
"description": "exports IITF"
}
This media is not supported in your browser
VIEW IN TELEGRAM
Мульти Выпадающий Список
Давно
хотел сделать
This media is not supported in your browser
VIEW IN TELEGRAM
Вариант с возможностью отсеивания уже выбранных позиций
This media is not supported in your browser
VIEW IN TELEGRAM
Следующие N флажков