Google App Script - Custom Importrange Function, Need Auto-Update - javascript

I am porting data from 9 different Google Sheets to a master overview dashboard to track company metrics. Instead of using ImportRange, I created a custom function with Google Apps Script because I need all the formatting to come with it. The sheet that I want to copy over uses formulas, so I first create a copy of the sheet in the source spreadsheet without formulas and then copy that sheet over to the destination spreadsheet.
The nice thing about ImportRange is that it is constantly fetching the data and auto-updating. The function I wrote below creates and deletes sheets to get the formatting to port over to the masterSS. Is there a work around that anyone can think of to just get the values to auto-update, without having to create and delete a bunch of new sheets?
Also, everytime I create and delete a new sheet, the sheet count increases by 1. Is there a way to reset this counter?
function importPortComp(portComp, srcRange, destRange) {
// Create temporary sheet in source spreadsheet
var tempSheet = portComp.insertSheet();
// Copy values, formatting, and column widths to temporary sheet
srcRange.copyTo(tempSheet.getRange(1, 1), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
srcRange.copyTo(tempSheet.getRange(1, 1), SpreadsheetApp.CopyPasteType.PASTE_FORMAT, false);
srcRange.copyTo(tempSheet.getRange(1, 1), SpreadsheetApp.CopyPasteType.PASTE_COLUMN_WIDTHS, false);
// Copy temporary sheet destination spreadsheet
var copiedSheet = tempSheet.copyTo(masterSS);
// Delete temporary sheet from source spreadsheet
portComp.deleteSheet(tempSheet);
// Copy source range to destination range
copiedSheet.getRange(srcRange.getA1Notation()).copyTo(destRange);
copiedSheet.getRange(srcRange.getA1Notation()).copyTo(destRange, SpreadsheetApp.CopyPasteType.PASTE_COLUMN_WIDTHS, false);
// Delete copied sheet from T/R spreadsheet
masterSS.deleteSheet(copiedSheet);
}

if I correctly understand your question:
use:
array = sheet.getSheetValues(startRow, startColumn, numRows, numColumns)
to get the values
then push to the array at the correct index (I guess it's array[row][column])the other datas you want to "concat/add" set the correct range and the use
sheet.range.setValues(array)
you can check this documentation

Related

Google Apps Script - copying TextStyles fails with Exception

I am writing GAS script that copys some sheets from one spreadsheet to another - can't use copyTo as I don't want all the named ranges pulled in, for one thing.
A script gets data from one sheet, creating a sheet object, including the initializer:
textStyles: sheet.getLastColumn() != 0 ? sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getTextStyles() : [[]],
another script copies the sheet info into a new sheet ...
newSheet.sheet.getRange(newSheet.sheetRange).setTextStyles(newSheet.textStyles);
which results in the error
Exception: The parameters (number[]) don't match the method signature for SpreadsheetApp.Range.setTextStyles.
I copied oldsheet -> newsheet using let newSheet = JSON.parse(JSON.stringify(oldSheet));
but I have tried :
newSheet.sheet.getRange(newSheet.sheetRange).setTextStyles(oldSheet.textStyles);
with the same result.
Any ideas what I am doing wrong, please?

Using Google Apps Script, how can I replace text in a Google Sheets template to make a new Sheet?

I have a Google Sheet which is being populated by a Google Form. I am using Google Apps Script to add some extra functionality. Please feel free to access and modify these as needed in order to help.
My goal is to be able to take responses from a Google Form, have that come into a Google Sheet, and then, using a template file, populate the template with the responses and have that sent out as an email attachment to whomever I specify.
This is a dumbed down version of my ultimate project, but the process should remain the same so that I can transpose from this small scale example to that bigger one.
Currently, in my Apps Script, I have code which is successfully able to make a copy of the template file and name it accordingly:
//Enter collected info into Requirements Template
const googleSheetTemplate = DriveApp.getFileById('1wqCwMhpuDLReU1hE1CbcDL-Vdw_4zge1xM6oOl34Ohg');
const destinationFolder = DriveApp.getFolderById('1GxNZQmP8mxHBhVl5AMoqBFs8sAIYzcm3');
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses 2');
const copy = googleSheetTemplate.makeCopy(`${row[3]}, ${row[0]} Vehicle Order` , destinationFolder);
const newSheet = SpreadsheetApp.openById(copy.getId());
const A1 = newSheet.getActiveRange();
But the next few lines which are meant to be able to find and replace certain strings within the newly copied Sheet does not seem to function properly.
A1.createTextFinder("{{Customer}}").replaceAllWith(row[3]);
A1.createTextFinder("{{Car}}").replaceAllWith(row[1]);
A1.createTextFinder("{{Color}}").replaceAllWith(row[2]);
A1.createTextFinder("{{Delivery}}").replaceAllWith(row[5]);
I just get the same dummy lines back in the new copy.
I was following another post which I found on a different issue but with the same goal. The majority of the concept I was looking to copy came from this blog post, but where they used a Google Doc, I was hoping to use a Google Sheet. Ultimately, the person that receives this new sheet will need to do some calculations and things with the provided information, so it still needs to be in Sheet form.
What modifications do I need to make in order to successfully replace the text in the template with the answers provided from the Google Form responses?
As far as I can tell, this line means some cells on the sheet were selected:
const A1 = newSheet.getActiveRange();
And script will search and replace within these cells only.
Probably you need to define the range with no reference on active range. Something like this:
const A1 = newSheet.getRange("A1:A"); // or "A1:Z", or .getDataRange()
I don't know what the range you need.
From the documentation, createTextFinder(findText) only works on a Sheet class, this means you need to define a Sheet variable before replacing text:
const copy = googleSheetTemplate.makeCopy(`${row[3]}, ${row[0]} Vehicle Order` , destinationFolder);
const newSheet = SpreadsheetApp.openById(copy.getId()).getSheets()[0];
newSheet.createTextFinder("{{Customer}}").replaceAllWith(row[3]);
newSheet.createTextFinder("{{Car}}").replaceAllWith(row[1]);
newSheet.createTextFinder("{{Color}}").replaceAllWith(row[2]);
newSheet.createTextFinder("{{Delivery}}").replaceAllWith(row[5]);

Creating a new menu and an item right under it for uploading excel template in google sheet(Javascript)

I created an item named “import” under the menu “database” in my google sheet. What I want to execute with this item is that the excel file, with two columns only, can be uploaded and the values nested within them can be stored in an array without appending a new spreadsheet for this excel file. However, I got stuck in “how to upload excel file” this way. After loading the array with the newly uploaded data, another function will be called to add the name-style pair which doesn’t exist in sheet 1 from the array to the unoccupied cells. So this item is designed for updating the sheet1 automatically.
function interface() {
var ui = SpreadsheetApp.getUi();
var menu=ui.createMenu("Data base")
menu.addItem("Import","cal")
menu.addToUi()
}
function onOpen(){
interface()
}
function cal() {
var ss = SpreadsheetApp.getActive().getSheetByName("updated list");// I don't know how to accomplish this part so I created a sheet to store the data as an alternative for the time being.
var lastRow=ss.getLastRow()
var dataBase=ss.getRange(2,1,lastRow,1).getValues()// I want to store the valuse nested within this two columns but there is an error when I use "indexOf" to pick out the data which doesn't exist in sheet1 and push it to the unoccupied cells so I only take one column of values here(Making it one level deep only).
var dataBase2=ss.getRange(2,2,lastRow,1)
var ss1 = SpreadsheetApp.getActive().getSheetByName("sheet1")
var lastRow1=ss1.getLastRow();
var storedData=ss1.getRange(2,1,lastRow1,1).getValues()// Faced with the same problem as described above.
for(var i=0; i<lastRow1;i++){
if(storedData.indexOf(dataBase[i])==-1){
var counter=1
ss1.getRange(lastRow1+counter,1),setValue=dataBase[i]
ss1.getRange(lastRow1+counter,1),offset(0,1),setValue=dataBase2[i]// The error "offset is not defined" shows up here
Logger.log(ss1.getRange(lastRow1+counter,1),setValue=dataBase[i])
counter++
}
}
}
Sheet1 is the worksheet used for looking up who takes charge of which style
Updated list contains the data which I want to add to the array
The logic is that me and my team mates can just take a look at the sheet1 to look for the merchandiser(Name) to know the style he or she takes charge of. But this list should be updated at least once a week. So I wonder if it's possible to automatically add the names and styles in the "updated list" to sheet1 when there is no match found.
For example:
Jason S55567899 and
Nick Jack52578 should be added into worksheet1 right below the last occupied row since these two styles don't exist in sheet1 yet.

Duplicating and renaming Google Sheet automatically

I am creating employee rosters for each division at my job that need to be checked daily. I have the roster and I would like to create a certain date range worth in a workbook for each division. I have the first sheet dated 090120, for example, and need to duplicate and rename up to 091220. Is there an easy way to do this without having to right click, duplicate, right click, rename on each tab? All the information for each one is identical and there are no formulas or anything like that. I am new to Google Sheets and am not tech savvy at all but there has to be an easier way to do this.
Solution:
function duplicateSheet(){
const ss = SpreadsheetApp.getActive();
const src_sheet = ss.getSheetByName('090120');
const dupl_sheets = ['090220','090320','090420','090520','090620',
'090720','090820','090920','091020','091120','091220'];
dupl_sheets.forEach(sheet=>{
var dupl_sheet=src_sheet.copyTo(ss);
dupl_sheet.setName(sheet);
});
}
Explanation:
dupl_sheets contains the names of the duplicate sheets you want to create.
forEach() is used to iterate over dupl_sheets and for every
sheet name it creates a sheet that is a duplicate of src_sheet.
Instructions:
Click on Tools => Script editor:
Copy/Paste the aforementioned code into the script editor and click run:
Result:

How to sort a specific column in multiple Google sheets

I'd like to sort the forth column of more than one sheet in ascending order.
I can do this in the active sheet (sheet1), but can not figure out how to do it in the non-active sheets.
Below is my code.
function sort() {
var bus = SpreadsheetApp.openByUrl("URI");
var sheet = bus.getSheets()[0];
sheet.sort(4,true);
}
Instead of getting just the first sheet, get all of them in a variable (notice the absence of the zero index - [0]):
var sheets = bus.getSheets();
Then iterate through all of them in a FOR loop:
for( sheet in sheets)
sheets[ sheet ].sort(4,true);
That will sort every sheet in the active Spreadsheet, you can also open sheets by ID, URL, name and the position in Spreadsheet, to find the methods you want just read the documentation.

Categories

Resources