Reputation: 1
I need to prepare an empty sheet to be the size of a SetValues.
Details
I'm trying to use this nice routine from clueless to make a values-only copy of a google sheet file including all tabs. (Ultimately I'll run it on a schedule and download it to microsoft cloud drive so I can access live from Power BI). Clueless uses hard-coded parameters TL and BR to represent the Top Left and Bottom Right of the ranges. Clueless starts by deleting any tab with a matching name in the destination sheet, thus starting with a new tab.
Unfortunately, my source sheet tabs' ranges are not all consistent. Some larger than TL BL and some smaller. Therefore I get either "...out of bounds..." errors or "The number of rows in the data does not match the number of rows in the range. " if I increase or decrease the TL and BL globals.
How to I solve this? Is there maybe a way to prepare the destination sheet, before SetValues, by making it's size match the source sheet GetDataRange size before SetValues is executed?
Thanks!
function update_view(dup_id="<spreadsheet_id>", TL="A1", BR="BE900") {
// Open current Sheet
var ss = SpreadsheetApp.getActiveSpreadsheet()
// Supply a duplicate google doc ID. This document will be exported to excel
var ds = SpreadsheetApp.openById(dup_id)
// UI element for notifying in the google sheets
var ui = SpreadsheetApp.getUi()
//Copy each sheet one by one
var sheets = ss.getSheets();
for (i=0; i<sheets.length; i++) {
src_sheet = sheets[i];
sheet_name = src_sheet.getName();
Logger.log(sheet_name);
// If same sheet exists in the destination delete it and create an empty one
dst_sheet = ds.getSheetByName(sheet_name);
if (dst_sheet != null) {
ds.deleteSheet(dst_sheet)
}
dst_sheet = ds.insertSheet(sheet_name);
//set column width correctly
for(j=1; j<=src_sheet.getLastColumn(); j++){
dst_sheet.setColumnWidth(j, src_sheet.getColumnWidth(j))
}
src_range = src_sheet.getRange(TL + ":" + BR);
dst_range = dst_sheet.getRange(TL + ":" + BR);
//Note: DisplayValues is set as Values, formulas are removed in dup sheet
dst_range.setValues(src_range.getDisplayValues());
//Nice to haves for formatting
dst_range.setFontColors(src_range.getFontColors());
dst_range.setFontStyles(src_range.getFontStyles());
dst_range.setBackgrounds(src_range.getBackgrounds());
dst_range.setHorizontalAlignments(src_range.getHorizontalAlignments());
dst_range.setVerticalAlignments(src_range.getVerticalAlignments());
dst_range.setWraps(src_range.getWraps());
dst_contents_range = dst_sheet.getDataRange();
dst_contents_range.setBorder(true, true, true, true, true, true);
}
//Completed copy, Now open the dup document and export.
ui.alert("Backup Complete, Please open " + dup_id + " sheet to view contents.")
}
Upvotes: 0
Views: 1413
Reputation: 1
Thanks @Ruben. That was helpful. using getNumRows() and getNumColumns() did it. For others here is the complete function. I also changed the name and replaced my file id with
function MakeCopyAsValues(dup_id="<google file id>") {
// Open current Sheet
var ss = SpreadsheetApp.getActiveSpreadsheet()
// Supply a duplicate google doc ID.
var ds = SpreadsheetApp.openById(dup_id)
// UI element for notifying in the google sheets
var ui = SpreadsheetApp.getUi()
//Copy each sheet one by one
var sheets = ss.getSheets();
for (i=0; i<sheets.length; i++) {
src_sheet = sheets[i];
sheet_name = src_sheet.getName();
// Logger.log(sheet_name); // this was helpful for debugging.
// If same sheet exists in the destination delete it and create an empty one
dst_sheet = ds.getSheetByName(sheet_name);
if (dst_sheet != null) {
ds.deleteSheet(dst_sheet)
}
dst_sheet = ds.insertSheet(sheet_name);
src_range = src_sheet.getDataRange(); //Get the source's range that has data.
dst_range = dst_sheet.getRange(1,1,src_range.getNumRows(), src_range.getNumColumns());
//Note: DisplayValues is set as Values, formulas are removed in dup sheet
dst_range.setValues(src_range.getDisplayValues());
//set column widths correctly. Moving this after the range setting prevents some errors.
for(j=1; j<=src_sheet.getLastColumn(); j++){
dst_sheet.setColumnWidth(j, src_sheet.getColumnWidth(j))
}
//Other Nice to haves for formatting
dst_range.setFontColors(src_range.getFontColors());
dst_range.setFontStyles(src_range.getFontStyles());
dst_range.setBackgrounds(src_range.getBackgrounds());
dst_range.setHorizontalAlignments(src_range.getHorizontalAlignments());
dst_range.setVerticalAlignments(src_range.getVerticalAlignments());
dst_range.setWraps(src_range.getWraps());
dst_contents_range = dst_sheet.getDataRange();
dst_contents_range.setBorder(true, true, true, true, true, true);
}
ui.alert("Backup Complete, Please open " + dup_id + " sheet to view contents.")
}
Upvotes: 0
Reputation: 38160
Instead of using A1 notation to get the range you might use getDataRange()
to grab the data range (the all the rows and columns having at least one cell with a value), then might use getNumRows()
, getNumColumns()
among other methods or use Array.prototype.length()
to get the range dimensions and grab a range of the same size from the destination sheet.
Resources
Related
Upvotes: 0