Сообщество - MS, Libreoffice & Google docs

MS, Libreoffice & Google docs

762 поста 14 934 подписчика

Популярные теги в сообществе:

67

Типы клавиатур в чат ботах

Сегодня познакомимся с существующими клавиатурами в ботах и тем, как их подключить и настроить.


Всего есть два типа клавиатур:

- ReplyKeyboardMarkup;

- InlineKeyboardMarkup.


ReplyKeyboardMarkup используется в случаях, когда вы хотите получить от пользователя конкретный ответ, предоставляя ему возможность не печатать ручками, а выбрать из предлагаемых вариантов. Иными словами, это заготовки текстовых сообщений. Расположены кнопки под полем ввода сообщения

InlineKeyboardMarkup - это более продвинутый вариант кнопок, за которыми скрыт дополнительный функционал. В данном случае кнопки прикрепляются непосредственно к сообщению от бота

В зависимости от выбранной кнопки могут последовать те или иные действия. Эту логику мы задаем в скрипте для каждой кнопки.

В приведенном примере мы хотим записать пользователя на маникюр и предлагаем ему определиться с днем (в качестве примера приведены только два варианта, но это можно закастомить).


После выбора того или иного дня бот внесет инфу в ГТ, а именно: дату, имя пользователя и ид чата.

Запись через чат имеет следующий вид

Здесь мы выбрали кнопку Сегодня и получили ответ от бота.

В ГТ при этом появилась строчка

Подключение и настройка


Каждая клава (инлайн-клавиатур может быть сколько угодно) записана в соответствующую переменную:


var INLINE_Days =

{

"inline_keyboard": [

[{"text": "Сегодня", "callback_data": "today"}],

[{"text": "Завтра", "callback_data": "tomorrow"}],

],

"resize_keyboard": true

}


var KEYBOARD =

{

"keyboard": [

["Записаться", "Отменить запись"]

],

"resize_keyboard": true

}


Обратите внимание, что синтаксис для инлайн (INLINE_Days) и обычной (KEYBOARD) клавиатур различается.

Клавиатурам можно добавить дополнительные свойства, мы использовали только resize_keyboard со значением true. Их не так много и они есть в документации телеграма.


Далее в коде обращаемся к клавам по имени переменной.


С ReplyKeyboardMarkup все достаточно просто. Она добавляется при первом прогоне скрипта, когда вы отправляете в чат команду /start, например.


Нам нужна функция, которая отправит в чат клавиатуру. Функция та же, что и при отправке сообщения ботом send(), за двумя исключениями:


- у функции появляется дополнительный параметр - keyboard;

- у объекта payload появляется доп свойство - reply_markup : JSON.stringify(keyboard)


Ниже скрипт функции отправки обычной клавы в чат:


function send_key (msg, chat_id, api, keyboard)

{

var payload = {

'method': 'sendMessage',

'chat_id': String(chat_id),

'text': msg,

'parse_mode': 'HTML',

reply_markup : JSON.stringify(keyboard)

}

var data = {

"method": "post",

"payload": payload

}

UrlFetchApp.fetch('https://api.telegram.org/bot' + api + '/', data);

}


Вызов функции осуществляется из тела функции doPost(e) одной строкой:


send_key("Поехали", chat_id, API_TOKEN, KEYBOARD)


Здесь всё.


Что касается инлайн-клавиатур.

Отправка клавиатуры наступает при определенном условии. Если пользователь отправил в чат слово “Записаться”, то отправляем ему нашу инлайн-клаву:


if (text == "Записаться") {

Demo.send_key("Выберите день", chat_id, API_TOKEN, INLINE_Days)

}


Переменная text  содержит текст сообщения, которое мы и проверяем на соответствие.


Результатом выполнения функции send_key будет сообщение от бота Выберите день и кнопки под ним.


Далее нужно предусмотреть алгоритм обработки нажатия этих кнопок.

Если мы кликаем на какую-либо из кнопок (“Сегодня” или "Завтра"), то добавляем новую строку в ГТ и отправляем сообщение в чат, что запись создана.


if (data == "today")

{

let date = Demo.getNewDate(0);

let ind = get_ind(chat_id);

Clients.getRange(ind,1).setValue(user_name);

Clients.getRange(ind,2).setValue(chat_id);

Clients.getRange(ind,3).setValue(date);

Demo.send("Вы успешно записались. "+"Дата визита: "+ date, chat_id, API_TOKEN);

}


Ниже скрипт полностью (не забываем, что значения глобальных переменных у вас будут свои):


// Объявляем все нужные нам переменные. Док важно открывать именно по ID, а не брать активный док, т.к. запуск кода будет производить бот

const API_TOKEN = "1946675042:AAHg1HTHe42GhR9EEt0EdbR94j1G8pDcTWE";

const DOC = SpreadsheetApp.openById("1ALJLtLdt-LT7GEF4hawIizVeJXFnoPZCsC0pw7kcp70");

const Clients = DOC.getSheetByName("Clients");

const Calendar = DOC.getSheetByName("Calendar");


function api_connector ()

{

var App_link = "https://script.google.com/macros/s/AKfycbx9izXW_GcUvg-OlXuP9...";

UrlFetchApp.fetch("https://api.telegram.org/bot"+API_TOKEN+"/setWebHook?url="+App_link);

}


function doPost(e)

{

var update = JSON.parse(e.postData.contents);

if (update.hasOwnProperty('message'))

{

var msg = update.message;

var chat_id = msg.chat.id;

var text = msg.text;

var msg_array = msg.text.split(" ");

var date = (msg.date/86400)+25569.125;

var user = msg.from.username;

if (text == "Записаться") {

Demo.send_key("Выберите день", chat_id, API_TOKEN, INLINE_Days)

}

if (text == "Отменить запись") {

let ind = get_ind(chat_id);

Clients.getRange(ind,1,1,3).deleteCells(SpreadsheetApp.Dimension.ROWS);

Demo.send("Запись отменена", chat_id, API_TOKEN)

}

}

if (update.hasOwnProperty('callback_query'))

{

var data = update.callback_query.data;

var text = update.callback_query.message.text;

var id = update.callback_query.message.message_id;

var chat_id = update.callback_query.message.chat.id;

var user_name = update.callback_query.from.username;

if (data == "today")

{

let date = Demo.getNewDate(0);

let ind = get_ind(chat_id);

Clients.getRange(ind,1).setValue(user_name);

Clients.getRange(ind,2).setValue(chat_id);

Clients.getRange(ind,3).setValue(date);

Demo.send("Вы успешно записались. "+"Дата визита: "+ date, chat_id, API_TOKEN);

}

if (data == "tomorrow") {

let date = Demo.getNewDate(1);

let ind = get_ind(chat_id);

Clients.getRange(ind,1).setValue(user_name);

Clients.getRange(ind,2).setValue(chat_id);

Clients.getRange(ind,3).setValue(date);

Demo.send("Вы успешно записались. "+"Дата визита: "+ date, chat_id, API_TOKEN);

}

}

}


Отдельно ниже представлена доп функция, которая проверяет наличие ид в ГТ. Если ид уже есть в таблице, мы обновляем данные у строки с этим ид. В противном случае создаем новую строку.


function get_ind() {

let chat_id = 311157431;

let arr = Clients.getRange(1,2,Clients.getLastRow()).getValues()

arr = arr.flat()

let ind = arr.indexOf(chat_id)

if (ind > -1) {

ind = ind+1;

} else {

ind = Clients.getLastRow()+1;

}

return ind

}



ID для подключения библиотеки Demo: 1JkXEW_zfhr6v0TKsvU_ZbygNLpXEczxZcC46fMF_ffk-noMk8UKcMitz


Здесь также заметим, что клик по кнопке в инлайн клавиатуре отправляет боту JSON со свойством callback_query. Это значит, что нам нужны дополнительные переменные, в которые мы запишем значения из этого JSON пакета.


Это краткая вводная в мир клавиатур. Скоро будут посты про простые сервисы, куда будут добавлены и доработаны те же клавиатуры и доп функции.

Показать полностью 4
471

Еще 5 важных хитростей при работе с POWER POINT

Эх, на целый месяц меня выбила рутина с Пикабушки. Но я тут и готов поделиться еще несколькими простыми, но гиперкрутыми фишками, «интуитивно понятной для домохозяек» программы – Power Point.

Начнем!

1. Работа с векторами.

В прошлом посте я коротко упомянул базовый инструмент при работе с векторными фигурами – «Изменение узлов». Но этим дело не ограничивается. Самая частая операция с векторами, которую проделываю я – Объединение фигур.

Давайте на секунду представим, что в PP нет базовой фигуры «Месяц». А она нам ну пипец как нужна. Что делать? Искать на стоках? Рисовать в Иллюстраторе? Не, мы пойдем простым путём – нарисуем два одинаковых круга (1).

Наложим один на другой, чтобы при пересечении образовался полумесяц (2) и выделим их. Вначале тот, что будем обрезать, а потом тот, кем будем обрезать. В контекстно-зависимом меню Формат фигуры (оно справа в ленте появляется) ищем пункт Объединить фигуры и выбираем Вычитание (3). Вуаля – у нас появился такой нужный нам полумесяц (4).

Понятное дело, что это самый простой вариант применения. Фигуры можно объединять, убирать или оставлять пересекающиеся фрагменты, можно обрезать картинки и прочее-прочее-прочее. Возможности ограничены только вашей фантазией. А из-за того, что иконки, текст, символы в PP являются фигурами можно делать так буквально в несколько кликов:

При этом картинку внутри букв можно всегда подвигать с помощью Обрезки


2. Анимация

Стой-стой-стой! Я не про выпрыгивающие буковки и «занавес» при переключении слайда. Хотя и это кому-то может пригодиться. Я расскажу про простейший вид анимации, о котором многие не знают. Представь, что ты выступаешь перед жрецами древнего культа. И тебе просто необходимо показать парад планет. Но схематично. Не обессудьте, вот такой вот культ. Из исходных данных у нас только этот слайд:

Что делаем? Просто дублируем слайд и ставим планеты так как нужно, например вот так:

Не забываем про выравнивание по центру слайда и первого списка фишек PP=)

Затем на нашем слайде с готовым парадом планет жмем Переходы и выбираем Трансформация (1).

Все, магия началась! Можем настроить время или выбрать объекты, которые не будут участвовать в нашем веселье. В результате за минуту (!) в PowerPoint (!!)  мы сделали вот такую анимацию:

К слову записать такой видосик или гифку можно в самом PP с помощью инструмента Запись слайдшоу. Но…

На очереди у нас две простейшие фишки, облегчающие работу со стилями фигур и текста.


3. Ctrl+Shit+C — Ctrl+Shit+V

Аналог богоподобной копипасты, но для стиля текста, фигуры, картинки и т. д. Копирует шрифт, обводку, эффекты, заливку и всё-всё-всё. Особенно шикарно, если вам нужно повторить какой-то сложный градиент. Очень помогает быстро выдержать единую стилистику на всех слайдах, а не ковыряться и не искать, какой же толщины у вас была граница на втором слайде – 1,5 или 2,5 pt.

Как использовать, думаю, ясно.


4. Фигура по умолчанию

Честно, в те времена, когда я не знал про шаблоны и про этот инструмент, а мне приходилось иногда делать презы, я жутко бесился от того, что каждая новая фигура рисуется каким-то гадким синим цветом, да еще и с тёмно-синей обводкой. Каждый раз убирал обводку, перекрашивал. Пока в один случайный момент не кликнул правой кнопкой мышки по фигуре и не обратил внимание на это (1):

Один жмяк – и все последующие фигуры будут создаваться именно в такой стилистике. Нужно изменить? Жмяк на нужной фигуре – и поехали. Просто как два пальца, экономит уйму времени, но неочевидно.

5. Сложная обрезка картинок. Полилиния.

Итак, продолжая морскую тематику давайте возьмём вот такой слайд:

Допустим нам нужно весь текст или его часть поместить за центрального персонажа картинки – Мистера Чайку. Фотошопа у нас нема, да и стоит он дорого. Удаление фона работает криво – белые облака смешивается с белыми крыльями. На выход приходит инструмент Полилиния: фигура (1)

При нажатой клавише мыши он рисует произвольную кривенькую фигуру. А вот отдельные щелчки похожи на Прямоугольное лассо из Фотошопа. Наша задача – обвести этой фигурой то, что нам надо вырезать. Но вначале – дублируем картинку, соотносим ее с исходной и отправляем ее на задний слой. Туда же отправляем текст – чтоб не мешался. И затем рисуем нашу фигуру (2). Всю чайку обводить не будем – головы достаточно. Если напортачили – нестрашно – Backspace все вернет на шаг назад. Главное – правильно замкнуть фигуру.

Затем проводим операцию из первой части поста – выбираем вначале исходную картинку, затем получившуюся фигуру, идем в Формат фигурыОбъединение фигур, но на этот раз выбираем Пересечение (3). Хоба! – декапитация Мистера Чайки прошла успешно. (4) Если вы все сделали правильно у вас получится вот это:

Добавьте тени буквам, настройте размеры и удивляйте всех шикарным и необычным слайдом.

А у меня на сегодня всё! Удачи вам и шикарных презентаций!


Mr. Powerpoint


P.S. Первые 5 хитростей по работе с PP - тут

Показать полностью 11
43

Чат с прогнозом погоды и триггеры в гугл таблицах (GS6)

Глобально задача в следующем:

1 - забрать с какого-нибудь сайта прогноз погоды

2 - подключить бота и привязать его к таблице

3 - настроить триггер для отправки.

Посмотрев несколько сайтов с погодой - выбор пал на Яндекс, ввиду удобной структуры сайта.

Отсюда я забрал прогноз:

Подробнее о том как спарсить данные с сайта в таблицу в этом посте: Парсинг данных с сайтов в гугл таблички (GS1)

Тут приведу только формулу:

=IMPORTHTML("https://yandex.ru/pogoda/ufa/details?via=mf#26","table",1)

Теперь подключаем бота. Как это сделать - читай тут: Подключение телеграм бота к гугл табличкам (GS3)


Если ранее мы использовали chat_id - чат с самим ботом, то сейчас мы будем использовать ид чата/ группы в телеграме, в который бот был добавлен.

Для этого нам необходимо сохранять ид чата отдельно в таблице и обращаться к этому значению как к значению переменной chat_id.

Соответственно, нам нужна функция, которая будет это делать:


function link(chat_id) {

//записывает ид чата в таблицу

DOC.getSheetByName("Settings").getRange(2,1).setValue(chat_id);

Demo.send("ID записан", chat_id, API_TOKEN);

}


Важно! В строке Demo.send я вызываю функцию send, которая уже рассматривалась в посте про создание бота. Demo в данном контексте - это название библиотеки, также подробнее про библиотеки можно почитать в соответствующем посте.


Вызывать ее мы будем из тела функции doPost(e) при условии, что боту отправлена команда /link. В коде это выглядит вот так:

Теперь соберем все вместе и сформируем сообщение для отправки в чат.


Глобальные переменные:


API_TOKEN - токен бота

DOC - ссылка на вашу гугл таблицу

DATA - лист гугл таблицы, содержащий прогноз погоды

SETTINGS - лист гугл таблицы, содержащий значение chat_id

App_link - URL веб приложения

Все, что в кавычках, должно быть изменено на ваши значения.

Функция для подключения веб хука:

Функция link(chat_id) для запоминания id чата

Функция daily() для формирования и отправки прогноза в чат:

На данный момент функция daily() не вызывается другой функцией или командой типа /link или /hello.


Мы добавим триггер, который будет вызывать функцию автоматически каждое утро.


Переходим на вкладку Triggers

Добавляем новый триггер

В окне задаем необходимые параметры.

Во-первых, функцию. Фукция, которая вызывается по триггеру, - daily().

Event source - по времени (Time-driven)

Type of time based trigger - Day timer (раз в день)

Time of day - в какое время триггер должен сработать

Сохраняем.


Результат работы скрипта ниже.

Дополнительно: триггеры на то и триггеры, что работают автономно (без участия пользователя или разработчика, с закрытым доком или чатом. В любой ситуации сообщение будет отправлено в чат в установленное время с установленной частотой.

Показать полностью 11
59

Создание библиотеки в гугл скриптах

В Гугл скриптах, как и в других языках программирования, есть возможность использовать библиотеки.

Что такое библиотека? Это набор функций и методов, которые часто используются программистами в разных программах. Чтобы не создавать одну и ту же функцию дважды или больше раз, достаточно один раз сохранить ее в библиотеку и подключать библиотеку к новому коду с уже написанными стандартными функциями.


Го к примерам.

В посте про создание телеграм бота мы использовали только три функции, и эти функции стандартные для любого бота. Следовательно, чтобы при создании второго, третьего… десятого бота не переписывать эти функции снова и снова, давайте просто сохраним их в библиотеку.


Создаем новые ГТ и скрипт в ней

Пропишем функцию send(msg, chat_id) :


function send (msg, chat_id, api) {

//Отправляет сообщения в тлг. На вход функции дать сообщение и ID чата, в который нужно провести отправку

var payload = {

'method': 'sendMessage',

'chat_id': String(chat_id),

'text': msg,

'parse_mode': 'HTML'

}

var data = {

"method": "post",

"payload": payload

}

UrlFetchApp.fetch('https://api.telegram.org/bot' + api + '/', data);

}


Сохраняем проект и делаем деплой

Кликаем по шестеренке и выбираем Library

Кликаем Deploy внизу окна и видим ссылку на библиотеку

Из всей ссылки нам нужен только id, который зашит между /d/ и /4 (согласно скрину выше) - 1iJ_IOEicfGzTlfbhDkcKIcBBEbh9UJ8WLf1FRQZ1Wu_Wnoqw6OBtITjZ. Копируем свой ид и идем дальше.


Создаем новые гугл таблицу и скрипт. В скрипте прописываем глобальные переменные

Помним, что значения этих переменных у вас будут свои.


Попробуем добавить тот же функционал, что и в посте про создание бота, с отправкой сообщения в чат телеграма. Но в этот раз мы не будем создавать функцию send(), а подключим библиотеку, в которой она уже есть.


Добавляем библиотеку

В открывшемся окне вставляем ID библиотеки (не ссылку, а ид) и кликаем Look up

Если подключение библиотеки прошло успешно, в окне появятся дополнительные поля выбора версии и указания идентификатора.


Название идентификатора меняем на короткое и понятное и кликаем Add.

В результате в списке библиотек видим новую библиотеку

Напоминаю, что в библиотеке у нас 1 функция. К ней можно обратиться следующим образом: имяБиблиотеки.имяФункции

Когда вы прописываете имя библиотеки и ставите точку, вы видите список всех доступных функций. В нашем случае это только функция send. Выбираем ее и прописываем передаваемые параметры:

Demo.send("Hello World", chat_id, API_TOKEN)

Сохраняем проект, кликаем Deploy, обновляем Api_link, выполняем функцию api_connector и идем тестить работу этого бота (этот алгоритм действий также подробнее описан в статье про создания бота).

Новый бот отправляет сообщение в чат с помощью функции, которая зашита в библиотеке.

Таким образом, в ту же библиотеку можно добавить ряд стандартных функций и к новым скриптам подключать уже написанные функции, не создавая их снова.

Показать полностью 11
316

Подключение телеграм бота к гугл табличкам - обновленный пост (GS3)

Всем ку

Комбинация из ТЛГ и ГТ, простота подключения КМК делает из ГТ офигенный инструмент автоматизации.

Тайм-менеджмент, таск-менеджмент, учёт финансов, объявления, пересылка событий - всё это создается и довольно быстро настраивается. Главное - это становится полезным не только в бизнесе, но и для обычных чатлан.

Пост ориентирован прежде всего на людей, которые только познают ГТ и на первых порах не требует знания гугл скриптов. В этом посте будет только первичная настройка и подключение. В следующих постах рассмотрю всё что описал выше (как трекать время, задачи, финансы и т.д. и как это настроить под себя).

Для начала находим отца всех ботов @botfather в телеге.

После старта бота botftaher выведет список команд. Здесь нам интересна команда создания нового бота /newbot.

Порядок очень простой: создать бота, назвать его человеческим языком, задать ему username. В результате получаем API токен нашего бота (1860347610:AAH1q6eqTPnVh0qe6mQWidNSTELcprXEfOk). Он-то нам и нужен.

Теперь переходим к гугл таблице. Создаем новую таблицу, переходим в пункт меню Инструменты/Tools -> Редактор скриптов/ Script editor.

Должно получиться вот это:

Затираем дефолтный код и вставляем следующий скрипт:


const API_TOKEN = '1860347610:AAH1q6eqTPnVh0qe6mQWidNSTELcprXEfOk'

const DOC = SpreadsheetApp.openById(‘10W0T9eOP_NN_6g4qyEJzWjm4nkKRN2vyUOnpx73f-N0’);

function doPost(e) {

var update = JSON.parse(e.postData.contents);

//нам нужен только тип "сообщение"

if (update.hasOwnProperty('message')) {

var msg = update.message;

var chat_id = msg.chat.id;

var text = msg.text;

var msg_array = msg.text.split(" ");

var date = (msg.date/86400)+25569.125;

var user = msg.from.username;

if (msg_array[0] == "/hello") {

send("Hello World", chat_id)

}

}

}

function send (msg, chat_id) {

//Отправляет сообщения в тлг. На вход функции дать сообщение и ID чата, в который нужно провести отправку

var payload = {

'method': 'sendMessage',

'chat_id': String(chat_id),

'text': msg,

'parse_mode': 'HTML'

}

var data = {

"method": "post",

"payload": payload

}

UrlFetchApp.fetch('https://api.telegram.org/bot' + API_TOKEN + '/', data);

}


Обращаем внимание на переменные DOC и API_TOKEN (выделено жирным). Значения переменных необходимо исправить на ваши значения.


Таким образом:

1) меняем ID гугл таблицы (находится в строке адреса после /d/)

2) меняем токен бота, который мы получили при его создании выше

Круто! Львиная доля работы уже проделана.

Следующим важным моментом является регистрация вебхука (webhook).

Добавим следующий код к нашему скрипту:


function api_connector () {

const App_link = "";

UrlFetchApp.fetch("https://api.telegram.org/bot"+API_TOKEN+"/setWebHook?url="+App_link);

}


Переменную App_link пока оставляем пустой. Следующий шаг - это генерация значения для нее.


Сохраняем наш код и кликаем Deploy.

В открывшемся окне кликаем по шестеренке и выбираем Web app

В поле Who has access выбираем Anyone

И кликаем Deploy.


При первом запуске приложение попросит авторизации. Проделываем это упражнение.


Получаем следующее:

Здесь нам нужен URL в самом конце. Копируем его и вставляем в качестве значения переменной App_link.


Теперь функция должна выглядеть следующим образом:


function api_connector () {

const App_link = "https://script.google.com/macros/s/AKfycbznvI6P0sc4vrIm7GW6C...";

UrlFetchApp.fetch("https://api.telegram.org/bot"+API_TOKEN+"/setWebHook?url="+App_link);

}


Снова сохраняем код и запускаем функцию api_connector:

И наконец переходим к боту в телеге! Запускаем, отправляем команду /hello и видим результат.

Теперь подробно по коду. В коде всего 3 функции:


doPost(e)

send (msg, chat_id)

api_connector ()


doPost - это стандартная функция при работе с телеграм ботами, в которую зашиваются ответные действия от бота при отправке сообщения в чат с ним.

В нашем случае, если мы отправляем команду /hello, бот отвечает Hello World, вызывая функцию send. Это все его действия.


send - функция, которая непосредственно осуществляет отправку сообщения в чат. Функция имеет параметры msg (текст сообщения) и chat_id (ид чата, в который осуществляется отправка).


api_connector - функция подключения вебхука

Показать полностью 16
9

Текст разделился надвое вдоль листа. Word 2007 упд: Решено!

Помогал печатать конспект жене. Много копировал из другого документа, в том числе и таблицы, которые почему-то плохо вставлялись, приходилось дико форматировать их, так как сам я не сильно продвинутый пользователь.
Вчера открыл документ, а там текст с самого начала и до страницы семидесятой примерно (всего около ста страниц, позавчера добирал последние тридцать), так вот текст после позовчерашнего сохранения съехал, разделившись надвое по длине листа.

Как можно вернуть исходное состояние? Откатить назад уже не мог, так как текст уже был сохранён.
Заранее благодарю всех!

Текст разделился надвое вдоль листа. Word 2007 упд: Решено!
Показать полностью 1
8

Power Query для цен LM

Всем привет.  После недавнего поста про Power Query решил реализовать это на другом примере - вытаскивать актуальные цена с сайта Леруа. Прошлось совместить два гайда, но в самом конце вылезает ошибка.

После "преобразовать данные" удаляю в примененных шагах "навигация" и у источника через шестеренку меняю "открыть файл как" на текстовый. С помощью заранее найденной на сайте строчки через F12 через поиск отсекаю нужную строку, затем либо с помощью замены лишних частей , либо с помощью разделения по знакам >;< отделяю столбцы и удаляю лишние - получаю только нужное значение.  Дальше действую уже по гайду, и в конце получаю это.

Power Query для цен LM
11

Продолжение поста «Московский подрядчик. Форма акта сдачи-приемки в Excel»1

При подготовке акта обнаружилась ошибка, если дата окончания периода и дата акта - октябрь.

Ниже ссылки на исправленный файл.


https://docs.google.com/spreadsheets/d/1TftJIRnsU9fMFrnnTWRW...


https://disk.yandex.ru/i/gPYc2fDpoG_lqg

Отличная работа, все прочитано!