I need to copy and paste Formulas only in a spreadsheet using Google Apps Script
var range = activeSheet.getRange(targetRow-1, 1, 1, activeSheet.getLastColumn());
range.copyTo(activeSheet.getRange(targetRow, 1, 1, activeSheet.getLastColumn()), {contentsOnly:false});
This give me the full information, including the formulas and data. However, I wish to only copy the formulas (without data).
CopyFormulasToRange
unfortunately does not exists.
Use getFormulasR1C1 and setFormulasR1C1 to copy formulas and preserve relative references. For example:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var currentRow = sheet.getLastRow();
var sourceRange = sheet.getRange(currentRow, 3, 1, 4);
var sourceFormulas = sourceRange.getFormulasR1C1();
currentRow++;
var targetRange = sheet.getRange(currentRow, 3, 1, 4);
targetRange.setFormulasR1C1(sourceFormulas);
https://developers.google.com/apps-script/reference/spreadsheet/range#getformular1c1 https://developers.google.com/apps-script/reference/spreadsheet/range#setformulasr1c1formulas
The following function will copy formulas only. It has user settings for what row and column to start getting the formulas from.
function copyFormulas() {
var activeSheet,numberOfSourceColumnsToGet,sourceColumnStart,sourceFormulas,sourceRange,
sourceRowStart,targetColumn,targetRange,targetRowStart;
//USER INPUT
sourceRowStart = 1; //Row to start getting formulas from
sourceColumnStart = 2; //Column to start getting formulas from
numberOfSourceColumnsToGet = 1; //Number of columns to get formulas from
targetRowStart = 1; //Row to start copying formulas to
targetColumn = 3; //Column to start copying formulas to
//END OF USER INPUT
activeSheet = SpreadsheetApp.getActiveSheet();
sourceRange = activeSheet.getRange(sourceRowStart, sourceColumnStart, activeSheet.getLastRow(), numberOfSourceColumnsToGet);
sourceFormulas = sourceRange.getFormulas();//Get only formulas from the source range
targetRange = activeSheet.getRange(targetRowStart,targetColumn,sourceFormulas.length,sourceFormulas[0].length);
targetRange.setFormulas(sourceFormulas);//Copy the formulas to the target range
}
I found this question while trying to figure out how to copy just the formulas from one row into another row. This is the very common pattern of adding a row to a spreadsheet to add another data set, where each set is a single row and some of the columns in that row are computed values. You want all of copied formulas to reference values in the new row, not the row from which the formulas were copied.
@AllenWell's answer copies the formulas, but for me at least, doesn't update the cell references to reference cells in the new row. With his code, the copied formulas still refer to the row from which the formulas were copied. I have since learned that the secret here is to use get/setFormulasR1C1
rather than get/setFormulas
because the latter uses relative references such that formulas reference values in whatever row they're in.
@MarkBird's answer uses get/setFormulasR1C1
but doesn't work for me. It seems to put something in every cell of the new row because it does a copy even for columns that do not contain formulas. This screws up my logic, where I have formulas that put results in multiple columns, but only if they're blank. His code could work fine in simpler cases, but it would be better if it only copied formulas. That's what my solution does.
I wrote a more complex function that copies only the formulas in such a way that the formulas reference values in the new row. I grab all the formulas and then selectively copy them to the new row, skipping empty spots in the list of formulas. This gave me the behavior I wanted and I think what most people want when they want to create a new row in a spreadsheet. Here is the function that does this. it takes a Sheet
reference and the indexes of the source and destination rows:
function copyFormulas(sheet, sourceRow, targetRow) {
var formulas = sheet.getRange(sourceRow, 1, 1, sheet.getLastColumn()).getFormulasR1C1()[0];
for (var i = 0; i < formulas.length; i++) {
if (formulas[i] !== '') {
sheet.getRange(targetRow, i + 1).setFormulaR1C1(formulas[i]);
}
}
}
Notice the test for if the formula is empty. I think this is what is missing from @MarkBird's simpler solution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.