Скрипт Google Apps для перемещения строк с комментариями на другой лист

У меня есть скрипт для перемещения строк на другой лист, он работает, но не полностью, как хотелось бы.

У меня есть электронная таблица с 2 вкладками, одна «ПЛАНИРОВЩИК» и одна «МАСТЕР». На вкладке "A PLANIFIER" в столбце B значение может быть OUI или NON, строки для перемещения - это строки со значением OUI. Столбцы B, D, F в U, V в AB и AE из "A PLANIFIER" в H, J, L в AA, AM в AS и BL из "MASTER" соответственно.

Я изменил скрипт в ответе SputnikDrunk2 с помощью функции moveTo(), которая отлично работает, потому что она также передает комментарии, но недостатком является то, что она портит условное форматирование целевого листа. Поэтому я использовал функцию copyTo(), которая тоже работает очень хорошо, но ее недостатком является то, что комментарии не импортируются.

Я попробовал несколько решений с setComment() и getComment(), но я действительно не могу этого сделать.

Может ли кто-нибудь помочь мне понять мою ошибку?

Мой лист В проекте сценария имя: Transfert Client Planifié.gs

Мой сценарий:

function transferData() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sourceSheet = ss.getSheetByName("A PLANIFIER");
  var targetSheet = ss.getSheetByName("MASTER");
  // Retrieve the sheet row numbers with 'OUI' data & place in an array
  var ouiData = sourceSheet.getDataRange().getValues().map((x, i) => [i + 1, x[1]]).filter(x => x[1] == 'OUI');
  // Get the next empty row from the target sheet [reference: https://stackoverflow.com/a/56080850/15384825]
  var targetSheetNextRow = targetSheet.getRange(1, 8).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow() + 1;

  ouiData.forEach(y => {
    var row = y[0];

    sourceSheet.getRange("B" + row).copyTo(targetSheet.getRange("H" + targetSheetNextRow), {contentsOnly:true});
    sourceSheet.getRange("D" + row).copyTo(targetSheet.getRange("J" + targetSheetNextRow), {contentsOnly:true});
    sourceSheet.getRange("F" + row + ":U" + row).copyTo(targetSheet.getRange("L" + targetSheetNextRow + ":AA" + targetSheetNextRow), {contentsOnly:true});
    sourceSheet.getRange("V" + row + ":AB" + row).copyTo(targetSheet.getRange("AM" + targetSheetNextRow + ":AS" + targetSheetNextRow), {contentsOnly:true});
    sourceSheet.getRange("AE" + row).copyTo(targetSheet.getRange("BL" + targetSheetNextRow), {contentsOnly:true});

    // Delete transferred values from source sheet
    sourceSheet.getRange("B" + row + ":AE" + row).clearContent();

    // Update the next empty row on the target sheet
    targetSheetNextRow = targetSheetNextRow + 1;

  }
  )

  sortM();
  sortAP();
}

Я нашел это решение:

function transferData() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sourceSheet = ss.getSheetByName("A PLANIFIER");
  var targetSheet = ss.getSheetByName("MASTER");
  // Retrieve the sheet row numbers with 'OUI' data & place in an array
  var ouiData = sourceSheet.getDataRange().getValues().map((x, i) => [i + 1, x[1]]).filter(x => x[1] == 'OUI');
  // Get the next empty row from the target sheet [reference: https://stackoverflow.com/a/56080850/15384825]
  var targetSheetNextRow = targetSheet.getRange(1, 8).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow() + 1;

  ouiData.forEach(y => {
    var row = y[0];

    sourceSheet.getRange("B" + row).moveTo(targetSheet.getRange("H" + targetSheetNextRow));
    sourceSheet.getRange("D" + row).moveTo(targetSheet.getRange("J" + targetSheetNextRow));
    sourceSheet.getRange("F" + row + ":U" + row).moveTo(targetSheet.getRange("L" + targetSheetNextRow + ":AA" + targetSheetNextRow));
    sourceSheet.getRange("V" + row + ":AB" + row).moveTo(targetSheet.getRange("AM" + targetSheetNextRow + ":AS" + targetSheetNextRow));
    sourceSheet.getRange("AE" + row).moveTo(targetSheet.getRange("BL" + targetSheetNextRow));

    // Clear format of the target sheet
    targetSheet.getRange("H" + targetSheetNextRow + ":BL" + targetSheetNextRow).clearFormat();

    // Update the next empty row on the target sheet
    targetSheetNextRow = targetSheetNextRow + 1;

    // Keep the format of the target line
    var rng = targetSheet.getRange("A7:CL7")
    rng.copyTo(targetSheet.getRange("A6:CL200" + row), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
    rng.copyTo(targetSheet.getRange("A6:CL200" + row), SpreadsheetApp.CopyPasteType.PASTE_CONDITIONAL_FORMATTING, false);

    // Keep the format of the source line
    var rng = sourceSheet.getRange("A50:AG50")
    rng.copyTo(sourceSheet.getRange("A6:AG50" + row), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
    rng.copyTo(sourceSheet.getRange("A6:AG50" + row), SpreadsheetApp.CopyPasteType.PASTE_DATA_VALIDATION, false);
  }
  )

  sortM();
  sortAP();
}

Пожалуйста, подумайте о том, чтобы задать подмножество вопросов, и из ответа вы сможете получить остальные. В противном случае просто делали всю вашу работу за вас. Мне неинтересно. Я мог бы это сделать. Я просто не хочу.

Cooper 30.03.2023 21:35

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

JLMosher 30.03.2023 21:44

@JLMosher В настоящее время я следую вашим предложениям, и для функции вставки вы предлагаете copyTo () вместо moveTo ()?

Mozart75 01.04.2023 01:21

Я бы избегал методов .moveTo() и .copyTo() по многим причинам и обрабатывал все с помощью .getValues() и .getNotes(), перебирал массив значений с помощью .forEach(), строил массивы значений и заметок, а затем используйте ,setValues().setNotes() для обновления целевых ячеек назначения. это может быть более эффективным и не будет мешать условному форматированию.

JLMosher 03.04.2023 16:01

@JLMosher Но Note и Comment в Google Sheets разные. Мне нужно скопировать/вставить комментарии

Mozart75 03.04.2023 16:14

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

JLMosher 03.04.2023 16:20

@JLMosher Думаю, я нашел решение, вы можете увидеть его наверху.

Mozart75 03.04.2023 18:04
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
7
130
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ПРЕДПОЛОЖЕНИЕ

Примечание. Обратите внимание, что мы не пишем код за вас, но вы можете использовать приведенный ниже измененный скрипт, который поможет вам в вашем реальном проекте.

При проверке вашего скрипта ваш цикл прерывается после первой строки данных, поэтому он перемещает только одну строку. Возможно, вы можете протестировать этот измененный скрипт ниже, где он специально собирает строки листа на A PLANIFIER с данными «OUI» в массив и выполняет цикл через forEach(). Я добавил несколько комментариев к сценарию для большего контекста.

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

Скрипт

function transferData() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sourceSheet = ss.getSheetByName("A PLANIFIER");
  var targetSheet = ss.getSheetByName("MASTER");
  // Retrieve the sheet row numbers with 'OUI' data & place in an array
  var ouiData = sourceSheet.getDataRange().getValues().map((x, i) => [i + 1, x[1]]).filter(x => x[1] == 'OUI');
  // Get the next empty row from the target sheet [reference: https://stackoverflow.com/a/56080850/15384825]
  var targetSheetNextRow = targetSheet.getRange(1, 8).getDataRegion(SpreadsheetApp.Dimension.ROWS).getLastRow() + 1;

  ouiData.forEach(y => {
    var row = y[0];

    sourceSheet.getRange("B" + row).moveTo(targetSheet.getRange("H" + targetSheetNextRow));
    sourceSheet.getRange("D" + row).moveTo(targetSheet.getRange("J" + targetSheetNextRow));
    sourceSheet.getRange("F" + row + ":U" + row).moveTo(targetSheet.getRange("L" + targetSheetNextRow + ":AA" + targetSheetNextRow));
    sourceSheet.getRange("V" + row + ":AB" + row).moveTo(targetSheet.getRange("AM" + targetSheetNextRow + ":AS" + targetSheetNextRow));
    sourceSheet.getRange("AE" + row).moveTo(targetSheet.getRange("BL" + targetSheetNextRow));

    // Update the next empty row on the target sheet
    targetSheetNextRow = targetSheetNextRow + 1;

    // Keep the format of the source line
    var rng = sourceSheet.getRange("A50:AG50")
    rng.copyTo(sourceSheet.getRange("A6:AG50" + row), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
  }
  )

  sortM();
  sortAP();
}

Демо

После запуска скрипта:

Рекомендации

Спасибо SputnikDrunk2, этот скрипт работает очень хорошо и намного быстрее. Я искал альтернативу moveTo(), потому что эта функция работает очень хорошо, но имеет недостаток, она полностью отключает условное форматирование целевого листа (MASTER).

Mozart75 01.04.2023 20:32

Другие вопросы по теме