Вопрос по гугл таблицам, а именно необходимо при нажатии на флажок (страница Транзит (разработка), столб 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, ...
Gustav, указал все необходимые вызовы обработчиков в onEdit(e), разделив их if. Все получилось!
Так же на странице Рекламации при нажатии на ячейку (столбец J) корректно отображается дата на момент установки флажка (столбец C)
Учел все рекомендации выше, переписал скрипт по примеру с Транзитом. (Перенос ячеек: C5:G из страницы Рекламации в Приход при нажатии флажка в столбце J) ДАТА, PARTNUMBER, КОЛ-ВО, ПОСТАВЩИК Второй день бьюсь над задачей. Как я понимаю в первую очередь должна выполнятся функция function process_reklamac, чтобы далее значение перенеслось в приход.
Большая просьба указать в чем ошибка):
Вызов обработчика в function onEdit(e) [vba]
Код
// Копировать строку из Рекламаций в Приход //Ячейка с щелкнутым флажком (Для Рекламаций) var bla = e.range;
if (bla.getSheet().getName() == "Рекламации" && bla.getNumColumns() == 1 && bla.getNumRows() == 1 && bla.getColumn() == 10 // column L && bla.getRow() >= 5) { // Рабочая область страницы
process_reklamac_copy(bla); }
[/vba]
[vba]
Код
function process_reklamac_copy(coll){ var kk = SpreadsheetApp.getActive();
// если флажок устанавливается if (coll.getValue() == true) { // строка, на которой выполнен щелчок var row = coll.getRow(); // диапазон строки щелчка var rngArray = coll.getSheet().getRange("C2:F").offset(row-5, 0, 1); // контент строки щелчка (начало данных - с 5-й строки "Рекламации") var arry = rngArray.getValues();
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,,,") { // добавление в массив значений колонок, которых нет в "Рекламации" // (!именно в таком порядке "с конца", т.е. начиная с более высоких индексов вставки!)
arry[0].splice(4,0,null); // "ЗАКУПОЧНАЯ ЦЕНА" - одна колонка
arry[0].splice(5,0,null); // "СРЕДНЯЯ ЗАКУПОЧНАЯ ЦЕНА" - одна колонка
arry[0].splice(6,0,'',''); // "СУММА" - одна колонка
arry[0].splice(8,0,'',''); // "СКЛАД" - одна колонка
arry[0].splice(9,0,'',''); // "ЯЧЕЙКА" - одна колонка
arry[0].splice(10,0,'',''); // "КОММЕНТАРИЙ" - одна колонка
// удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход"
arry[0][2] = null; // Наименование arry[0][6] = null; // Сумма
// определение точки вставки на листе "Приход" var sheet = kk.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset( 0, 0, 1, 11).setValues(arry); // копирование форматов с предыдущей строки rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } }
Gustav, указал все необходимые вызовы обработчиков в onEdit(e), разделив их if. Все получилось!
Так же на странице Рекламации при нажатии на ячейку (столбец J) корректно отображается дата на момент установки флажка (столбец C)
Учел все рекомендации выше, переписал скрипт по примеру с Транзитом. (Перенос ячеек: C5:G из страницы Рекламации в Приход при нажатии флажка в столбце J) ДАТА, PARTNUMBER, КОЛ-ВО, ПОСТАВЩИК Второй день бьюсь над задачей. Как я понимаю в первую очередь должна выполнятся функция function process_reklamac, чтобы далее значение перенеслось в приход.
Большая просьба указать в чем ошибка):
Вызов обработчика в function onEdit(e) [vba]
Код
// Копировать строку из Рекламаций в Приход //Ячейка с щелкнутым флажком (Для Рекламаций) var bla = e.range;
if (bla.getSheet().getName() == "Рекламации" && bla.getNumColumns() == 1 && bla.getNumRows() == 1 && bla.getColumn() == 10 // column L && bla.getRow() >= 5) { // Рабочая область страницы
process_reklamac_copy(bla); }
[/vba]
[vba]
Код
function process_reklamac_copy(coll){ var kk = SpreadsheetApp.getActive();
// если флажок устанавливается if (coll.getValue() == true) { // строка, на которой выполнен щелчок var row = coll.getRow(); // диапазон строки щелчка var rngArray = coll.getSheet().getRange("C2:F").offset(row-5, 0, 1); // контент строки щелчка (начало данных - с 5-й строки "Рекламации") var arry = rngArray.getValues();
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,,,") { // добавление в массив значений колонок, которых нет в "Рекламации" // (!именно в таком порядке "с конца", т.е. начиная с более высоких индексов вставки!)
arry[0].splice(4,0,null); // "ЗАКУПОЧНАЯ ЦЕНА" - одна колонка
arry[0].splice(5,0,null); // "СРЕДНЯЯ ЗАКУПОЧНАЯ ЦЕНА" - одна колонка
arry[0].splice(6,0,'',''); // "СУММА" - одна колонка
arry[0].splice(8,0,'',''); // "СКЛАД" - одна колонка
arry[0].splice(9,0,'',''); // "ЯЧЕЙКА" - одна колонка
arry[0].splice(10,0,'',''); // "КОММЕНТАРИЙ" - одна колонка
// удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход"
arry[0][2] = null; // Наименование arry[0][6] = null; // Сумма
// определение точки вставки на листе "Приход" var sheet = kk.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset( 0, 0, 1, 11).setValues(arry); // копирование форматов с предыдущей строки rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } }
Вначале новая (и полная) редакция функции process_reklamac_copy. Всё немного проще, чем было у вас написано. С оператором splice явно не разобрались (погуглите по строке "javascript splice", поучите матчасть), правда, он здесь не особо и нужен. Помимо этого много мелких "грешков" (отмечены //*) - пожалуйста, будьте внимательнее (мне "ошибки диктанта" проверять не доставляет). [vba]
Код
function process_reklamac_copy(coll){ var kk = SpreadsheetApp.getActive();
// если флажок устанавливается if (coll.getValue() == true) { // строка, на которой выполнен щелчок var row = coll.getRow(); // диапазон строки щелчка var rngArray = coll.getSheet().getRange("C5:F").offset(row-5, 0, 1); //* c 5-й строки начало, а не со 2-й // контент строки щелчка (начало данных - с 5-й строки "Рекламации") var arry = rngArray.getValues();
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,") { //* тут всего 3 запятые, так как в считанном массиве 4 элемента // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arry[0][2] = null; // Наименование
// определение точки вставки на листе "Приход" var sheet = kk.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset( 0, 0, 1, 4).setValues(arry); //* здесь вставляем 4 первых колонки - здесь этого достаточно // копирование форматов с предыдущей строки //* а вот формат переносим с 11 - всё верно rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
[/vba] Дальше - фрагменты изменений. С местом их расположения, думаю, разберетесь. [vba]
Код
if (bla.getSheet().getName() == "Рекламации" && bla.getNumColumns() == 1 && bla.getNumRows() == 1 && bla.getColumn() == 10 // column L && bla.getRow() >= 5) { // Рабочая область страницы
process_reklamac(sheet); //* должно выполниться непосредственно перед process_reklamac_copy, так как будет нужна дата SpreadsheetApp.flush(); //* чтобы обновились изменения, вызванные process_reklamac process_reklamac_copy(bla); }
[/vba]
[vba]
Код
var headers = sheet.getRange(4, 1, 1, sheet.getLastColumn()).getValues(); //* здесь строка стала 4-й
[/vba]
[vba]
Код
if (dateCol > 0 && rowIndex > 1 && editColumn == orderCol) { // sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new Date(), "UTC+3", "dd.MM.yyyy")); //* не надо здесь перемудрять с форматированием даты в коде: //* вставили дату из скрипта, а всей колонке на листе вручную задали формат даты sheet.getRange(rowIndex, dateCol).setValue(new Date()); }
[/vba]
Вначале новая (и полная) редакция функции process_reklamac_copy. Всё немного проще, чем было у вас написано. С оператором splice явно не разобрались (погуглите по строке "javascript splice", поучите матчасть), правда, он здесь не особо и нужен. Помимо этого много мелких "грешков" (отмечены //*) - пожалуйста, будьте внимательнее (мне "ошибки диктанта" проверять не доставляет). [vba]
Код
function process_reklamac_copy(coll){ var kk = SpreadsheetApp.getActive();
// если флажок устанавливается if (coll.getValue() == true) { // строка, на которой выполнен щелчок var row = coll.getRow(); // диапазон строки щелчка var rngArray = coll.getSheet().getRange("C5:F").offset(row-5, 0, 1); //* c 5-й строки начало, а не со 2-й // контент строки щелчка (начало данных - с 5-й строки "Рекламации") var arry = rngArray.getValues();
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,") { //* тут всего 3 запятые, так как в считанном массиве 4 элемента // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arry[0][2] = null; // Наименование
// определение точки вставки на листе "Приход" var sheet = kk.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset( 0, 0, 1, 4).setValues(arry); //* здесь вставляем 4 первых колонки - здесь этого достаточно // копирование форматов с предыдущей строки //* а вот формат переносим с 11 - всё верно rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
[/vba] Дальше - фрагменты изменений. С местом их расположения, думаю, разберетесь. [vba]
Код
if (bla.getSheet().getName() == "Рекламации" && bla.getNumColumns() == 1 && bla.getNumRows() == 1 && bla.getColumn() == 10 // column L && bla.getRow() >= 5) { // Рабочая область страницы
process_reklamac(sheet); //* должно выполниться непосредственно перед process_reklamac_copy, так как будет нужна дата SpreadsheetApp.flush(); //* чтобы обновились изменения, вызванные process_reklamac process_reklamac_copy(bla); }
[/vba]
[vba]
Код
var headers = sheet.getRange(4, 1, 1, sheet.getLastColumn()).getValues(); //* здесь строка стала 4-й
[/vba]
[vba]
Код
if (dateCol > 0 && rowIndex > 1 && editColumn == orderCol) { // sheet.getRange(rowIndex, dateCol).setValue(Utilities.formatDate(new Date(), "UTC+3", "dd.MM.yyyy")); //* не надо здесь перемудрять с форматированием даты в коде: //* вставили дату из скрипта, а всей колонке на листе вручную задали формат даты sheet.getRange(rowIndex, dateCol).setValue(new Date()); }
Необходимо получить значение из ячейки Поставщик и добавить в Приход. Помимо (дата, partnumber, наименование, кол-во которые отлично приходят)
Указав 5 элементов массива вместо 4 значение не поступает, как это можно исправить? [vba]
Код
function process_reklamac_copy(coll){ var kk = SpreadsheetApp.getActive();
// если флажок устанавливается if (coll.getValue() == true) { // строка, на которой выполнен щелчок var row = coll.getRow(); // диапазон строки щелчка var rngArray = coll.getSheet().getRange("C5:G").offset(row-5, 0, 1); //* c 5-й строки начало, а не со 2-й // контент строки щелчка (начало данных - с 5-й строки "Рекламации") var arry = rngArray.getValues();
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,,,,,") { //* тут всего 3 запятые, так как в считанном массиве 4 элемента // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arry[0][2] = null; // Наименование /*arry[0][4] = null; // ЗАКУПОЧНАЯ ЦЕНА arry[0][5] = null; // СРЕДНЯЯ ЗАКУПОЧНАЯ ЦЕНА arry[0][6] = null; // СУММА */ // определение точки вставки на листе "Приход" var sheet = kk.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset(0, 0, 1, 5).setValues(arry); //* здесь вставляем 4 первых колонки - здесь этого достаточно // копирование форматов с предыдущей строки //* а вот формат переносим с 11 - всё верно rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
[/vba]
Gustav, благодарю за подробный ответ!
Необходимо получить значение из ячейки Поставщик и добавить в Приход. Помимо (дата, partnumber, наименование, кол-во которые отлично приходят)
Указав 5 элементов массива вместо 4 значение не поступает, как это можно исправить? [vba]
Код
function process_reklamac_copy(coll){ var kk = SpreadsheetApp.getActive();
// если флажок устанавливается if (coll.getValue() == true) { // строка, на которой выполнен щелчок var row = coll.getRow(); // диапазон строки щелчка var rngArray = coll.getSheet().getRange("C5:G").offset(row-5, 0, 1); //* c 5-й строки начало, а не со 2-й // контент строки щелчка (начало данных - с 5-й строки "Рекламации") var arry = rngArray.getValues();
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,,,,,") { //* тут всего 3 запятые, так как в считанном массиве 4 элемента // удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arry[0][2] = null; // Наименование /*arry[0][4] = null; // ЗАКУПОЧНАЯ ЦЕНА arry[0][5] = null; // СРЕДНЯЯ ЗАКУПОЧНАЯ ЦЕНА arry[0][6] = null; // СУММА */ // определение точки вставки на листе "Приход" var sheet = kk.getSheetByName("Приход"); var rngNew = sheet.getRange(sheet.getMaxRows(), 1).getNextDataCell(SpreadsheetApp.Direction.UP).offset(1, 0); // вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset(0, 0, 1, 5).setValues(arry); //* здесь вставляем 4 первых колонки - здесь этого достаточно // копирование форматов с предыдущей строки //* а вот формат переносим с 11 - всё верно rngNew.offset(-1, 0, 1, 11).copyTo(rngNew, SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false); } } }
Я выписал по порядку колонки, ИЗ которых надо считать данные, и колонки, В которые надо записать данные: [vba]
Код
Лист РЕКЛАМАЦИИ - считываем данные из 5 ПЕРВЫХ колонок Index Column 0 --- ДАТА *** 1 --- PARTNUMBER *** 2 --- НАИМЕНОВАНИЕ *** 3 --- КОЛ-ВО *** 4 --- ПОСТАВЩИК ***
[/vba] [vba]
Код
Лист ПРИХОД - помещаем данные в 8 ПЕРВЫХ колонок Index Column 0 --- ДАТА *** 1 --- PARTNUMBER *** 2 --- НАИМЕНОВАНИЕ *** 3 --- КОЛ-ВО *** 4 --- ЗАКУПОЧНАЯ ЦЕНА 5 --- СРЕДНЯЯ ЗАКУПОЧНАЯ ЦЕНА 6 --- СУММА 7 --- ПОСТАВЩИК ***
[/vba] После считывания строки из диапазона Рекламации!C5:G имеем массив из 5 элементов. Для вставки на лист Приход массив надо "растянуть" до 8 элементов - потому что колонка ПОСТАВЩИК - 8-я на этом листе (или элемент с индексом 7). Для такой "растяжки" надо вставить в массив 8 - 5 = 3 элемента, начиная с элемента с индексом 4 (это ПОСТАВЩИК). При вставке трёх элементов на место исходного элемента с индексом 4 сам этот элемент смещается правее (или "ниже") на 3 элемента и после операции становится элементом с индексом 7.
Описанную операцию вставки выполняет оператор: [vba]
Код
arry[0].splice(4,0,'','','');
[/vba] где 4 - индекс элемента вставки, 0 - количество удаляемых элементов (в данном случае ничего не удаляем), три пустые строки - вставляемые в массив значения элементов, получающих после вставки индексы 4, 5, 6 соответственно. Элемент ПОСТАВЩИК после вставки получает индекс 7.
Дальше - фрагменты изменений: [vba]
Код
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,,") { //** тут всего 4 запятые, так как в считанном массиве 5 элементов
//** добавление в массив значений колонок, которых нет в "Транзите" arry[0].splice(4,0,'','',''); //** добавляем три пустые колонки (ячейки)
// удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arry[0][2] = ''; //** Наименование - пустая строка или null - эффект одинаковый
[/vba] [vba]
Код
// вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset(0, 0, 1, 8).setValues(arry); //** здесь вставляем 8 первых колонок
[/vba]
Я выписал по порядку колонки, ИЗ которых надо считать данные, и колонки, В которые надо записать данные: [vba]
Код
Лист РЕКЛАМАЦИИ - считываем данные из 5 ПЕРВЫХ колонок Index Column 0 --- ДАТА *** 1 --- PARTNUMBER *** 2 --- НАИМЕНОВАНИЕ *** 3 --- КОЛ-ВО *** 4 --- ПОСТАВЩИК ***
[/vba] [vba]
Код
Лист ПРИХОД - помещаем данные в 8 ПЕРВЫХ колонок Index Column 0 --- ДАТА *** 1 --- PARTNUMBER *** 2 --- НАИМЕНОВАНИЕ *** 3 --- КОЛ-ВО *** 4 --- ЗАКУПОЧНАЯ ЦЕНА 5 --- СРЕДНЯЯ ЗАКУПОЧНАЯ ЦЕНА 6 --- СУММА 7 --- ПОСТАВЩИК ***
[/vba] После считывания строки из диапазона Рекламации!C5:G имеем массив из 5 элементов. Для вставки на лист Приход массив надо "растянуть" до 8 элементов - потому что колонка ПОСТАВЩИК - 8-я на этом листе (или элемент с индексом 7). Для такой "растяжки" надо вставить в массив 8 - 5 = 3 элемента, начиная с элемента с индексом 4 (это ПОСТАВЩИК). При вставке трёх элементов на место исходного элемента с индексом 4 сам этот элемент смещается правее (или "ниже") на 3 элемента и после операции становится элементом с индексом 7.
Описанную операцию вставки выполняет оператор: [vba]
Код
arry[0].splice(4,0,'','','');
[/vba] где 4 - индекс элемента вставки, 0 - количество удаляемых элементов (в данном случае ничего не удаляем), три пустые строки - вставляемые в массив значения элементов, получающих после вставки индексы 4, 5, 6 соответственно. Элемент ПОСТАВЩИК после вставки получает индекс 7.
Дальше - фрагменты изменений: [vba]
Код
// если щёлкнутая строка "Рекламации" не пустая if (arry.toString() != ",,,,") { //** тут всего 4 запятые, так как в считанном массиве 5 элементов
//** добавление в массив значений колонок, которых нет в "Транзите" arry[0].splice(4,0,'','',''); //** добавляем три пустые колонки (ячейки)
// удаление значений из колонок с формулами массива - чтобы избежать ошибки #REF! на листе "Приход" arry[0][2] = ''; //** Наименование - пустая строка или null - эффект одинаковый
[/vba] [vba]
Код
// вставка значений выбранной строки "Рекламации" в конец листа "Приход" rngNew.offset(0, 0, 1, 8).setValues(arry); //** здесь вставляем 8 первых колонок
Заметил ошибку в ходе тестирования, не могу понять почему строка из Рекламации не переноситься в Приход, хотя по столбцам и коду порядок. Пожалуйста подскажи в чем дело?
Заметил ошибку в ходе тестирования, не могу понять почему строка из Рекламации не переноситься в Приход, хотя по столбцам и коду порядок. Пожалуйста подскажи в чем дело?
не могу понять почему строка из Рекламации не переноситься в Приход
Подозреваю, что это из-за того, что из кода напрочь пропала функция process_reklamac_copy (см. два первых фрагмента кода в сообщении № 8 с дополнениями из сообщения № 10).
не могу понять почему строка из Рекламации не переноситься в Приход
Подозреваю, что это из-за того, что из кода напрочь пропала функция process_reklamac_copy (см. два первых фрагмента кода в сообщении № 8 с дополнениями из сообщения № 10).Gustav