I'm new to javascript and a novice coder. I have been trying to write a simple script for a Google Sheet to concatenate two columns of data into another column:
My script below runs fine but only produces Aaron Ward as line 1 of Desired Column C. I'm sure it is really simple what I am missing, but if anyone has a minute to help a rookie, I'd really appreciate it.
function concatenate() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var lr = sheet.getLastRow()
var values1 = sheet.getSheetValues(1, 1, lr, 1);
var values2 = sheet.getSheetValues(1, 2, lr, 1);
var results = [];
for (var i = 0; i < lr; i++) {
results = [values1[i] + " " + values2[i]];
Logger.log(results);
sheet.getRange(1, 3, results.length).setValues([results]);
}
}
Why not using a formula? In C1 place the formula =JOIN(“ “,A1:B1) and drag it to the last row.
You're very close. In your for-loop, you need to push() the concatenated string into your results array. Then you can setValues(results) after the for-loop.
function concatenate() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var lr = sheet.getLastRow()
var values1 = sheet.getSheetValues(1, 1, lr, 1);
var values2 = sheet.getSheetValues(1, 2, lr, 1);
var results = [];
for (var i = 0; i < lr; i++) {
results.push([values1[i] + " " + values2[i]]);
}
sheet.getRange(1, 3, results.length).setValues(results);
}
You can either use this
function conCat(){
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ws = ss.getSheetByName("your sheet name")
var data = ws.getDataRange().getValues()
for(var k = 1;k<data.length;k++){
var row = data[k]
var merge = row[0]+" "+row[1]
ws.getRange(k+1,3).setValue(merge)
}
}
This code will simply take values from first and second column and concatenate result will show in third column
Related
I have two issues on my code, due to my luck of experience in coding, the code that I have is made to copy rows with a specific cell value, in my case it's 'commande confirmer', the first problem that I have is the first line of my values even if it has the specific value it's not copying but on other lines it's working perfectly.
And for the 2nd issue I want to get also when the data copied it transfer with it to the active sheet email, I found how to get it, but how to include it and being transferred I couldn't make it.
Here is my code
and thanks in advance.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Sheet1");
var url = "https://docs.google.com/spreadsheets/d/15nIAXcP0a14OvvBr5lww4tO23stQD4PEu0QDAcgaFyE/edit?ouid=112360896426304156672&usp=sheets_home&ths=true";
var ss2 = SpreadsheetApp.openByUrl(url);
var pasteSheet = ss2.getSheetByName("Sheet2");
// get source range
var max = copySheet.getMaxRows().toString();
var email= Logger.log(Session.getActiveUser().getEmail());
var range = copySheet.getRange(2, 1, max, 10);
var dataValues = range.getValues();
for (i = 1; i < dataValues.length; i++) {
if (dataValues[i][9] === 'COMMANDE CONFIRMER') {
pasteSheet.appendRow([dataValues[i][0],
dataValues[i][email],
dataValues[i][1],
dataValues[i][2],
dataValues[i][3],
dataValues[i][4],
dataValues[i][5],
dataValues[i][6],
dataValues[i][7],
dataValues[i][8],
dataValues[i][9]]);
var clearRow = i + 2;
copySheet.getRange('A' + clearRow + ':J' + clearRow).clear();
}
}
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow() + 1, 1, max, 1);
// clear source values
Browser.msgBox('Commande Confirmer');
}
Try it this way:
function funko() {
var ss = SpreadsheetApp.getActive();
var csh = ss.getSheetByName("Sheet1");
var ss2 = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/15nIAXcP0a14OvvBr5lww4tO23stQD4PEu0QDAcgaFyE/edit?ouid=112360896426304156672&usp=sheets_home&ths=true");
var psh = ss2.getSheetByName("Sheet2");
var email = Session.getActiveUser().getEmail();
var range = csh.getRange(2, 1, csh.getLastRow() - 1, 10);
var cvs = range.getValues();
let oA = [];
cvs.forEach((r, i) => {
if (r[9] == 'COMMANDE CONFIRMER') {
let t = r.slice();
t.splice(1, 0, email);
oA.push(t);
csh.getRange(i + 1, 1, 1, csh.getLastColumn()).clearContent();
}
});
psh.getRange(psh.getLastRow() + 1, 1, oA.length, oA[0].length).setValues(oA);
Browser.msgBox('Commande Confirmer');
}
So this is the script am using, it sends out a blank mail without any content in them. Here I am trying to compare two columns and if the value in one column is great am trying to add the row header to the list which has to be sent out via mail. Can someone help me out pls.
function Mailer1() {
var ss = SpreadsheetApp.openById("");
var sheet = ss.getSheetByName("Today");
var values = sheet.getRange("AD2:AD").getValues();
var value1s = sheet.getRange("AE2:AE").getValues();
var results = [];
for(var i=0;i<values.length;i++)
{
if(values[i]>value1s[i])
{
var value5 = sheet.getRange(i+2,1).getValue();
results.concat(value5);
}
}
MailApp.sendEmail('vinay_narayanan#playshifu.com','Restock Needed At:',results);
};
I'm guessing that the values in 30 and 31 are some sort of quantities and the value in column 1 is a date.
Try doing this:
function Mailer1() {
var ss = SpreadsheetApp.openById("");
var sh = ss.getSheetByName("Today");
var values = sh.getRange(2, 30, sh.getLastRow() - 1).getValues().flat();
var value1s = sh.getRange(2, 31, sh.getLastRow() - 1).getValues().flat();
var results = [];
for (var i = 0; i < values.length; i++) {
if (values[i] > value1s[i]) {
results.push(sh.getRange(i + 2, 1).getValue());
}
}
MailApp.sendEmail('vinay_narayanan#playshifu.com', 'Restock Needed At:', results.join('\n'));
};
I'm trying to add x blank rows after every no blank cells in a range.
I use a loop but with my loop, only the first cell is affected.
Here, my code :
I think I know where I'm wrong (I need to loop in sheet.insertRowsAfter(i, 5); but I can not do it...)
Thank you !
function insertRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
var sourceRange = sheet.getRange(10, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues();
var numRows = sourceRange.getNumRows();
Logger.log(numRows);
for (var i=10; i < numRows; i++) {
sheet.insertRowsAfter(i, 5);
}
}
In your case we need to start at the end of the range and work our way up, adding rows where appropriate. The code below will do this and add a 5 rows below any row which has data, even adding rows if there is a blank row following the one with data. You could pass startRow to the function if you wish for more flexibility
function insertRows() {
var startRow = 10;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
var sourceRange = sheet.getRange(startRow, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues();
var numRows = sourceRange.getNumRows() - startRow;
// Logger.log(numRows);
for (var i=numRows; i > -1; i--) {
if (sheetData[i].join("")) {
sheet.insertRowsAfter(i + startRow, 5);
}
}
}
As a general comment: You are retrieving more rows as necessary as sheet.getLastRow() gets the last row number with data and the use in getRange() is telling the app to pull that number of rows as opposed to that number minus the starting position.
Try the below. This will add 3 rows when there is a no blank cell.
function insertRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
var sourceRange = sheet.getRange(1, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues();
for (var i=0; i < sheetData.length; i++) {
if(sheetData[i][0]!=""){
sheet.insertRowsAfter(i+1, 3);
sheetData = sheet.getRange(1, 1, sheet.getLastRow()).getValues();
}
}
}
I want a Google Script which checks once a day on my spreadsheet and copies the values to another sheet and than deletes all the rows if the date in that cell is small than the current.
The file looks like this:
And this is what I wrote so far:
function DeleteIfDateIsToSmall(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
var today = new Date();
var today2 = Utilities.formatDate(today,'GMT+0200','dd.MM.yyyy');
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow()-1
for (var i=2; i < numRows; i++) {
var DateCell = s.getRange(i, 13);
var sheetDate = DateCell.getValue()
var sheetDate2 = Utilities.formatDate(sheetDate,'GMT+0200','dd.MM.yyyy');
var row = i;
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Ended or Deleted");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
if (s.getName() == "Start" && sheetDate != 0 && sheetDate != "" && today2.valueOf() > sheetDate2.valueOf()){
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
}
It doesn't seem to work, please help.
A few things are wrong or suboptimal here.
For a timed trigger, the event object does not have any range/source data; it only has time data. You need to pick a sheet by name (or loop through all sheets obtained by getSheets, if this is what you want).
Utilities.formatDate returns a string, which is not the best way to compare dates; in any case calling valueOf on it seems pointless.
Instead of using getValue in a loop, it is more efficient to obtain values before entering the loop, with getValues. There are some other things you do in the loop that should be outside.
Deleting rows when moving top to bottom in a sheet is tricky, because rows shift, messing up their indexing. For this reason, I collect the rows to be deleted in an array, and then delete them in bottom-to-top order.
function DeleteIfDateIsTooSmall() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Start");
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Ended or Deleted");
var today = new Date();
var dates = s.getRange(2, 13, s.getLastRow()-1, 1).getValues();
var rowsToDelete = [];
for (var i = 0; i < dates.length; i++) {
if (dates[i][0] && dates[i][0] < today) {
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(i + 2, 1, 1, numColumns).moveTo(target);
rowsToDelete.push(i + 2);
}
}
for (i = rowsToDelete.length - 1; i >= 0; i--) {
s.deleteRow(rowsToDelete[i]);
}
}
So I'm working on creating something that will automatically create a spreadsheet of names and employees shifts. Below is the code that I'm using to copy and paste those names and shifts into the new sheet. I'm using a concatenate-like process to produce an outcome something like this: "6:00 AM - 1:00 PM." My problem now is that the function gets 52 rows on the first sheet and I don't always have 52 rows of data so it returns and pastes just the " - " of the function.
All I'm looking to do is have a function to find the " - " within an entire cell in a given range and clear it before I go to the sort function.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "Update", functionName: "Update"}
];
ss.addMenu("Advanced", menuEntries);
}
function Update(){
var doc = SpreadsheetApp.openById('SOURCE ID GOES HERE');
var gs = doc.getSheets()[1];
var lastColumn = gs.getLastColumn();
var data = gs.getRange(2, 1, 52, lastColumn).getValues();
var destdoc = SpreadsheetApp.openById('DESTINATION ID GOES HERE');
var destsheet = destdoc.getSheets()[0];
//Day1
//Names
var fullNames1 = [];
for (var i = 0; i < data.length; i++) {
fullNames1.push([data[i][9]]);
}
var destRangeName = destsheet.getRange("A3").offset(0, 0, fullNames1.length);
destRangeName.setValues(fullNames1);
//shift
var shift1 = [];
for (var i = 0; i < data.length; i++) {
shift1.push([data[i][10] + ' - ' + data[i][11]]);
}
var destRangeName = destsheet.getRange("B3").offset(0, 0, shift1.length);
destRangeName.setValues(shift1);
//sort
var range1 = destsheet.getRange("A3:B54");
range1.sort([{column: 2, ascending: true}]);
You don't need to read a fixed range of 52 rows, because you can get only the populated rows via .getDataRange(). Instead of this:
var data = gs.getRange(2, 1, 52, lastColumn).getValues();
Use this.
var data = gs.getDataRange().getValues()
.slice(1); // Skip 1 header row
You've decoupled creation of the names and shift columns, try creating your new "shiftData" as a 2-D array with both names and the concatenated shift data. This is easier to maintain in future.
You are doing your sort on the range after writing to the spreadsheet, but you could do that entirely in javascript arrays before writing them out. For this to work, you need to provide a function that will give sort the comparison result for two elements, as a parameter.
The final Update() function is:
function Update(){
var doc = SpreadsheetApp.openById('SOURCE ID GOES HERE');
var gs = doc.getSheets()[1];
var data = gs.getDataRange().getValues()
.slice(1); // Skip 1 header row
var shiftData = [];
for (var i = 0; i < data.length; i++) {
shiftData.push([data[i][9], data[i][10] + ' - ' + data[i][11]]);
}
shiftData.sort(function(a,b) {
// sort by shift
return a[1] - b[1];
});
var destdoc = SpreadsheetApp.openById('DESTINATION ID GOES HERE');
var destsheet = destdoc.getSheets()[0];
var destRangeName = destsheet.getRange("A3")
.offset(0, 0, shiftData.length, shiftData[0].length);
destRangeName.setValues(shiftData);
}