Streamline Google Script for combining multiple CSV to avoid timeout - csv

I am working on a sheet that combines 10 CSV files that are stored in a google folder into one google sheet. I have been able to run the code previously, but I am starting to run into a lot of time based errors. I am hoping that someone can help streamline the following code. I know that I could run this in a loop, but I don't think that would be any faster.
//Sets Sheets to variable
var AUG = DriveApp.getFilesByName("Set1.csv").next();
var Sep1 = DriveApp.getFilesByName("Set2.csv").next();
var Sep2 = DriveApp.getFilesByName("Set3.csv").next();
var Oct1 = DriveApp.getFilesByName("Set4.csv").next();
var Oct2 = DriveApp.getFilesByName("Set5.csv").next();
var Nov1 = DriveApp.getFilesByName("Set6.csv").next();
var Nov2 = DriveApp.getFilesByName("Set7.csv").next();
var Dec1 = DriveApp.getFilesByName("Set8.csv").next();
var Dec2 = DriveApp.getFilesByName("Set9.csv").next();
var Dec3 = DriveApp.getFilesByName("Set10.csv").next();
//Parse String
var csvAUG = Utilities.parseCsv(AUG.getBlob().getDataAsString());
var csvNov1 = Utilities.parseCsv(Nov1.getBlob().getDataAsString());
var csvNov2 = Utilities.parseCsv(Nov2.getBlob().getDataAsString());
var csvOct1 = Utilities.parseCsv(Oct1.getBlob().getDataAsString());
var csvOct2 = Utilities.parseCsv(Oct2.getBlob().getDataAsString());
var csvSep1 = Utilities.parseCsv(Sep1.getBlob().getDataAsString());
var csvSep2 = Utilities.parseCsv(Sep2.getBlob().getDataAsString());
var csvDec1 = Utilities.parseCsv(Dec1.getBlob().getDataAsString());
var csvDec2 = Utilities.parseCsv(Dec2.getBlob().getDataAsString());
var csvDec3 = Utilities.parseCsv(Dec3.getBlob().getDataAsString());
//Determine Lengths
var rowset1 = csvAUG.length
var rowset2 = rowset1+csvSep1.length;
var rowset3 = rowset2+csvSep2.length;
var rowset4 = rowset3+csvOct1.length;
var rowset5 = rowset4+csvOct2.length;
var rowset6 = rowset5+csvNov1.length;
var rowset7 = rowset6+csvNov2.length;
var rowset8 = rowset7+csvDec1.length;
var rowset9 = rowset8+csvDec2.length;
var rowset10 = rowset9+csvDec3.length;
var colset = csvAUG[0].length;
//Start Combines CSV's for Scores
ss.setActiveSheet(ss.getSheetByName("Raw Scores"));
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
sheet.getRange(1, 1, rowset1, colset).setValues(csvAUG);
sheet.getRange(1+rowset2, 1, csvSep1.length, colset).setValues(csvSep1);
sheet.getRange(1+rowset3, 1, csvSep2.length, colset).setValues(csvSep2);
sheet.getRange(1+rowset4, 1, csvOct1.length, colset).setValues(csvOct1);
sheet.getRange(1+rowset5, 1, csvOct2.length, colset).setValues(csvOct2);
sheet.getRange(1+rowset6, 1, csvNov1.length, colset).setValues(csvNov1);
sheet.getRange(1+rowset7, 1, csvNov2.length, colset).setValues(csvNov2);
sheet.getRange(1+rowset8, 1, csvDec1.length, colset).setValues(csvDec1);
sheet.getRange(1+rowset9, 1, csvDec2.length, colset).setValues(csvDec2);
sheet.getRange(1+rowset10, 1, csvDec3.length,colset).setValues(csvDec3);

Related

Starting row of the range is too small

I have an issue that I cannot figure out. I wrote some code to take an item from a sheet called "Bag Label" and then look up its location in another sheet called "Inventory & Lots". and then to copy some of the cells to the right of that location.
It works well as long as the location is not row 80 or higher in sheet "Inventory & Lots". For the life of me, I cannot figure out why row 1 to 79 works but not 80+.
var ss=SpreadsheetApp.getActiveSpreadsheet();
var menuSheet=ss.getSheetByName("Bag Label");
var inventorySheet = ss.getSheetByName("Registered Lots");
var inventorySheetData = ss.getSheetByName("RegisteredLots - NO DEL");
var nextRow = inventorySheetData.getLastRow()+1;
var inventoryLots = ss.getSheetByName("Inventory & Lots");
var inventoryCalc = ss.getSheetByName("Inventory Calculation");
var inventoryCalcData = inventoryCalc.getRange(2,1,inventoryCalc.getLastRow()-1,4).getValues()
var inventoryData = inventoryLots.getRange(1,1,inventoryLots.getLastRow()-1,10).getValues()
var columnIndex = 0
var matchText = menuSheet.getRange("D2").getValue()
var kgNeed = menuSheet.getRange("AB2").getValue()
var index = inventoryData.findIndex(row => row[columnIndex] === matchText)
var rowNumber = index +1
var kg1 = inventoryLots.getRange(rowNumber,2).getValue();
var lot1 = inventoryLots.getRange(rowNumber,3).getValue();
var bb1 = inventoryLots.getRange(rowNumber,4).getValue();
var kg2 = inventoryLots.getRange(rowNumber,5).getValue();
var lot2 = inventoryLots.getRange(rowNumber,6).getValue();
var bb2 = inventoryLots.getRange(rowNumber,7).getValue();
var kg3 = inventoryLots.getRange(rowNumber,8).getValue();
var lot3 = inventoryLots.getRange(rowNumber,9).getValue();
var bb3 = inventoryLots.getRange(rowNumber,10).getValue();
Use array methods such as Array.filter() to get data more easily. Try this pattern to get started:
const ss = SpreadsheetApp.getActive();
const matchText = ss.getRange('Bag Label!D2').getValue();
const inventoryLots = ss.getSheetByName('Inventory & Lots');
const matchingData = inventoryLots.getDataRange().getValues()
.filter(row => row[0] === matchText);

Why the installable trigger is not working in my code?

I have been trying to run this code in Google Apps Script and make it update information from one spreadsheet to another one once the user edits a certain range of cells in the file, but for some reason the trigger is not working, i am using an installable trigger since simple triggers cannot access to other files. Here is the code:
function new_troop() {
var source = SpreadsheetApp.openById("***");
var target = SpreadsheetApp.openById("***");
var source_sheet = source.getSheetByName("***");
var target_sheet = target.getSheetByName("***");
var seller = source_sheet.getRange("B14").getValue();
var category = source_sheet.getRange("B5").getValue();
var probability = source_sheet.getRange("B11").getValue();
var outcome1 = target_sheet.getRange("B1").setValue(seller);
var outcome2 = target_sheet.getRange("B2").setValue(category);
var outcome3 = target_sheet.getRange("B3").setValue(probability);
var source_sheet2 = target.getSheetByName("***");
var target_sheet2 = source.getSheetByName("***");
var range1 = source_sheet2.getRange(1, 5, 100, 1).getValues();
var range2 = source_sheet2.getRange(1, 18, 100, 1).getValues();
var range3 = source_sheet2.getRange(1, 14, 100, 1).getValues();
var range4 = source_sheet2.getRange(1, 17, 100, 1).getValues();
target_sheet2.getRange(1,1, 100,1).setValues(range1);
target_sheet2.getRange(1,2, 100,1).setValues(range2);
target_sheet2.getRange(1,3, 100,1).setValues(range3);
target_sheet2.getRange(1,4, 100,1).setValues(range4);
var distance = SpreadsheetApp.openById("***");
var distance_sheet = distance.getSheetByName("***");
var km = distance_sheet.getRange(1,2,100,5).getValues();
source_sheet.getRange(1,7,100,5).setValues(km);
ScriptApp.newTrigger('new_troop')
.forSpreadsheet(SpreadsheetApp.getActive())
.onEdit()
.create();
}

Is there any way to be more efficient when taking values from a spreasheet if they contain certain value?

I´m new at this and I´m trying to copy and paste certain rows (every row that contains the value "Buenos días" in the column C) from spreadsheet 1 (CSV) into spreadsheet 2 (buenosDias). It takes too much time to the script to totally run and I cannot find a way to be more efficient.Is there any way to be more efficient? This is the code I have come up with:
function buenosDias() {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1ur1Y7KoPONxPiFBMdGR4UfJW4GfyLy4MDxTEk30mg8w/edit#gid=0"); var sheets = ss.getSheets();
var buenosDias = ss.getSheetByName("Buenos días"); var range = buenosDias.getDataRange().getValues(); var CSV = ss.getSheetByName("CSV");
var lastRowA = CSV.getLastRow(); var CSVA = CSV.getRange(1, 1, lastRowA).getValues();
var lastRowB = CSV.getLastRow(); var CSVB = CSV.getRange(1, 2, lastRowB).getValues();
var lastRowC = CSV.getLastRow(); var CSVC = CSV.getRange(1, 3, lastRowC).getValues();
var lastRowD = CSV.getLastRow(); var CSVD = CSV.getRange(1, 4, lastRowD).getValues();
var lastRowE = CSV.getLastRow(); var CSVE = CSV.getRange(1, 5, lastRowE).getValues();
var lastRowF = CSV.getLastRow(); var CSVF = CSV.getRange(1, 6, lastRowF).getValues();
var lastRowG = CSV.getLastRow(); var CSVG = CSV.getRange(1, 7, lastRowG).getValues();
var lastRowH = CSV.getLastRow(); var CSVH = CSV.getRange(1, 8, lastRowH).getValues();
var lastRowI = CSV.getLastRow(); var CSVI = CSV.getRange(1, 9, lastRowI).getValues();
var lastRowJ = CSV.getLastRow(); var CSVJ = CSV.getRange(1, 10, lastRowJ).getValues();
var lastRowK = CSV.getLastRow(); var CSVK = CSV.getRange(1, 11, lastRowK).getValues();
var lastRowL = CSV.getLastRow(); var CSVL = CSV.getRange(1, 12, lastRowL).getValues();
var lastRowM = CSV.getLastRow(); var CSVM = CSV.getRange(1, 13, lastRowM).getValues();
for (var i = 1;i < CSVA.length; i++) {
var lastRow0 = buenosDias.getLastRow();
var RowToComplete = lastRow0;
if (CSVC[i] == "Buenos días") {
buenosDias.getRange(RowToComplete+1, 1).setValue(CSVA[i]).setHorizontalAlignment("center");
buenosDias.getRange(RowToComplete+1, 2).setValue(CSVF[i]).setNumberFormat("0").setHorizontalAlignment("center");
buenosDias.getRange(RowToComplete+1, 3).setValue(CSVH[i]).setNumberFormat("0").setHorizontalAlignment("center");
buenosDias.getRange(RowToComplete+1, 4).setValue(CSVH[i]/CSVF[i]).setNumberFormat("00.00%").setHorizontalAlignment("center");
buenosDias.getRange(RowToComplete+1, 5).setValue(CSVJ[i]).setNumberFormat("0").setHorizontalAlignment("center");
buenosDias.getRange(RowToComplete+1, 6).setValue(CSVJ[i]/CSVF[i]).setNumberFormat("00.00%").setHorizontalAlignment("center");
}
} }
Thanks!
Try using the method appendRow so you don't need to get the last Row of the Sheet, as it will add the values at the end of the Sheet.
Also, I made a single for loop to iterate over the Column C, looking for the string "Buenos dias". If it coincides, then appends that row to the CSV Sheet. Don't forget to change the numberofColumns to the actual number of Columns you want to copy from each row from Column A.
From the setHorizontalAlignment loop you made at the end I guess you want to center all the data of the CSV Sheet. It's easier to set it for all the Data Range instead of looping over all the rows.
function buenosDias() {
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1ur1Y7KoPONxPiFBMdGR4UfJW4GfyLy4MDxTEk30mg8w/edit#gid=0");
var buenosDias = ss.getSheetByName("Buenos días");
var CSV = ss.getSheetByName("CSV");
var range = CSV.getRange("C1:C").getValues(); //Range goes from C1 to the last C with values
for (var i = 0; i < range.length; i++){
if (range[i][0] == "Buenos días"){
CSV.appendRow(buenosDias.getRange((i+1), 1, numberofColumns).getValues());
}
}
CSV.getDataRange().setHorizontalAlignment('center');
}

Script Time Exceeded in Google App Script

This is the first time I am programming using Google Script and I cannot figure out how to add a function to circumvent Google's error message of exceeding processing time. Could you please help?
The program gets the number of bars and pints ordered and references them into a different sheet which has a calculator to calculate costs and outputs the value. Would really appreciate the help
/**
*
*
*/
function STBIBOL()
{
var r = 6
var destclm = 11
var pintsclm = 105
var barsclm = 101
var spreadsheet_url = 'https://docs.google.com/spreadsheets/d/1cqgdo_pgJ4n0xhXqMah24g6jjv7sfl2o92k1pwXNUuo/edit#gid=532254312';
var sheet_name = 'BOLs Entered for Fulfillment';
var sheet_name1 = 'STBI Calculator';
var ss = SpreadsheetApp.openByUrl(spreadsheet_url);
var sheet = ss.getSheetByName(sheet_name);
var sheet1 = ss.getSheetByName(sheet_name1);
var lastRow = sheet.getLastRow();
for(i =1; i< 20; i++)
{
var rangeD = sheet.getRange(r,destclm)
var dest = rangeD.getValue()
var rangeS = sheet.getRange(r,pintsclm)
var pints = rangeS.getValue()
var rangeB = sheet.getRange(r, barsclm)
var bars = rangeB.getValue()
var range = sheet1.getRange(14,3)
range.setValue(dest)
var range2 = sheet1.getRange(11, 3)
range2.setValue(pints)
var range3 = sheet1.getRange(12, 3)
range3.setValue(bars)
var rangev = sheet1.getRange(8,3)
var value = rangev.getValue()
var range4 = sheet.getRange(r,110)
range4.setValue(value)
r = r + 1
}
}
Instead of making multiple calls to GAS services on each run of the loop, which causes the execution to fail, you could simply get the entire range in one call like this:
var range1 = sheet1.getRange(startRow, startColumn, numberOfRows, numberOfColumns);
If the range in the 2nd sheet has the same dimensions (same number of rows and columns) as the 1st sheet, you could simply 1) get the values from the original sheet as a 2d array
var values1 = range.getValues();
2) Write values to the 2nd sheet
var range2 = sheet2.getRange(startRow, startColumn, numberOfRows, numberOfColumns);
range2.setValues(values1);

Copy/paste values and formats while asking for name

I am trying to copy over all of the values and formats to a different spreadsheet, week by week, creating a new sheet within the workbook each time. This is for archival purposes. I have pieced together the following:
function ArchiveByWeek(){
var source = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('CRS Stats By Week')
var buildVersion = Browser.inputBox("What is the Weekend Ending Date?");
var sValues = source.getDataRange().getValues();
var sBG = source.getDataRange().getBackgrounds();
var sFC = source.getDataRange().getFontColors();
var sFF = source.getDataRange().getFontFamilies();
var sFL = source.getDataRange().getFontLines();
var sFFa = source.getDataRange().getFontFamilies();
var sFSz = source.getDataRange().getFontSizes();
var sFSt = source.getDataRange().getFontStyles();
var sFW = source.getDataRange().getFontWeights();
var sHA = source.getDataRange().getHorizontalAlignments();
var sVA = source.getDataRange().getVerticalAlignments();
var sNF = source.getDataRange().getNumberFormats();
var sWR = source.getDataRange().getWraps();
var destination = SpreadsheetApp.openById('1WVfJGDbdOewO2H-aMhQiek7sCOolK6xH7cSbfZ8KQgY');
var destinationSheet = destination.insertSheet(buildVersion, 1);
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues)
.setBackgrounds(sBG)
.setFontColors(sFC)
.setFontFamilies(sFF)
.setFontLines(sFL)
.setFontFamilies(sFFa)
.setFontSizes(sFSz)
.setFontStyles(sFSt)
.setFontWeights(sFW)
.setHorizontalAlignments(sHA)
.setVerticalAlignments(sVA)
.setNumberFormats(sNF)
.setWraps(sWR);
}
This seems to work fine, only some cells are not copied. For some reason, it is only cells that are summing other cells. Can't figure out why.
I found the following script, which worked perfectly, only I was unable to find a way to give each new sheet a unique name:
function copySheetValues(){
var source = SpreadsheetApp.getActiveSheet();
var sourcename = source.getSheetName();
var sValues = source.getDataRange().getValues();
var sBG = source.getDataRange().getBackgrounds();
var sFC = source.getDataRange().getFontColors();
var sFF = source.getDataRange().getFontFamilies();
var sFL = source.getDataRange().getFontLines();
var sFFa = source.getDataRange().getFontFamilies();
var sFSz = source.getDataRange().getFontSizes();
var sFSt = source.getDataRange().getFontStyles();
var sFW = source.getDataRange().getFontWeights();
var sHA = source.getDataRange().getHorizontalAlignments();
var sVA = source.getDataRange().getVerticalAlignments();
var sNF = source.getDataRange().getNumberFormats();
var sWR = source.getDataRange().getWraps();
var destination = SpreadsheetApp.openById('15ucPbZrIYXZAOCYVdpK6OA0oyQT1NcsmuiJmDRfdpHQ');
var destinationSheet = destination.insertSheet(sourcename, 0);
destinationSheet.getRange(1,1,sValues.length,sValues[0].length).setValues(sValues)
.setBackgrounds(sBG)
.setFontColors(sFC)
.setFontFamilies(sFF)
.setFontLines(sFL)
.setFontFamilies(sFFa)
.setFontSizes(sFSz)
.setFontStyles(sFSt)
.setFontWeights(sFW)
.setHorizontalAlignments(sHA)
.setVerticalAlignments(sVA)
.setNumberFormats(sNF)
.setWraps(sWR);
}
I was actually able to come up with a solution that I was satisfied with. This was able to paste all of the values, and formats exactly as they were on the sheet when viewing. It asks for a name of the new sheet, which was my intention:
function Archive() {
var source = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SHEET NAME')
var sValues = source.getDataRange()
.getValues();
var weekEnding = Browser.inputBox("What is the Weekend Ending Date?");
var destination = SpreadsheetApp.openById('SHEET ID');
var copy = source.copyTo(destination)
.setName(weekEnding)
copy.getRange(1, 1, sValues.length, sValues[0].length)
.setValues(sValues); // overwrite all formulas that the copyTo preserved