When I use copyTo to copy an entire sheet, drawings get copied but I don't want to copy the entire sheet so I tried to use copyTo on a range but drawings do not get copied. Anyone know if this is expected behavior or a bug? For example if a drawing is in A4 ...
function test() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var test1 = ss.getSheetByName("test1");
var test2 = ss.getSheetByName("test2");
// this does not copy drawing to sheet test2
var rangeToCopy = test1.getRange(1,1,5,1);
rangeToCopy.copyTo(test2.getRange(1,1));
// this copies drawing to new sheet Copy of test1
test1.copyTo(ss);
}
I realize there are two copyTo's, one for sheets and one for ranges, just would have expected they both should copy drawings.
no, it doesnt copy drawings. a big part of it is that drawings do not sit on a given cell or range.
you can confirm this by inserting rows above the drawing. sometimes google shifts the drawing down and sometimes doesnt, so it's not tied to specific rows, at least not strictly.
you can also confirm that copying ranges manually with the web interface also doesnt copy the drawings.
one solution is to convert the drawing to an image and host it somewhere (like a google sites cabinet with public access) and use cell formula `=IMAGE("http://path.to.image.png")' which will get copied.
another way if you must use drawings, is to copy the entire sheet into a new sheet, then manually copy the ranges that you didnt want to overwrite from your destination sheet, then delete the original destination sheet and rename the new sheet with the destination name.
Related
I am trying to write a script that will move data from one sheet to another and simultaneously transpose it. I need to use the same script on the same Input Range several times (with different data), so it needs to paste each set of data in the next available set of rows in the destination sheet.
I have looked extensively on the site for solutions, but I have only been able to find solutions for each of these functions separately. (Copy and Paste, Transpose, Only paste in next empty row, and date Timestamp)
The only code I have been working on if from the first of those, and is as follows;
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange("Import!E4:I41");
var destSheet = ss.getSheetByName("Database!E3:AP7");
destSheet.appendRow(source.getValues()[0]);
var destination = destSheet.getRange(destSheet.getLastRow(), 1); // Added
source.copyTo(destination, SpreadsheetApp.CopyPasteType.PASTE_VALUES) // Added
}
Happy to learn more and have any feedback from people who know better.
Example Sheet, with Ideal Solution
I'm making a spreadsheet to format the responses of a google form. However, this form will be given every week; ideally, I would like to import the form responses into this spreadsheet, have the formatted data sheet now use this new responses sheet instead of the older one, without having to update the formulae in the data sheet. But if I try to do this by renaming the new data sheet to what the old one was called, it keeps the old sheet reference and updates its name in all the formulae.
I haven't found any solutions from a few google searches. Is there an easy way to get around this?
EDIT: here is an example spreadsheet. Ideally, I want the data in 'Formatting Sheet' to be retrieved from 'New Sheet' instead of old sheet. However, I don't want to have to change all of the formulae in 'Formatting Sheet' to reflect this, as this will be a transition I do regularly. Unfortunately renaming the sheets preserves the reference.
You want to use the values at the sheet Formatting Sheet by replacing the values in the sheet Old Sheet with new values in the sheet New Sheet.
In your current issue, even when the sheet name is changed, the values cannot be updated.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
In your case, even when the sheet name is changed, the sheet ID is not changed. By this, the formula uses old values. I think that the reason of your issue is this. In this answer, in order to achieve your goal, Google Apps Script is used.
Flow:
The flow of the sample script is as follows.
Retrieve the sheet object of New Sheet and Old Sheet, which are the source sheet and destination sheet, respectively.
Backup Old Sheet.
In you don't want to backup it, please remove destinationSheet.copyTo(ss).setName(destinationSheet.getName() + "_backup_" + new Date().toISOString());.
Copy the values from New Sheet to Old Sheet. By this, the values are replaced. And at Formatting Sheet, the new values are used.
Sample script:
Please copy and paste the following sample script to the script editor of your shared Spreadsheet. And run myFunction().
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName("New Sheet");
var destinationSheet = ss.getSheetByName("Old Sheet");
// Backup "Old Sheet".
destinationSheet.copyTo(ss).setName(destinationSheet.getName() + "_backup_" + new Date().toISOString());
// Put values from "New Sheet" to "Old Sheet"
sourceSheet.getDataRange().copyTo(destinationSheet.getRange(1, 1));
}
When you run the script of myFunction(), you can see the result calculated by new values at the sheet of Formatting Sheet.
References:
copyTo() in Class Sheet
copyTo() in Class Range
I have a template spreadsheet and multiple copies of it. I need to be able to update the template spreadsheet's sheets (be it values or formulas) and quickly reflect theses changes across all the spreadsheet copies.
The obstables are:
The copy method does not work in this case because it only works within the same spreadsheet;
Copying an entire sheet also does not work because it breaks the charts (adding a new sheet, removing old one, renaming new sheet);
I tried to use getValues and getFormulas and then use the following code to have one complement the other:
var combined = []
for (cell in templateValues) {
var row = [];
if (templateValues[cell] == '') {
row.push(templateFormulas[cell])
} else {
row.push(templateValues[cell])
}
combined.push(row);
}
Logger.log(combined)
and then using
var targetRange = targetSheets[sheet].getRange(1, 1, combined.length, combined[0].length);
targetRange.setValues(combined);
to paste the values. That did not work (values weren't pasted in the right place nor were formulas).
Any ideas?
EDIT: Including some sample spreadsheets for clarity.
Source Spreadsheet and Target Spreadsheet.
Again, the point is that I can copy everything in the "SameSheet" sheet of the Source Spreadsheet to the "SameSheet" sheet of the Target Spreadsheet (in the actual use case it is a Drive folder with multiple target spreadsheets).
I have a big google sheet file with more thousand rows.
My goal is to create another smaller spreadsheet which imports a given line from the big database (just for show, I don't want to edit it oruse it) and after that I'd like to add some data to that given line.
I was able to do it with IMPORTRANGE function, but after I change to another row, the other rows I edited before don't keep the information I entered.
Also, I can't use my sheet to select a row in the big database and add a permanent data to it.
Do you have any idea how could I solve this problem? (Google script would be fine too, I really have no idea how to do this).
Thanks
Copy Selected Row
From one spreadsheet to another.
function copySelectedRow(){
var ss1=SpreadsheetApp.getActive();
var sh1=ss1.getSheetByName('Data');//Change data to the name of the sheet that you wish to copy from in ss1
var rg1=sh1.getRange(sh1.getActiveCell().getRow(),1,1,sh1.getLastColumn());//Select a cell in the row that you wish to copy and then run this function.
var vA1=rg1.getValues();
var ss2=SpreadsheetApp.openById('ID of Spreadsheet Copying To');
var sh2=ss2.getSheetByName('Data');//Change data to the name of the sheet that you wish to copy to in ss2
sh2.appendRow(vA1[0]);
}
I'm trying to create a script that upon opening copies formulas down to the end of the data.
Obviously the formulas themselves contain both relative and absolute addressing and that will need to be maintained.
IE, one formula might look like:
=if($C2="no", "no", VLOOKUP(concatenate($A2,$B2,$C2),'v2'!$A$2:$CN,MATCH(H$1,'v2'!$B$1:$CN$1,0)+1,FALSE))
The formulas stretch across many columns and the amount of columns might also change over time. So creating a custom action for each column is not possible.
Here is what I got so far:
var target_book = SpreadsheetApp.getActiveSpreadsheet();
var source_sheet = target_book.getSheetByName("most_recent");
var rows = source_sheet.getLastRow();
var cols = source_sheet.getLastColumn();
var formulas = source_sheet.getRange("C2:CI2").getFormulas();
source_sheet.getRange(3,3,rows -3, cols-2).setFormulas(formulas);
I have tried variations of the getFormulas function.
1) If I use getFormulas or getFormulasR1C1 it copies ALL formulas. It then also pastes all the formulas into each and every destination cell.
2) IF I use getFormula or getFormulaR1C1 it ends up copying the first formula from the range and pastes that into every cell in the target range.enter code here
I'm a bit at a loss, I just want to do the most basic copy and paste, updating the relative addressing. Is that possible somehow?
Thanks,
Chris
You may want to look at copyTo(), which will copy cells in the same way as if you were copying and pasting manually in the spreadsheet (absolute and relative referencing will be respected).