#google_spreadsheet #google_apps_script
Именно сегодня перестала работать функция - вставить результат вычисления формулы как значения. (В Google Apps Scripts, Google Spreadsheets). На сейчас эта функция работает как clearContents() - просто затирает все значения. Пример: function myFunction() { var ss = SpreadsheetApp.getActiveSpreadsheet() var sheet = ss.getActiveSheet() var range = sheet.getRange("A1:C3") range.setFormula("=1+2") range.copyTo(range, {contentsOnly:true}) //Или так: //range.copyValuesToRange(sheet, range.getColumn(), range.getLastColumn(), range.getRow(), range.getRowIndex()) //range.copyTo(range, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false) } Можно использовать другие методы, поколдовав с форматами, но почему же перестало работать?? range.setValue(range.getValues()) range.setValue(range.getDisplayValues())
Ответы
Ответ 1
Вдруг кому интересно будет не смотря на минусовой вопрос: Необходимо добавить перед range.copyTo(range, {contentsOnly:true}) SpreadsheetApp.flush() Согласно документации, этот метод применяет все ожидающие изменения в таблице Applies all pending Spreadsheet changes. То есть, как я понимаю, ранее, при вызове copyTo, google перед тем, как брать данные из ячеек, сам применял все изменения (высчитывал результаты формул), а после этого уже делал копирование. Сейчас же нужно этот момент задавать вручную. UPD1: Согласно комментарию oshliaer, можно и Sheets API использовать. Насколько я понимаю, код будет где-то такой: // ss = SpreadsheetApp.getActiveSpreadsheet() // sheet = ss.getSheetByName("NAME") //Для примера: range = sheet.getRange("A1:C") function killAllFormulas2(ss, sheet, range) { // Обязателен вызов flush(), иначе если вы только вставили сложные формулы и сразу захотели вставить результаты вычисления как значения - они могут не успеть обновить данные в ячейках SpreadsheetApp.flush() // Получаем ID вашего Spreadsheet var ssID = ss.getId() // Если выбран такой диапазон как в примере - его обязательно нужно перевести в вид A1:C1000 (условно) var rangeA1 = sheet.getRange(range.getRow(), range.getColumn(), range.getLastRow()-range.getRow()+1, range.getLastColumn()-range.getColumn()+1).getA1Notation() // Получаем значения var values = Sheets.Spreadsheets.Values.get(ssID, sheet.getName() + "!" + rangeA1) // Вставляем значения Sheets.Spreadsheets.Values.update(values, ssID, sheet.getName() + "!" + rangeA1, {valueInputOption:"USER_ENTERED"}) } В примерах, которые встречаются вот здесь указано, что для большинства случаев использования лучше использовать стандартные методы встроенного SpreadsheetApp (например цитата для записи данных: This code uses the Sheets Advanced Service, but for most use cases the built-in method SpreadsheetApp.getActiveSpreadsheet().getRange(range).getValues(values) is more appropriate. По скорости работы я проверял на некоторых диапазонах со сложными формулами - разницы вообще не увидел. Скорее всего это все один и тот же алгоритм. Надеюсь, этот ответ поможет кому-то не тратить драгоценное время на поиски истины.
Комментариев нет:
Отправить комментарий