I have running script in google sheets for submitting data, but I have no idea how to skip empty values
Here is my script :
function SubmitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formS = ss.getSheetByName("FORM");
var dataS= ss.getSheetByName("DATA");
var values = formS.getRange(8,1,20,5).getValues();
dataS.getRange(dataS.getLastRow()+1,3,20,5).setValues(values);
}
Thank You
var values = formS.getRange(8,1,20,5).getValues();
values = values.filter(e=>e.join('') !== '');
dataS.getRange(dataS.getLastRow()+1,3,values.length,5).setValues(values);
Related
I'm trying to get this code to work but keep getting a "TypeError: offset.copyTo is not a function". The script is supposed to take one value from sheet "Budget" and copy it into the next available row in column F on sheet "Projected".
I have tried playing around with syntax and other ways to copy but to now avail, any help would be greatly appreciated
function OffsetRecord() {
var sheet = SpreadsheetApp.openById("xx").getSheetByName("Budget");
var offset = sheet.getRange('I5').getValue();
var destSheet = SpreadsheetApp.openById("xx").getSheetByName("Projected");
var colF = destSheet.getRange('F:F').getValues();
var fcolF = colF.filter(function (e) {return e[0];});
var firstEmptyRowIncolF = fcolF.indexOf('')+1;
offset.copyTo(firstEmptyRowIncolF, {contentsOnly: true});
copyTo expects ranges as parameters, not values or column numbers, see here
Modify your code as following:
function OffsetRecord() {
var spreadsheet = SpreadsheetApp.openById("XX");
var sheet = spreadsheet.getSheetByName("Budget");
var offset = sheet.getRange('I5');//without ".getValue();"!
var destSheet = spreadsheet.getSheetByName("Projected");
...
firstEmptyRowIncolF = ...;
var destinationColumn = 1;
var range = destSheet.getRange(firstEmptyRowIncolF, destinationColumn);
offset.copyTo(range, {contentsOnly: true});
}
So I am new to Google Sheets. I am making an inspection report for a small company using Sheets. I would like to add a button to the bottom of the sheet which does the following script:
Duplicate original sheet
Rename sheet to a cell value +today's date. i.e Fred01011980
Email the sheet as a PDF to a recipient.
Finally clear the inputted values in the original master template sheet.
I have looked up how to do each of these and a few of them are straightforward, but I don't know how to combine them. Can I just add all of the functions individually together without any additional syntax needed? Any help on this would be really appreciated. Thank you.
I believe you can just create another function that calls your functions, like this:
function doAllStuff() {
doStuff();
doMoreStuff();
}
Here's how I did it:
function AllinOne() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var name = "Inspection";
var sheet = ss.getSheetByName("Inspection").copyTo(ss);
var newname = ss.getSheetByName("Inspection").getRange(2, 2).getValue();
var newnamedate = ss.getSheetByName("Inspection").getRange(3, 2).getValue();
var sheetx = ss.getActiveSheet()
var thisSheet = sheetx.getName();
var actualSheetName = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName()
var sheetfinal = ss.getSheetByName("Inspection")
var old = ss.getSheetByName(newname+newnamedate);
if (old) ss.deleteSheet(old);
sheet.setName(newname+newnamedate); //copies the sheet and renames it to "store+date"
ss.setActiveSheet(sheet)
// below is pdf conversion
var originalSpreadsheet = SpreadsheetApp.getActive();
var sourcesheet = originalSpreadsheet.getActiveSheet();
var sourcerange = sourcesheet.getRange('A1:B176'); // range to get - here I get all of columns which i want
var sourcevalues = sourcerange.getValues();
var data = sourcesheet.getDataRange().getValues();
var newSpreadsheet = SpreadsheetApp.create(thisSheet); // can give any name.
var sheetnow = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var projectname = SpreadsheetApp.getActiveSpreadsheet();
var sheetz = sourcesheet.copyTo(newSpreadsheet);
var destrange = sheetz.getRange('A1:B176');
destrange.setValues(sourcevalues);
newSpreadsheet.getSheetByName('Sheet1').activate();
newSpreadsheet.deleteActiveSheet();
var pdf = DriveApp.getFileById(newSpreadsheet.getId());
var theBlob = pdf.getBlob().getAs('application/pdf').setName(newname+newnamedate);
var folderID = "File_ID"; // Folder id to save in a folder.
var folder = DriveApp.getFolderById(folderID);
var newFile = folder.createFile(theBlob);
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
MailApp.sendEmail("Email","New Manager Inspection: "+newname+newnamedate, "A new Manager Inspection Report has been added to the Drive.");
ss.getSheetByName(name).getRangeList(["B176","B150:B164","B138:B146","B129:B134","B119:B125","B106:B115","B99:B102","B84:B95","B78:B80","B66:B74","B55:B62","B48:B51","B34:B44","B25:B30","B18:B21","B10:B14","B4:B7","B2","B16","B23","B32","B46","B53","B53","B64","B76","B82","B97","B104","B117","B127","B136","B148","B166"]).clearContent();
ss.setActiveSheet(sheetfinal);
SpreadsheetApp.getUi().alert("Report Submitted, Please do NOT Resubmit. Thank You");
}
I am getting this error: TypeError: Cannot call method "getName" of null. I have used a script to replace the formulas of the active sheet with the cell values. However, I don't want to accidentally run this on a few sheets, so I want to be able to exclude or include only specific sheets. I have been following another post and came up with this, and now I have the error:
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
//loop through all sheets and get name to see if it includes specific string
for (i = 0; i < sheets.length; i++) {
var sheet = ss.getSheetByName(sheets[i]);
var name = sheet.getName();
if (name.includes("String_00")) {
//get active sheet and replace range with values
var sheetActive = ss.getActiveSheet();
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
} else {
continue;
//skip over all those that don't meet the condition
}
}
}
UPDATE:
Trying this:
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
//loop through all sheets and get name to see if it includes specific string
for (i = 0; i < sheets.length; i++) {
//var sheet = ss.getSheetByName(sheets[i]);
var name = sheets[i].getName().toString();
if (name.indexOf("String_00") > -1) {
//get active sheet and replace range with values
//var sheetActive = ss.getActiveSheet();
var range = sheets.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
} else {
continue;
//skip over all those that don't meet the condition
}
}
}
But now it doesn't do anything. using .include was giving me an error, so I moved over to .indexOf() > -1. Does not freeze data as expected for any sheet, regardless of name.
I came up with 2 solutions for this, sort of started from the drawing board. One creates an array, a sort of blacklist, and then if the sheet name contains any item in the blacklist, then it returns and doesn't execute the replacement. The second solution searches for a pattern in the sheet name and only then continues on to the replacement. Both accomplish what I was trying to do. I think the code I found was a bit buggy and was a bit complicated for what I was doing. I didn't need to loop through all sheet names, just check the sheet name against given variables. Anyway, here they are:
This one creates the array blacklist of pages not to edit:
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ['Sheet1', 'Sheet2', 'Sheet3', 'Sheet4'];
var sheetActive = ss.getActiveSheet();
if (sheets.indexOf(sheetActive.getName()) > -1) return;
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
}
This one only searches for specific text in the sheet name before proceeding with the replacement.
function freezeValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetActive = ss.getActiveSheet();
var name = sheetActive.getName()
if (name.indexOf("String_00") > -1) {
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
}
}
I'm sure there is a method to use sheet index value so if you want to skip the first 4 sheets, you can probably do that as well, so it doesn't call on names at all.
UPDATE
function freezeValues2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetActive = ss.getActiveSheet();
if (sheetActive.getIndex() > 4) {
var range = sheetActive.getRange("A1:Z50");
range.copyTo(range, {contentsOnly: true});
}
}
I have a script that will copy a line into another sheet when I enter a value in column 17 (the date when the file is closed).
I don't know why but before copying, the format changes and the date appears in numeric format
for example: 04/08/2017 => 42951
Any idea on what could be the problem?
Here is my script:
function onEdit(r) {
var sheet = r.source.getActiveSheet();
if(sheet.getName()!="Remboursements"){return}
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source_sheet = ss.getSheetByName("Remboursements");
var target_sheet = ss.getSheetByName("Remboursements traités");
var range1 = r.range;
var columnOfCellEdited = range1.getColumn();
if (columnOfCellEdited === 17){
var source_range = source_sheet.getRange("A"+ range1.getRow()+":Q"+ range1.getRow());
var last_row = target_sheet.getLastRow();
target_sheet.insertRowAfter(last_row);
var target_range = target_sheet.getRange("A"+(last_row+1)+":Q"+(last_row+1));
source_range.copyTo(target_range);
source_sheet.deleteRow(range1.getRow())
}
}
Here's another way to do this:
function onEdit(r) {
if(r.source.getActiveSheet().getName()!="Remboursements"){return}
var source_sheet=r.source.getSheetByName("Remboursements");
var target_sheet=r.source.getSheetByName("Remboursements traités");
if (r.range.getColumn()==17)
{
var source_range=source_sheet.getRange("A"+ r.range.getRow() +":Q"+ r.range.getRow());
var values=source_range.getValues();
target_sheet.appendRow(values);
source_sheet.deleteRow(r.range.getRow())
}
}
This is my code (it is fully working as intended).
function concatenate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Responses");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
for (i=lastrow;i>=2;i--) {
var datad = sheet.getRange(i, 4).getValue();
var datae = sheet.getRange(i, 5).getValue();
var concatde = sheet.getRange(i, 4).setValue(sheet.getRange(i, 1).getValue());
}
}
However my question is regarding the line var concatde = sheet.getRange(i, 4).setValue(sheet.getRange(i, 1).getValue()); in my code.I wish to add a string at the end of the setValue as well shown in this line.
var concatde = sheet.getRange(i, 4).setValue(sheet.getRange(i, 1).getValue(), "A");
However, when I run it with the string "A", I get this error message:
Cannot find method setValue(object,string). (line 12, file "Code")
Any suggestions for me to be able to have a string at the end of it as well?
From what I can see setValue() only takes in one parameter.
Google Apps Script is just javascript so you can do something like below:
var concatde = sheet.getRange(i, 4).setValue(sheet.getRange(i, 1).getValue() + "A");
Note the '+' after getValue().