Вопрос по гугл таблицам, а именно необходимо при нажатии на флажок (страница Транзит (разработка), столб L) значения всей строки (с A-J) переносились в самую нижнюю строку на страницу Приход. Названия колонок совпадает.
Перенос осуществляется один раз. Если отжать флажок ничего не меняется.
Вопрос по гугл таблицам, а именно необходимо при нажатии на флажок (страница Транзит (разработка), столб L) значения всей строки (с A-J) переносились в самую нижнюю строку на страницу Приход. Названия колонок совпадает.
Перенос осуществляется один раз. Если отжать флажок ничего не меняется.
Даю первое простое приближение скрипта. Оно, скорее всего, вам не понравится, потому что наружу полезут различные недоразумения, как-то: * наличие формул с открытыми диапазонами в первой строке данных листа "Приход", которые после добавления строк превращаются в ошибки #REF! * несоответствие колонок листов "Транзит" и "Приход" - кол-во совпадает, но названия различаются * непривычный формат даты у первой колонки в добавляемых строках * наличие большого "пустого" пространства в таблице перед строками, добавляемыми скриптом. Это пространство возникает потому, что "Проверка данных" в некоторых колонках была сразу раскручена до конца таблицы (а любая ячейка с проверкой считается непустой, учитывается как занятая оператором appendRow и потому им пропускаемая).
Когда вы переварите эти нюансы, можно будет продолжить разговор по конструктивному изменению скрипта. Пока же он (его "рыба") выглядит так: [vba]
Код
function onEdit(e) { // ячейка с щёлкнутым флажком var rng = e.range; if (rng.getSheet().getName() == 'Транзит (разработка)' && rng.getNumColumns() == 1 && rng.getNumRows() == 1 && rng.getColumn() == 12 // column L && rng.getRow() >= 5) {
// если флажок устанавливается if (rng.getValue() == true) { // строка, на которой выполнен щелчок var row = rng.getRow(); // контент строки щелчка (начало данных - с 5-й строки "Транзита") var arr = rng.getSheet().getRange('A5:K').getValues()[row-5]; // если щёлкнутая строка "Транзита" не пустая if (arr.toString() != ',,,,,0,,,,,') { // передаем ее в конец "Прихода" SpreadsheetApp.getActive().getSheetByName('Приход').appendRow(arr); } } } }
[/vba]
Даю первое простое приближение скрипта. Оно, скорее всего, вам не понравится, потому что наружу полезут различные недоразумения, как-то: * наличие формул с открытыми диапазонами в первой строке данных листа "Приход", которые после добавления строк превращаются в ошибки #REF! * несоответствие колонок листов "Транзит" и "Приход" - кол-во совпадает, но названия различаются * непривычный формат даты у первой колонки в добавляемых строках * наличие большого "пустого" пространства в таблице перед строками, добавляемыми скриптом. Это пространство возникает потому, что "Проверка данных" в некоторых колонках была сразу раскручена до конца таблицы (а любая ячейка с проверкой считается непустой, учитывается как занятая оператором appendRow и потому им пропускаемая).
Когда вы переварите эти нюансы, можно будет продолжить разговор по конструктивному изменению скрипта. Пока же он (его "рыба") выглядит так: [vba]
Код
function onEdit(e) { // ячейка с щёлкнутым флажком var rng = e.range; if (rng.getSheet().getName() == 'Транзит (разработка)' && rng.getNumColumns() == 1 && rng.getNumRows() == 1 && rng.getColumn() == 12 // column L && rng.getRow() >= 5) {
// если флажок устанавливается if (rng.getValue() == true) { // строка, на которой выполнен щелчок var row = rng.getRow(); // контент строки щелчка (начало данных - с 5-й строки "Транзита") var arr = rng.getSheet().getRange('A5:K').getValues()[row-5]; // если щёлкнутая строка "Транзита" не пустая if (arr.toString() != ',,,,,0,,,,,') { // передаем ее в конец "Прихода" SpreadsheetApp.getActive().getSheetByName('Приход').appendRow(arr); } } } }
Второе пришествие скрипта - учтены все заявленные недоразумения первой версии. Обработка вынесена в отдельную подпрограмму process_tranzit_m_true_v2, поскольку в общей onEdit могут присутствовать многие различные фрагменты по разным поводам и поэтому не стоит ее перегружать частностями. [vba]
Код
function onEdit(e) { // ячейка с щёлкнутым флажком var rng = e.range;
function process_tranzit_m_true_v2(cell) { var ss = SpreadsheetApp.getActive();
// если флажок устанавливается if (cell.getValue() == true) { // строка, на которой выполнен щелчок var row = cell.getRow(); // диапазон строки щелчка var rngArr = cell.getSheet().getRange('A5:J').offset(row-5, 0, 1); // контент строки щелчка (начало данных - с 5-й строки "Транзита") var arr = rngArr.getValues();
// если щёлкнутая строка "Транзита" не пустая if (arr.toString() != ',,,,,0,,,,') { // добавление в массив значений колонки "Средняя закупочная цена", которой нет в "Транзите" arr[0].splice(5,0,null); // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arr[0][2] = null; // Наименование arr[0][6] = null; // Сумма
// определение точки вставки на листе "Приход" var sheet = ss.getSheetByName('Приход'); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Транзита" в конец листа "Приход" rngNew.offset( 0, 0, 1, 11).setValues(arr); // копирование форматов с предыдущей строки rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
[/vba]
Второе пришествие скрипта - учтены все заявленные недоразумения первой версии. Обработка вынесена в отдельную подпрограмму process_tranzit_m_true_v2, поскольку в общей onEdit могут присутствовать многие различные фрагменты по разным поводам и поэтому не стоит ее перегружать частностями. [vba]
Код
function onEdit(e) { // ячейка с щёлкнутым флажком var rng = e.range;
function process_tranzit_m_true_v2(cell) { var ss = SpreadsheetApp.getActive();
// если флажок устанавливается if (cell.getValue() == true) { // строка, на которой выполнен щелчок var row = cell.getRow(); // диапазон строки щелчка var rngArr = cell.getSheet().getRange('A5:J').offset(row-5, 0, 1); // контент строки щелчка (начало данных - с 5-й строки "Транзита") var arr = rngArr.getValues();
// если щёлкнутая строка "Транзита" не пустая if (arr.toString() != ',,,,,0,,,,') { // добавление в массив значений колонки "Средняя закупочная цена", которой нет в "Транзите" arr[0].splice(5,0,null); // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arr[0][2] = null; // Наименование arr[0][6] = null; // Сумма
// определение точки вставки на листе "Приход" var sheet = ss.getSheetByName('Приход'); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Транзита" в конец листа "Приход" rngNew.offset( 0, 0, 1, 11).setValues(arr); // копирование форматов с предыдущей строки rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
Gustav, по данному моменту все понятно. Перенос строки в лист Приход работает должным образом, спасибо!
Есть пару вопросов по onEdit(e), уже имеется данная функция в отдельном файле. (Скриншот №1) Данная функция осуществляет вывод текущей даты при нажатии на флажок на листе Рекламации. Каким образом можно осуществить их совместную работу? (Функционал переноса строки в Приход и Дата при нажатии на галку в Рекламации) Так как в будущем я планирую реализовать перенос строки из Рекламации в Приход, использовать onEdit(e) нужно будет в 3 раз.
Второй вопрос, удалил столбцы СКЛАД и ЯЧЕЙКА в Транзит (Разработка), внес изменения в файл Транзит.gs чтобы данные корректно приходили. Данные из столба Комментарий не поступают, как это можно исправить?
Gustav, по данному моменту все понятно. Перенос строки в лист Приход работает должным образом, спасибо!
Есть пару вопросов по onEdit(e), уже имеется данная функция в отдельном файле. (Скриншот №1) Данная функция осуществляет вывод текущей даты при нажатии на флажок на листе Рекламации. Каким образом можно осуществить их совместную работу? (Функционал переноса строки в Приход и Дата при нажатии на галку в Рекламации) Так как в будущем я планирую реализовать перенос строки из Рекламации в Приход, использовать onEdit(e) нужно будет в 3 раз.
Второй вопрос, удалил столбцы СКЛАД и ЯЧЕЙКА в Транзит (Разработка), внес изменения в файл Транзит.gs чтобы данные корректно приходили. Данные из столба Комментарий не поступают, как это можно исправить?
Есть пару вопросов по onEdit(e), уже имеется данная функция в отдельном файле. (Скриншот №1) Данная функция осуществляет вывод текущей даты при нажатии на флажок на листе Рекламации. Каким образом можно осуществить их совместную работу? (Функционал переноса строки в Приход и Дата при нажатии на галку в Рекламации) Так как в будущем я планирую реализовать перенос строки из Рекламации в Приход, использовать onEdit(e) нужно будет в 3 раз.
Функция onEdit должна быть одна на один файл таблицы (если их несколько, даже в разных скриптовых файлах, то сработает только одна и заранее неизвестно какая). В нее нужно поместить вызовы всех предполагаемых обработчиков, разделив их операторами if. Поскольку условий может быть много, то желательно оставить в onEdit только операторы if и операторы вызова соответствующих функций для конкретных случаев. Т.е. в терминах вашего примера следует придерживаться оформления случая 2 и избегать оформления в стиле случая 1: [vba]
Код
function onEdit(e) { var sheet = e.source.getActiveSheet(); // ячейка с щёлкнутым флажком var rng = e.range;
// 1-й случай использования onEdit if (sheet.getName() == "Рекламации") //"order data" is the name of the sheet where you want to run this script. { // -------------------------------------------- // это лучше убрать в отдельную подпрограмму, передав в нее параметр sheet // например, function process_reklamac(sheet) , т.е. по аналогии со 2-м случаем var actRng = sheet.getActiveRange(); var editColumn = actRng.getColumn(); var rowIndex = actRng.getRowIndex(); var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues(); var dateCol = headers[0].indexOf("Data_ystanovki_flajka") + 1; var orderCol = headers[0].indexOf("✓") + 1; if (dateCol > 0 && rowIndex > 1 && editColumn == orderCol) { sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new Date(), "UTC+3", "dd.MM.yy")); } // -------------------------------------------- }
// 2-й случай использования onEdit if (rng.getSheet().getName() == "Транзит (разработка)" && rng.getNumColumns() == 1 && rng.getNumRows() == 1 && rng.getColumn() == 10 // column L && rng.getRow() >= 5) {
Есть пару вопросов по onEdit(e), уже имеется данная функция в отдельном файле. (Скриншот №1) Данная функция осуществляет вывод текущей даты при нажатии на флажок на листе Рекламации. Каким образом можно осуществить их совместную работу? (Функционал переноса строки в Приход и Дата при нажатии на галку в Рекламации) Так как в будущем я планирую реализовать перенос строки из Рекламации в Приход, использовать onEdit(e) нужно будет в 3 раз.
Функция onEdit должна быть одна на один файл таблицы (если их несколько, даже в разных скриптовых файлах, то сработает только одна и заранее неизвестно какая). В нее нужно поместить вызовы всех предполагаемых обработчиков, разделив их операторами if. Поскольку условий может быть много, то желательно оставить в onEdit только операторы if и операторы вызова соответствующих функций для конкретных случаев. Т.е. в терминах вашего примера следует придерживаться оформления случая 2 и избегать оформления в стиле случая 1: [vba]
Код
function onEdit(e) { var sheet = e.source.getActiveSheet(); // ячейка с щёлкнутым флажком var rng = e.range;
// 1-й случай использования onEdit if (sheet.getName() == "Рекламации") //"order data" is the name of the sheet where you want to run this script. { // -------------------------------------------- // это лучше убрать в отдельную подпрограмму, передав в нее параметр sheet // например, function process_reklamac(sheet) , т.е. по аналогии со 2-м случаем var actRng = sheet.getActiveRange(); var editColumn = actRng.getColumn(); var rowIndex = actRng.getRowIndex(); var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues(); var dateCol = headers[0].indexOf("Data_ystanovki_flajka") + 1; var orderCol = headers[0].indexOf("✓") + 1; if (dateCol > 0 && rowIndex > 1 && editColumn == orderCol) { sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new Date(), "UTC+3", "dd.MM.yy")); } // -------------------------------------------- }
// 2-й случай использования onEdit if (rng.getSheet().getName() == "Транзит (разработка)" && rng.getNumColumns() == 1 && rng.getNumRows() == 1 && rng.getColumn() == 10 // column L && rng.getRow() >= 5) {
Второй вопрос, удалил столбцы СКЛАД и ЯЧЕЙКА в Транзит (Разработка), внес изменения в файл Транзит.gs чтобы данные корректно приходили. Данные из столба Комментарий не поступают, как это можно исправить?
Привожу исправленную версию сразу всей функции, чтобы просто заменить ее в файле (дополнительно ниже укажу на фрагменты, которые исправил): [vba]
Код
function process_tranzit_m_true_v2(cell) { var ss = SpreadsheetApp.getActive();
// если флажок устанавливается if (cell.getValue() == true) { // строка, на которой выполнен щелчок var row = cell.getRow(); // диапазон строки щелчка var rngArr = cell.getSheet().getRange("A5:H").offset(row-5, 0, 1); // контент строки щелчка (начало данных - с 5-й строки "Транзита") var arr = rngArr.getValues();
// если щёлкнутая строка "Транзита" не пустая if (arr.toString() != ",,,,,0,,") { // добавление в массив значений колонок, которых нет в "Транзите" // (!именно в таком порядке "с конца", т.е. начиная с более высоких индексов вставки!) // "Склад" и "Ячейка" - две колонки arr[0].splice(7,0,'',''); // "Средняя закупочная цена" - одна колонка arr[0].splice(5,0,null); // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arr[0][2] = null; // Наименование arr[0][6] = null; // Сумма
// определение точки вставки на листе "Приход" var sheet = ss.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Транзита" в конец листа "Приход" rngNew.offset( 0, 0, 1, 11).setValues(arr); // копирование форматов с предыдущей строки rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
[/vba] Мои исправления (по сравнению с текущей версией в файле, которую Вы уже правили по сравнению с моей первоначальной версией в сообщении №3 :)): [vba]
Код
* if (arr.toString() != ",,,,,0,,") { - изменилось кол-во запятых в строке сравнения после цифры 0 (самостоятельно подумать почему) * arr[0].splice(7,0,'',''); - добавился этот оператор для вставки в массив значений колонок "Склад" и "Ячейка" - из "Транзита"-то они убрались, но в "Приходе"-то остались, т.е. из "Транзита" читаем строку-массив из 8 значений, а в "Приход" вставляем 11 значений * поэтому в этих операторах надо оставить значения 11 (не менять на 9): rngNew.offset( 0, 0, 1, 11).setValues(arr); rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, ...
Второй вопрос, удалил столбцы СКЛАД и ЯЧЕЙКА в Транзит (Разработка), внес изменения в файл Транзит.gs чтобы данные корректно приходили. Данные из столба Комментарий не поступают, как это можно исправить?
Привожу исправленную версию сразу всей функции, чтобы просто заменить ее в файле (дополнительно ниже укажу на фрагменты, которые исправил): [vba]
Код
function process_tranzit_m_true_v2(cell) { var ss = SpreadsheetApp.getActive();
// если флажок устанавливается if (cell.getValue() == true) { // строка, на которой выполнен щелчок var row = cell.getRow(); // диапазон строки щелчка var rngArr = cell.getSheet().getRange("A5:H").offset(row-5, 0, 1); // контент строки щелчка (начало данных - с 5-й строки "Транзита") var arr = rngArr.getValues();
// если щёлкнутая строка "Транзита" не пустая if (arr.toString() != ",,,,,0,,") { // добавление в массив значений колонок, которых нет в "Транзите" // (!именно в таком порядке "с конца", т.е. начиная с более высоких индексов вставки!) // "Склад" и "Ячейка" - две колонки arr[0].splice(7,0,'',''); // "Средняя закупочная цена" - одна колонка arr[0].splice(5,0,null); // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arr[0][2] = null; // Наименование arr[0][6] = null; // Сумма
// определение точки вставки на листе "Приход" var sheet = ss.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Транзита" в конец листа "Приход" rngNew.offset( 0, 0, 1, 11).setValues(arr); // копирование форматов с предыдущей строки rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
[/vba] Мои исправления (по сравнению с текущей версией в файле, которую Вы уже правили по сравнению с моей первоначальной версией в сообщении №3 :)): [vba]
Код
* if (arr.toString() != ",,,,,0,,") { - изменилось кол-во запятых в строке сравнения после цифры 0 (самостоятельно подумать почему) * arr[0].splice(7,0,'',''); - добавился этот оператор для вставки в массив значений колонок "Склад" и "Ячейка" - из "Транзита"-то они убрались, но в "Приходе"-то остались, т.е. из "Транзита" читаем строку-массив из 8 значений, а в "Приход" вставляем 11 значений * поэтому в этих операторах надо оставить значения 11 (не менять на 9): rngNew.offset( 0, 0, 1, 11).setValues(arr); rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, ...