I want to write a script to read and log values of a specific row and copy them to a new sheet - google-apps-script

I want to build a script to automate creating a form out of specific values.
What I need to do is:
Ask the user which row is relevant for the form, enter the row in a text box
Log value of column A of that row (Date)
Check that row from column C-ZZZ for values (numbers)
if there is a cell with a value, log the value. If the cell is empty ignore it
If there is a value in a cell additionally log values of row 1-10 of that column (numbers + strings)
create a new sheet
copy logged values in a specific order into that new sheet (other order than in the first sheet)
I searched for scripts that offer any resemblance of what I want to do, but I only managed to copy values of a specific row and output them into a new sheet without any formatting
Ask user for a row (NaN error message doesn't work):
function tourzettelZeile() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var rowIdxStr = Browser.inputBox("For which row do you want to make the list?");
if (rowIdxStr == 'cancel') {
return;
}
var rowIdx = parseInt(rowIdxStr);
if (rowIdx == NaN) {
Browser.msgBox("Numbers only or 'cancel'");
return;
}
}
My attempt at logging and pasting data:
function readData(spreadsheetID)
{
var spreadsheetId = '1KdZNvKgwL6NMuF0FYGB8jBhRVpbwv954D_UcBZ22eh0';
var plakatMenge = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK15:DK900');
var plakatFormat = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK4');
var plakatName = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK15:DK1');
var plakatiererName = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!FK66');
var plakatInfo = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK7');
var plakatGebiet = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!FL66');
var auftragDatum = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!A66');
Logger.log(plakatMenge.values);
Logger.log(plakatFormat.values);
Logger.log(plakatName.values);
Logger.log(plakatiererName.values);
Logger.log(plakatInfo.values);
Logger.log(plakatGebiet.values);
Logger.log(auftragDatum.values);
Browser.msgBox(plakatMenge + plakatFormat + plakatName + plakatiererName + plakatInfo + plakatGebiet + auftragDatum);
//Neues Sheet erstellen
var requests = [{
'addSheet': {
'properties': {
'title': 'Tourzettel',
'gridProperties': {
'rowCount': 80,
'columnCount': 14
},
'tabColor': {
'red': 1.0,
'green': 0.3,
'blue': 0.4
}
}
}
}];
var response =
Sheets.Spreadsheets.batchUpdate({'requests': requests}, spreadsheetId);
Logger.log('Created sheet with ID: ' +
response.replies[0].addSheet.properties.sheetId);
//writeValues
// Specify some values to write to the sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
// ss is now the spreadsheet the script is associated with
var sheet = ss.getSheets()[5];
var values = [
[plakatMenge.values, "Gebiet", plakatFormat.values, plakatName.values, plakatiererName.values, plakatInfo.values, plakatGebiet.values, auftragDatum.values]
];
var range = sheet.getRange("A1:H1");
range.setValues(values);
}
Both these scripts don't do the right thing and are not combined (info on which row to check does nothing)

This function attempts to do the first five items in your list:
Feel free to use and debug it because I have not debugged it at all.
function readAndLog() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var row=SpreadsheetApp.getUi().prompt('Enter Row Number').getResponseText();
if(typeof(row)!=Number) {
throw("Invalid Response: terminating script");
return;
}else{
Logger.log(sh.getRange(row,1).getValue());
var vA=sh.getRange(row,3,1,sh.getLastColumn()-3).getValues();
var rA=[];
for(var i=0;i<vA.length;i++) {
if(vA[0][1] && typeOf(vA[0][i])==Number) {
rA.push({col:i+1,val:vA[0][i]});
Logger.log('column: %s, value: %s',rA[i].col,rA[i].val);
var cA=sh.getRange(1,rA[i].col,10,1).getValues();
for(var j=0;j<cA.length;j++) {
Logger.log('col: %s, row: %s value: %s',rA[i].col, j+1, cA[0][j]);
}
}
}
}
}
Thanks, that helped a lot. I had to get rid of this part:
if(typeof(row)!=Number) {
throw("Invalid Response: terminating script");
return;
}else{
As it gave me an error, I wasn't able to solve.
I added a bit to the code:
function Tourzettel(){
readAndLog();
newSheet();
logOutput();
}
function readAndLog() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var row=SpreadsheetApp.getUi().prompt('Gib die Zeile mit dem Datum für die Tour ein').getResponseText();
Logger.log(sh.getRange(row,1).getValue());
var vA=sh.getRange(row,3,1,sh.getLastColumn()-3).getValues();
var rA=[];
for(var i=0;i<vA.length;i++) {
if(vA[0][1] && typeOf(vA[0][i])==Number) {
rA.push({col:i+1,val:vA[0][i]});
Logger.log('column: %s, value: %s',rA[i].col,rA[i].val);
var cA=sh.getRange(1,rA[i].col,10,1).getValues();
for(var j=0;j<cA.length;j++) {
Logger.log('col: %s, row: %s value: %s',rA[i].col, j+1, cA[0][j]);
}
}
}
}
// Create new sheet
function newSheet() {
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName("TourzettelV2");
if (yourNewSheet != null) {
activeSpreadsheet.deleteSheet(yourNewSheet);
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName("TourzettelV2");
}
// Log in das neue Sheet schreiben
function logOutput() {
var stringToWrite = Logger.log;
SpreadsheetApp.getActive().getSheetByName('TourzettelV2').getRange("A1").setValue(stringToWrite);
}
My problem now is the function logOutput, because Logger.log doesn't seem to work. It outputs:
function log() {
[native code, arity=0]
}
Not sure what exactly it logged there, but it doesn't look like cell values. I do want every single logged value to be put into a seperate cell.

To fix the NaN error try this:
if (isNan(rowIdx)) {
Browser.msgBox("Numbers only or 'cancel'");
return;
}
The other part is a little hard to follow. If you want to pass the row index number to the second function, you could try adding this line to the first function:
readData(rowIdx);
And the second function would then be
function readData(rowIdx) {
...
}
And it can then use the rowIdx variable in the script. I'm assuming the 2nd function does not need the spreadsheetID passed to it as it is provided in the first line of the function. (Or is that there because you were testing?)

Related

Searching a sheet for value stored in a cell fails

I'm an extreme novice in programming and am trying to work an assignment that keeps failing. My code searches a sheet(tab1) in Google sheets for a value that is in a cell in another sheet(tab2). For some reason, the search never finds the value. For simplicity I tested by changing the value that I'm looking for to a whole number, not a ".GetValue". I then had an if statement that would alert with message "Found" and "Not Found" if it wasnt found. The data is never found.
function editRecord(){
var myGoogleSheet=SpreadsheetApp.getActiveSpreadsheet();
var shUserForm=myGoogleSheet.getSheetByName("Form");
var datasheet=myGoogleSheet.getSheetByName("Records");
var ui=SpreadsheetApp.getUi();
var response=ui.alert("Submit", 'Do you want to submit your data?', ui.ButtonSet.YES_NO);
var str=shUserForm.getRange("F7").getValue();
var values=datasheet.getDataRange().getValues();
var valuesFound=false;
if(response==ui.Button.NO){
return;
}
for (var i=0;i<values.length;i++){
if (values[i][1]==str){
var iRow=i+1;
datasheet.getDataRange(iRow,5).setValue(shUserForm.getDataRange("F15").getValue());
datasheet.getDataRange(iRow,6).setValue(shUserForm.getDataRange("F17").getValue());
datasheet.getDataRange(iRow,7).setValue(shUserForm.getDataRange("F19").getValue());
ui.alert("Data updated.");
shUserForm.getDataRange("F15").clearContent;
shUserForm.getDataRange("F17").clearContent;
shUserForm.getDataRange("F19").clearContent;
shUserForm.getDataRange("F21").clearContent;
shUserForm.getDataRange("F23").clearContent;
shUserForm.getDataRange("F25").clearContent;
valuesFound=true;
return;
}
if (valuesFound==false){
ui.alert("Your ID was not found.");
return;
}
}
}
Modification points:
I think that in your script, by return of if (valuesFound==false){}, when values[i][1]==str is false, the for loop is finished. By this, for example, when values[i][1]==str is false at the 1st row of values, the for loop is finished. I thought that this might be the reason of your issue.
About getDataRange(iRow, 5) of datasheet.getDataRange(iRow, 5), unfortunately, getDataRange has no arguments. I think that an error also occurs at this part.
About clearContent of shUserForm.getDataRange("F15").clearContent, in this case, the method of clearContent is not run.
If you want to search the value, how about the following modification?
Modified script 1:
When your script is modified, it becomes as follows.
function editRecord() {
var myGoogleSheet = SpreadsheetApp.getActiveSpreadsheet();
var shUserForm = myGoogleSheet.getSheetByName("Form");
var datasheet = myGoogleSheet.getSheetByName("Records");
var ui = SpreadsheetApp.getUi();
var response = ui.alert("Submit", 'Do you want to submit your data?', ui.ButtonSet.YES_NO);
var str = shUserForm.getRange("F7").getValue();
var values = datasheet.getDataRange().getValues();
var valuesFound = false;
if (response == ui.Button.NO) {
return;
}
for (var i = 0; i < values.length; i++) {
if (values[i][1] == str) {
var iRow = i + 1;
datasheet.getRange(iRow, 5).setValue(shUserForm.getRange("F15").getValue());
datasheet.getRange(iRow, 6).setValue(shUserForm.getRange("F17").getValue());
datasheet.getRange(iRow, 7).setValue(shUserForm.getRange("F19").getValue());
ui.alert("Data updated.");
shUserForm.getRange("F15").clearContent();
shUserForm.getRange("F17").clearContent();
shUserForm.getRange("F19").clearContent();
shUserForm.getRange("F21").clearContent();
shUserForm.getRange("F23").clearContent();
shUserForm.getRange("F25").clearContent();
valuesFound = true;
return;
}
}
if (valuesFound == false) {
ui.alert("Your ID was not found.");
return;
}
}
Modified script 2:
I thought that in your script, getValue and setValue are used in the loop. In this case, the process cost will become high. So, as another modified script, how about the following modification?
unction editRecord() {
var myGoogleSheet = SpreadsheetApp.getActiveSpreadsheet();
var shUserForm = myGoogleSheet.getSheetByName("Form");
var datasheet = myGoogleSheet.getSheetByName("Records");
var ui = SpreadsheetApp.getUi();
var response = ui.alert("Submit", 'Do you want to submit your data?', ui.ButtonSet.YES_NO);
var str = shUserForm.getRange("F7").getValue();
if (response == ui.Button.NO) {
return;
}
var res = datasheet.getRange("B1:B" + datasheet.getLastRow()).createTextFinder(str).matchEntireCell(true).findNext();
if (!res) {
ui.alert("Your ID was not found.");
return;
}
var [[v1],,[v2],,[v3]] = shUserForm.getRange("F15:F19").getValues();
datasheet.getRange(res.getRow(), 5, 1, 3).setValues([[v1, v2, v3]]);
shUserForm.getRangeList(["F15","F17","F19","F21","F23","F25"]).clearContent();
SpreadsheetApp.flush();
ui.alert("Data updated.");
}
In this sample, the value is searched using TextFinder. And, the cells are cleared using the RangeList.
References:
getRange(row, column)
clearContent()
createTextFinder(findText)

Replace character using google apps script

I have a column which is a date in string format with this format
2020-02-23T12:14:06+0000
And i want to remove the T and replace it with space and also just completely remove the last part (+0000)
I have tried this
var A1 = CONTENT.getRange("B:B").getValue();
var A1String = A1.toString().replace("T*", "");
but it doesn't work.
Any ideas?
This is the original script in which i want to incorporate it into.
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('sheetname');
var range = sheet.getRange("A:C");
var response = UrlFetchApp.fetch("API CALL");
var dataAll = JSON.parse(response.getContentText());
var dataSet = dataAll.data;
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push([new Date(),data.created_time,data.message,data.permalink_url,
data.reactions.summary.total_count
,data.comments.summary.total_count,data.insights.data[1].values[0].value,data.insights.data[2].values[0].value,data.insights.data[3].values[0].value,data.insights.data[0].values[0].value['link clicks'],data.insights.data[0].values[0].value['photo view'],data.insights.data[0].values[0].value['other clicks'],data.insights.data[0].values[0].value['video play'],data.insights.data[4].values[0].value,data.insights.data[5].values[0].value,data.insights.data[6].values[0].value,data.insights.data[7].values[0].value["like"],data.insights.data[7].values[0].value["love"],data.insights.data[7].values[0].value["wow"],data.insights.data[7].values[0].value["haha"],data.insights.data[7].values[0].value["sorry"]]); //your JSON entities here
}
Logger.log(rows)
//sheet.getRange(getlastRow() + 1, 1, rows.length, 2).setValues(rows);
sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, 22).setValues(rows);
/**
* Removes duplicate rows from the current sheet.
*/
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetname');
var data = sheet.getDataRange().getValues();
data.reverse(); //reverses the row order.
var last=sheet.getLastRow();
var newData = new Array();
for(i in data){
//Logger.log(i);
var row = data[i];
//Logger.log(row[5]);
var duplicate = false;
for(j in newData){
//Logger.log(newData[j][3]);
if(row[3] == newData[j][3]){
duplicate = true;
}
}
if(!duplicate){
newData.push(row);
}
}
newData.reverse(); // reverses your data back to its original order.
sheet.clearContents();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
//
//
If you want to remove always the same thing (i.e. "T" and "+0000"), you could use the following script:
The result obtained: 2020-02-23 12:14:06
CODE:
// ---------- Menu ----------
// Add a Menu named Format Date to run the script
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Format Date')
.addItem('Go!', 'FormatDate')
.addToUi();
}
function FormatDate() {
var ss = SpreadsheetApp.getActiveSheet(),
array = [];
ss.getRange("B2:B") // Choose the range here
.getValues()
.forEach(function (dates) {
// "T" is replaced with a space: " " and "+0000" is replace with empty:""
[["T", " "], ["+0000", ""]]
.map(function (a, i) {
return dates = replace(dates.toString(), a[0], a[1])
})
array.push([dates])
});
// You can set a different column to write the data
// Or keep B2:B to overwrite your data
ss.getRange("B2:B")
.setValues(array)
}
function replace(d, a, r) {
return d.indexOf(a) > -1 ? d.split(a)
.join(r) : d;
}
Credit: got inspired by JPV's code to a different question long time ago

check if cell has value if not prompt dialog with error abort script if value then run script

I have searched on many forums yet and could not find this issue.
I have a script that moves a row from sheet 1 to sheet 2.
What I'm trying to achieve is that when a specific cell from sheet 1 is forgotten and left blank.
When I run the moverows() script I want to check if this row is has any empty cells and prompt with a dialog that there are still blank cells and abort the moverows() script if all the cells are not blank. Then proceed without a dialog.
I hope that you can point a direction or to a thread where there is a similar question.
I don't have enough knowledge to combine the dialog prompt with a check combine it with what I've got now:
function Moverows5() {
var ss = SpreadsheetApp.openById('sheetID');
var sourceSheet = ss.getSheetByName("sheetname1");
var targetSheet = ss.getSheetByName("sheetname 2");
var values = sourceSheet.getRange("B8:T43").getValues();
var range0 = sourceSheet.getRange("C8:K43");
var range1 = sourceSheet.getRange("Q8:T43");
var range2 = sourceSheet.getRange("P2");
var range3 = sourceSheet.getRange("R2");
var firstFreeRow = goToFirstRowAfterLastRowWithData(targetSheet, "A:AD");
//check column to whatever column you want to check
targetSheet.getRange(firstFreeRow, 1, values.length, values[0].length) .setValues(values);
range0.clearContent();
range1.clearContent();
range2.clearContent();
range3.clearContent();
createPdf()//function gets started
} //end of first function
function goToFirstRowAfterLastRowWithData(sheet, range) {
var v = sheet.getRange(range).getValues(),l = v.length,r;
while (l > 0) {
if (v[l] && v[l][0].toString().length > 0) {
r = (l + 2);
break;
} else {
l--;
}
}
return r ? r : 'no data found';
}
Check range for blanks before copying
This function checks the values array for blanks. If blanks are found it alerts the user, identifies the blank cells and terminates the function. Otherwise, it makes the transfer and clears some ranges.
function Moverows5() {
var ss=SpreadsheetApp.getActive();
var sourceSheet=ss.getSheetByName("Sheet1");
var targetSheet=ss.getSheetByName("Sheet2");
var sourceRange=sourceSheet.getRange("B8:T43");
var values=sourceRange.getValues();
var range0=sourceSheet.getRange("C8:K43");
var range1=sourceSheet.getRange("Q8:T43");
var range2=sourceSheet.getRange("P2");
var range3=sourceSheet.getRange("R2");
var firstFreeRow=targetSheet.getLastRow() + 1;
var noBlanks=true;
var bA=[];
var ro=sourceRange.getRow();
var co=sourceRange.getColumn();
for(var ri=0;ri<values.length;ri++) {
for(var ci=0;ci<values[ri].length;ci++) {
if(!values[ri][ci]) {
noBlanks=false;
bA.push(sourceSheet.getRange(ri+ro,ci+co).getA1Notation());
}
}
}
if(noBlanks) {
targetSheet.getRange(firstFreeRow,1,values.length,values[0].length).setValues(values);
range0.clearContent();
range1.clearContent();
range2.clearContent();
range3.clearContent();
//createPdf()//function gets started
}else{
SpreadsheetApp.getUi().alert('Sorry there are blanks in the following cells: ' + bA.join(', '));
return;
}
}
If you wish you may use this function to create some test data before testing on valuable spreadsheet.
function createTestData() {
var m=1;//0 for random column positions >0 for fixed position
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
sh.clearContents();
var cols=30;//number of columns
var rows=50;//number of rows
var hpref='hdr';
var hA=[];
var hdrA=[];
var cA=[];
for(var i=0;i<cols;i++) {hA.push(i+1);};
for(var i=0;i<cols;i++) {
if(m==0) {
var index=Math.floor(Math.random() * hA.length);
}else{
var index=i;
}
var hnum=hA[index];
hdrA.push(hpref + hnum);
cA.push(hnum);
if(m==0) {
hA.splice(index,1);
}
}
sh.getRange(1,1,1,hdrA.length).setValues([hdrA]);
var rg=sh.getRange(2,1,rows,cols);
var vA=rg.getValues();
for(var i=0;i<rows;i++) {
for(var j=0;j<cols;j++) {
vA[i][j]=Number(i+1) + ',' + cA[j];
}
}
rg.setValues(vA);
sh.getRange("B8:T43").setBackground('#ff00ff');
}

Reading a cell in a Google script fonction and uses it in a fonction #inception

need help, i try to read a cell in this fonction. I've tried 20 differents type of thing,
i always have this error message when i run the focntion on my spreadsheet :
Message details :
Cannot convert function getData() { Sheet = SS.getSheetByName("Technic"); Range = Sheet.getRange(4, 2); Data = Range.getValue(); } to (class).
What wrong ?
function hideMyColumns()
{
var ss = SpreadsheetApp.getActive();
var sh = ss.getActiveSheet();
var vl = sh.getRange('A30').getValue();
var cols1 = [ function getData() {
Sheet = SS.getSheetByName('Technic');
Range = Sheet.getRange(4, 2);
Data = Range.getValue() }];
var cols2 = [4, 5, 7, 8, 10, 11,]
switch (vl)
{
case 1:
for (var i = 0; i < cols1.length; i++)
{
sh.hideColumns(cols1[i]);
}
break;
case 2:
for (var i = 0; i < cols2.length; i++)
{
sh.hideColumns(cols2[i]);
}
}
}
évolution of the situation :
ok, now the fonction is like this :
function hideMyColumns()
{
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var vl=sh.getRange('A30').getValue();
var cols1=[ function() {
Sheet = ss.getSheetByName('Technic');
Range = Sheet.getRange(2,4);
Data = Range.getValue();
return Data;
}()];
var cols2=[4,5,7,8,10,11,12,]
switch(vl)
{
case 1:
for(var i=0;i<cols1.length;i++)
{
sh.hideColumns(cols1[i]);
}
break;
case 2:
for(var i=0;i<cols2.length;i++)
{
sh.hideColumns(cols2[i]);
}
}
}
the context :
the spreadsheet have 2 sheet : "Main" and "Technic"
"Main" can have some columns hide by this fonction.
In the sheet "Technic" you find a cell that contains a formula that returns:"2,3,4..."
i try to use this formule like a variable in the fonction "hideMyColumns".
Under this i have another fonction more simple : unhideCols() of course. (work well!)
You want to give a value to cols1 using the function expressions. If my understanding is correct, how about this modification?
Modification points :
In your situation, when var cols1 = [function getData(){...}] is used as the function expressions, please modify to var cols1 = [function getData(){...}()] or var cols1 = [function(){...}()].
SS of SS.getSheetByName('Technic') is not declared.
When getData() is run, the error occurs here.
At the modified script, SS was modified to ss.
There are no returned values in getData().
By this, cols1 always becomes [].
Modified script :
var cols1 = [ function() { // Modified
Sheet = ss.getSheetByName('Technic'); // Modified
Range = Sheet.getRange(4, 2);
Data = Range.getValue();
return Data; // Added
}()]; // Modified
Note :
In this modified script, only var cols1 was modified.
If you want to use SS, please declare it.
If you want to return other values, please modify it.
From your script, it seems that cols1 has only one element. So you can modify from sh.hideColumns(cols1[i]); to sh.hideColumns(cols1[0]); without for loop. Or when it is declared as var cols1 = function(){...}(), you can modify to sh.hideColumns(cols1); without for loop.
References :
Why do you need to invoke an anonymous function on the same line?
Location of parenthesis for auto-executing anonymous JavaScript functions?
If I misunderstand your question, I'm sorry.
Edit :
If you want to use the values of column D as ranges, please try this modified script.
function hideMyColumns()
{
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var vl=sh.getRange('A30').getValue();
var cols1=function() { // Modified
Sheet = ss.getSheetByName('Technic');
Range = Sheet.getRange(3,4); // getRange(3,4) is D3, Modified
Data = Range.getValue();
return Data.split(","); // Modified
}();
var cols2=[4,5,7,8,10,11,12,]
switch(vl)
{
case 1:
for(var i=0;i<cols1.length;i++)
{
sh.hideColumns(cols1[i]);
}
break;
case 2:
for(var i=0;i<cols2.length;i++)
{
sh.hideColumns(cols2[i]);
}
}

Cell reference out of range, google sheets

I'm getting this error while running this sheet.
Cell reference out of range (line 81, file "genreportSE")
I don't know why it says it's 'out of range'.
I tried to used 'copyvalues'. I saw a script where you can't really "print" a range, but you can create another spreadsheet, copy that range, then print that sheet and delete it.
How should I accomplish this?
function genreportSE() { // This function let us read the value of a cell from a sheet and change the value of another cell in a different sheet
var ss = SpreadsheetApp.getActive(); //ss stands for spreadsheet, this is the active spreadsheet
var clientsheet = ss.getSheetByName('Clientes SE');
var gensheet = ss.getSheetByName('Generador SE');
var clienttable = clientsheet.getDataRange();
var numberofservices = clienttable.getNumRows(); //The number of services in the Clientes sheet
var error1;
var error2;
var rangetocheck1;
var rangetocheck2;
var client;
var clientname;
var i=0;
var reportswitherrors = []; //Array for faulty reports
var email ='jvaldez#galt.mx';
var subject = "Reporte de producción y consumo - " + (new Date()).toString();
var body = "TEXT" ;
for (i=0;i<=2;i++){
gensheet.getRange('B2').setValue(clientsheet.getRange(i+2,1).getValue()); //This will change the cell "B2" in "Generador SE" to the current service number for the report generation
Utilities.sleep(3000); //A timer to let the importdata function get the data from the SE server in miliseconds
client = gensheet.getRange('B4').getValue;
clientname = String(client);
rangetocheck1 = gensheet.getRange('B8:C14').getValues(); //Data range that could present calculation errors ********
rangetocheck2 = gensheet.getRange('H8:H14').getValues(); //Data range that could present calculation errors ********
if(String(rangetocheck1).indexOf('#N/A') == -1) { //This checks if there are any errors in rangetocheck1
error1 = false;
} else {
error1 = true;
};
if(String(rangetocheck2).indexOf('#N/A') == -1) { //This checks if there are any errors in rangetocheck2
error2 = false;
} else{
error2 = true;
};
if(error1||error2){
reportswitherrors.push(clientsheet.getRange(i+2,1).getValue()); //This appends the current service number to the faulty services array
} else {
// Convert individual worksheets to PDF
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export",15,60);
newSpreadsheet.getSheetByName('Sheet1').activate();
var newsheet = newSpreadsheet.getSheetByName('Sheet1');
var genRange = gensheet.getRange('A1:H50').copyValuesToRange(newsheet,0,10,0,55)
var pdf = DriveApp.getFileById(newSpreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'Weekly Status.pdf',content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(email, subject, body, {attachments:[attach]});
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
}
};
Logger.log(reportswitherrors);
}
It appears that you've got your row & column dimensions flipped between function calls. (Because Google decided to be inconsistent with the order of them...)
This line calls create(name, rows, columns):
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export",15,60);
You've created a spreadsheet with 15 rows and 60 columns.
A bit further along, probably on line 81, copyValuesToRange(sheet, column, columnEnd, row, rowEnd) gets invoked:
var genRange = gensheet.getRange('A1:H50').copyValuesToRange(newsheet,0,10,0,55)