I have a sheet "SourceData" that has a lot of formulas to develop a proposal price based on variables entered on the sheet "Inputs". I need script to generateNewScope, where the "SourceData" sheet is duplicated, formulas removed from the duplicate, and it's renamed from "Copy of SourceData" to 1, then 2, then 3, etc.
I'm close! I can duplicate and rename, and I've gotten a different script to the point where it removes the formulas, but that one removed formulas from both "SourceData" AND "1". I just need to add additional actions here that essentially copy/paste values only directly in the same spot, or just a remove formulas action.
function generateNewScope() {
ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("SourceData"));
var ns = ss.duplicateActiveSheet(),
allSheets = ss.getSheets();
ns.setName(allSheets.length - 4);
}
You want to copy a sheet in a Spreadsheet.
You want to copy only values without the formulas.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this modification?
Modification points:
In this modification, your script is modified.
Only values are copied using copyTo() after the sheet was copied.
Modified script:
function generateNewScope() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("SourceData"));
var ns = ss.duplicateActiveSheet();
var range = ns.getDataRange(); // Added
range.copyTo(range, {contentsOnly: true}); // Added
allSheets = ss.getSheets();
ns.setName(allSheets.length - 4);
}
Reference:
copyTo()
If I misunderstood your question and this was not the result you want, I apologize.
Related
I have the following that works fine:
function phototable() {
var ss = SpreadsheetApp.openById('####');
var lastRow = ss.getLastRow();
ss.getRange('H'+lastRow)
.setValue('=VLOOKUP("Form Responses_Images/"&B'+lastRow+',importrange("https://docs.google.com/spreadsheets/d/####/edit","Form Responses!U:Z"),4,false)');
}
However, I don't want the formula copied into column H, just the actual value. So I tried:
ss.getRange('H'+lastRow)
.getValue('=VLOOKUP("Form Responses_Images/"&B'+lastRow+',importrange("https://docs.google.com/spreadsheets/d/###/edit","Form Responses!U:Z"),4,false)')
.copyTo('H'+lastRow,{contentsOnly:true});
But that doesn't insert anything into column H. Any ideas?
Modification points:
About I have the following that works fine:, when I saw the above script, I think that an error occurs at getValue. Because getValue has no arguments. I thought that getValue was setValue.
At copyTo('H'+lastRow,{contentsOnly:true}), the 1st argument is thr range object.
In order to copy the result of the formula during the script as the string, it is required to use flush.
When above points are reflected to your script, it becomes as follows.
Modified script:
function phototable() {
var ss = SpreadsheetApp.openById('####');
var lastRow = ss.getLastRow();
var range = ss.getRange('H'+lastRow);
range.setValue('=VLOOKUP("Form Responses_Images/"&B'+lastRow+',importrange("https://docs.google.com/spreadsheets/d/###/edit","Form Responses!U:Z"),4,false)');
SpreadsheetApp.flush();
range.copyTo(range, {contentsOnly:true});
}
Note:
In your script, ss is the 1st tab of the Spreadsheet. Please be careful this.
References:
flush()
copyTo(destination, options)
Issues / Explanation:
You have 2 ways to update the cell in column H with the value of the formula:
If you want to update the cell in H with its value then get the value and set it back:
range.setValue(range.getValue());
Use the copyTo() method:
range.copyTo(range, {contentsOnly:true});
As a bonus information, copyTo() can not be used if the source range and the target range are not of the same spreadsheet file.
Since this process happens really fast, it is a good idea to use flush() for the pending sheet changes to be completed.
Solution:
function phototable() {
var ss = SpreadsheetApp.openById('####').getSheetByName('Sheet1');
var lastRow = ss.getLastRow();
var range = ss.getRange('H'+lastRow);
range.setValue('=VLOOKUP("Form Responses_Images/"&B'+lastRow+',importrange("https://docs.google.com/spreadsheets/d/####/edit","Form Responses!U:Z"),4,false)');
SpreadsheetApp.flush();
range.setValue(range.getValue());
// range.copyTo(range, {contentsOnly:true}); // choose this or the previous line
}
Modify Sheet1 to the name of the sheet you want to apply this operation.
Also it is a better practice to choose a particular sheet before you apply any function to it. To get a sheet by its name use getSheetByName().
I selected manually a range of data and want to press a button to copy those data to after the last row of data in the same sheet using Google Apps Script but not working at all. How to fix it? The codes are:
var listToCopy = SpreadsheetApp.getActiveSheet().getActiveRange();
var height = listToCopy.getHeight();
var destRow = listToCopy.getLastRow()+1;
listToCopy.copyTo(spreadsheet.getRange(destRow, 0, height));
I believe your goal as follows.
You want to copy the selected range to the last row of the same sheet using Google Apps Script.
For this, how about this answer?
Modification points:
In the case of var destRow = listToCopy.getLastRow()+1;, the last row of the range of listToCopy is retrieved.
In your case, the last row of the sheet is required to be retrieved.
The source range can be copied to the destination range as the start range like getRange(destRow, 1).
The 1st number of range is 1.
spreadsheet is not declared.
When above points are reflected to your script, it becomes as follows.
Modified script:
In order to use this script, please select the range and run the function of myFunction. By this, the selected range is copied to the last row of the same sheet.
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var listToCopy = sheet.getActiveRange();
var destRow = sheet.getLastRow() + 1;
listToCopy.copyTo(sheet.getRange(destRow, 1));
}
References:
getLastRow() of Class Sheet
copyTo(destination)
I have a script to copy values from one sheet to another that works perfectly except I only want to clear the values in the source sheet, and leave the formula in place in cells E3, I3 and J3
function addLeavers()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange("Add Leaver!A3:AM3");
var destSheet = ss.getSheetByName("Leavers");
destSheet.appendRow(source.getValues()[0]);
source.clear();
}
You want to clear the range of source.
You want to clear only values of the range.
You don't want to clear the formulas of the range..
If my understanding is correct, how about this modification? Please think of this as just one of several answers.
In this modification, the formulas are retrieve, and the range is clear using clear() or clearContent(). Then, the retrieved formulas are put to the range.
From:
source.clear();
To:
var formulas = source.getFormulas();
source.clear(): // or source.clearContent();
source.setFormulas(formulas);
References:
clearContent()
getFormulas()
setFormulas()
If I misunderstood your question and this was not the result you want, I apologize.
I have this script running nicely on Google Sheets:
function recordMax() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("K16:L16");
var values = range.getValues()[0];
range.setValues([[values[0], Math.max(values[0], values[1])]]);
}
But, I have this effect here http://screencast.com/t/BOXzC0UZxFZ (short 1 min video show you the issue). Summary of the issue is that when the script runs in forces K16 to just show the current value of the formula and strips out the =sum formula I have in K16.
What do you think I need to do so that when the script runs, it will not automatically strip the K16 formula so K16 will continue updating to new values?
:)
How about the following modification?
Modification point :
In order to retrieve formulas in the cells, it uses getFormulas().
Insert the retrieved formulas.
Modified script :
In the most cases, the following modified script can be used. I think that in your case, the following modified script can be used.
function recordMax() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("K16:L16");
var formula = range.getFormulas()[0]; // Added
var values = range.getValues()[0];
range.setValues([[formula[0], Math.max(values[0], values[1])]]); // Modified
}
There are sometimes the case that it requires to insert the formula using setFormula() as follows.
function recordMax() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("K16:L16");
var formula = range.getFormulas()[0]; // Added
var values = range.getValues()[0];
sheet.getRange("K16").setFormula(formula[0]); // Added
sheet.getRange("L16").setValue(Math.max(values[0], values[1])); // Added
}
Reference :
getFormula()
getFormulas()
setFormula(formula)
setFormulas()
If I misunderstand your question, please tell me. I would like to modify.
I am able to copy a range of values from one spreadsheet to another with Range.setValues(values) but not with Range.copyValuesToRange(sheet, column, columnEnd, row, rowEnd):
function test()
{
var sourceSheet = SpreadsheetApp.getActiveSheet();
var sourceCols = sourceSheet.getRange("A1:B10");
// Copying the first two columns this way works.
var sheet1 = SpreadsheetApp.create("New Spreadsheet 1").getActiveSheet();
sheet1.getRange("A1:B10").setValues(sourceCols.getValues());
// Copying the first two columns this way does not work.
var sheet2 = SpreadsheetApp.create("New Spreadsheet 2").getActiveSheet();
sourceCols.copyValuesToRange(sheet2, 1, 2, 1, 10);
}
Specifically, after running the code, New Spreadsheet 1 contains range A1:B10 of the source spreadsheet, while New Spreadsheet 2 is empty. Both have a single sheet named "Sheet1". The source spreadsheet is unmodified.
What am I doing wrong? I'm wondering if the failing method only works within a single spreadsheet, but I see nothing in the documentation about that.
The reason I want to use Range.copyValuesToRange() is so I can also copy the formatting with Range.copyFormatToRange().
The methods copyValuesToRange and copyFormatToRange, as well as Range.copyTo, are restricted to copying within the same spreadsheets, although documentation is not explicit about that. A workaround which allows you to copy between spreadsheets with formatting is to copy the entire sheet to the destination spreadsheet, using Sheet.copyTo method. Then copy the required range from there, and optionally, delete the sheet. Like this:
function cc() {
var ss1 = SpreadsheetApp.openByUrl('some url');
var ss2 = SpreadsheetApp.openByUrl('another url');
var sheet1 = ss1.getSheetByName('name');
var sheet2 = ss2.getSheetByName('another name');
// the above was the setup, main code begins here
var copySheet = sheet1.copyTo(ss2);
copySheet.getRange("A1:B2").copyTo(sh2.getRange("C1:D2"));
ss2.deleteSheet(copySheet);
}