Google apps script – Поиск и копирование новых данных (googlesheets)
Есть таблица 1 (Источник данных), куда каждый день загружаются новые операции (1 операция = 1 строка). Количество операций в день произвольное. В последнем столбце (Тип операции) вручную надо указать тип операции.
Есть таблица 2 (Прямые продажи), в которую должны автоматически подгружаться все новые операции из таблицы источника данных, у которых необходимый тип операции (в примере это тип "Прямые продажи").
Я по гайдам написал скрипт, который копирует данные из таблицы 1 в таблицу 2, но проблема в том, что при каждом запуске он копирует ВСЕ подходящие данные, уже со второго запуска создавая в таблице 2 дубликаты.
Понимаю, что нужно доработать скрипт, чтобы он при добавлении новых данных в таблицу 1:
- находил в таблице 1 последнюю строку из таблицы 2 (недопустимость дубликатов)
- пробегался по всем строкам под ней в таблице 1 (поиск новых подходящих операций)
- забирал все строки с необходимым типом операции в таблицу 2 (копирование новых операций)
Но компетенций на такого рода модернизации не хватает (к сожалению далек от программирования), я застрял еще на этапе сравнения двух массивов данных. Пробовал искать похожие кейсы, но везде предлагается после изъятия нужных данных очищать страницу (что в моем случае недопустимо, данные в таблице 1 должны оставаться), соответственно и перебор строк там не рассматривается.
Буду признателен если кто-нибудь сможет помочь доработать скрипт или направит в какую сторону искать/покажет похожие примеры, чтобы было где подсмотреть.
(в примере я разместил обе таблицы в одном файле на разных листах, и количество столбцов сократил для визуального облегчения. Но важный момент что сравнивать нужно будет Всю строку, чтобы загружать только уникальные операции)
Ссылка на таблицу: https://docs.google.com/spreadsheets/d/1D5K33BMi5aLDcZkDYlKSXBpag2av_FrzNOQ4O24ueVw/edit#gid=1217659551
Код который получилось написать:
function copyrows(){
const ss_sourse = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Источник Данных");
const ss_target = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Прямые продажи");
const ss_sourse_lr = ss_sourse.getLastRow();
const ss_target_lr = ss_target.getLastRow();
let sortRange = ss_sourse.getSheetValues(3,1,ss_sourse_lr, 6);
let b2b_direct = 1;
for (var i = 1; i <= sortRange.length; i++){
let name = ss_sourse.getRange(i,6).getValue();
if (name == "Прямые продажи"){
let rowValues = ss_sourse.getRange(i, 1, 1, 6).getValues();
ss_target.getRange(ss_target_lr+b2b_direct, 1, 1, 6).setValues(rowValues);
b2b_direct++;
}
}
Ответы (1 шт):
Необходимо построить индекс листа-приемника, по которому вы будете определять уникальные значения.
Далее необходимо отфильтровать данные листа-источника на основе ваших параметров и присутствия данных в индексе листа-приемника.
И потом вставить значения.
function copyrows() {
const to = SpreadsheetApp.getActive().getSheetByName('Прямые продажи');
const toIndex = to.getDataRange().getValues()
.map(calcIndex_);
const fromValues = SpreadsheetApp.getActive().getSheetByName('Источник данных')
.getDataRange().getValues()
.slice(2)
.filter(row => {
return row[5] === 'Прямые продажи' && toIndex.indexOf(calcIndex_(row)) === -1
});
if (fromValues.length) {
const lr = to.getLastRow();
if (lr >= to.getMaxRows())
to.insertRowAfter(lr);
to.getRange(lr + 1, 1, fromValues.length, fromValues[0].length)
.setValues(fromValues);
}
}
const calcIndex_ = (row) => {
const [a, b, c, d, e] = row;
const b_ = b.getTime ? b.getTime() : 0;
return [a, b_, c, d, e].join('_');
}
Пример в Таблице https://docs.google.com/spreadsheets/d/13hTtR4Z5LHHOtdJhswstjHBq6GIsEMGzj96nImce5DM/edit?usp=sharing