У меня есть скрипт для перемещения строк на другой лист, он работает, но не полностью, как хотелось бы.
У меня есть электронная таблица с 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();
}
Я бы предложил использовать другую стратегию. Перебор и получение каждой строки по отдельности не очень эффективно. Например, вы можете получить все значения диапазона с помощью range.getValues() и примечания с помощью range.getNotes(), затем перебрать массив значений и построить новый массив значений и массив заметок, а затем установить массивы значений и заметок в нужные новые диапазоны.
@JLMosher В настоящее время я следую вашим предложениям, и для функции вставки вы предлагаете copyTo () вместо moveTo ()?
Я бы избегал методов .moveTo() и .copyTo() по многим причинам и обрабатывал все с помощью .getValues() и .getNotes(), перебирал массив значений с помощью .forEach(), строил массивы значений и заметок, а затем используйте ,setValues().setNotes() для обновления целевых ячеек назначения. это может быть более эффективным и не будет мешать условному форматированию.
@JLMosher Но Note и Comment в Google Sheets разные. Мне нужно скопировать/вставить комментарии
а, да вы правы. Вот почему я никогда не использую комментарии для чего-либо, с чем нужно программно взаимодействовать. вы не сможете делать то, что пытаетесь, не нарушая условное форматирование, а также любые ссылки на ячейки формул на вашем листе с помощью методов перемещения и копирования.
@JLMosher Думаю, я нашел решение, вы можете увидеть его наверху.
Примечание. Обратите внимание, что мы не пишем код за вас, но вы можете использовать приведенный ниже измененный скрипт, который поможет вам в вашем реальном проекте.
При проверке вашего скрипта ваш цикл прерывается после первой строки данных, поэтому он перемещает только одну строку. Возможно, вы можете протестировать этот измененный скрипт ниже, где он специально собирает строки листа на 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).
Пожалуйста, подумайте о том, чтобы задать подмножество вопросов, и из ответа вы сможете получить остальные. В противном случае просто делали всю вашу работу за вас. Мне неинтересно. Я мог бы это сделать. Я просто не хочу.