Add data to the bottom of a range - google-apps-script

So I'm currently trying to set up a simple button which moves data from a range into another sheet for future reference. I've got it working if the sheet it is going to contains no information but I wanted to put all of the references into one sheet together.
Is there a way to add to the bottom of a range of data? This is what I have at the moment.
function Addvoucher() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var target_sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Meta');
var source_sheet = ss.getSheetByName("Tools");
var source_range = source_sheet.getRange("B9:D9");
var target_range = target_sheet.getRange("S3:U3");
var last_row = target_sheet.getLastRow();
var target_range = target_sheet.getRange("S3" + (last_row + 1) + ":U3" + (last_row + 1));
target_sheet.insertRowAfter(last_row);
source_range.copyTo(target_range);
}

Modification points:
I think that in your script, how about modifying "S3" + (last_row + 1) + ":U3" + (last_row + 1) of target_sheet.getRange("S3" + (last_row + 1) + ":U3" + (last_row + 1)) as follows?
In the current script, for example, last_row + 1 is 2, "S3" + (last_row + 1) + ":U3" + (last_row + 1) becomes S32:U32. In this case, it is required to be S2:U2. I think that this might be the reason of your issue.
Tried this, the issue is there is data in other columns to the left of this "block" of information thus this gets put onto row 100 as its the first available row.
From your replying, I could understand that in your Spreadsheet, the columns except for the columns "U" to "S" has the values and the last row of the columns "U" to "S" is different from other columns.
When above points as reflected to your script, I would like to propose to modify as follows.
From:
var last_row = target_sheet.getLastRow();
var target_range = target_sheet.getRange("S3" + (last_row + 1) + ":U3" + (last_row + 1));
To:
var last_row = target_sheet.getLastRow();
var values = target_sheet.getRange("S1:U" + last_row).getValues();
for (var i = values.length - 1; i >= 0; i--) {
if (values[i].every(e => e.toString() != "")) {
last_row = i + 1;
break;
}
}
var target_range = target_sheet.getRange("S" + (last_row + 1) + ":U" + (last_row + 1));

Related

How to Include more sheets to write incremental number

I am using this function which works upon submitting the entry via Google Forms. Currently the below script is adding increment number to the Sheet1 Last empty row
I want to include two more sheets where same incremental number will be added to last empty row.
Column will be same where increment number is pasting that is Column A but Sheet1 data starts from Row2 and Sheet2 and Sheet3 Data starts from row6.
Your help will be much appreciated.
function uPDATEiT() {
var aiColumnName = 'A'; //Sheet1,Sheet2,Sheet3 same column
var requieredColName = 'C' //it is just for Sheet1
var ss = SpreadsheetApp.getActiveSpreadsheet()
var worksheet = ss.getSheetByName('Sheet1','Sheet2','Sheet3')
var aiColRange = worksheet.getRange(aiColumnName + '1:' + aiColumnName + '1000');
var aiCol = aiColRange.getValues();
var aiColIndex = aiColRange.getColumn();
var reqCol = worksheet.getRange(requieredColName + '1:' + requieredColName + '1000').getValues();
var maxSeq = 0;
for (var i = 0; i <= aiCol.length; i++) {
if (parseInt(aiCol[i], 10) > maxSeq) { maxSeq = aiCol[i]; }
}
for (var i = 0; i <= aiCol.length; i++) {
if (('' + reqCol[i]).length > 0 && ('' + aiCol[i]).length === 0) {
maxSeq++;
worksheet.getRange(i + 1, aiColIndex).setValue(maxSeq);
}
}
}
You can use this formula in Sheet2!A4 and Sheet3!A4:
={"ID's";ARRAYFORMULA(IF(B5:B<>"",vlookup(B5:B,{'Data Sheet (Sheet1)'!$B$2:$B,'Data Sheet (Sheet1)'!$A$2:$A},2,false),""))}
What it does?
Check if column B is not empty, then get the id from Sheet1 based on the matched name(column B) as a key in the vlookup()
Output:
Original Sheet2:
Sheet 2 using the formula:
Update
If you just want to append your maxSeq in Sheet2, you can use this:
Code:
function uPDATEiT() {
var aiColumnName = 'A'; //Sheet1,Sheet2,Sheet3 same column
var requieredColName = 'C' //it is just for Sheet1
var ss = SpreadsheetApp.getActiveSpreadsheet()
var worksheet = ss.getSheetByName('Data Sheet (Sheet1)')
var sheet2 = ss.getSheetByName('Sheet2')
Logger.log(worksheet)
Logger.log(sheet2.getLastRow())
var aiColRange = worksheet.getRange(aiColumnName + '1:' + aiColumnName + '1000');
var aiCol = aiColRange.getValues();
var aiColIndex = aiColRange.getColumn();
var reqCol = worksheet.getRange(requieredColName + '1:' + requieredColName + '1000').getValues();
var maxSeq = 0;
for (var i = 0; i <= aiCol.length; i++) {
if (parseInt(aiCol[i], 10) > maxSeq) { maxSeq = aiCol[i]; }
}
for (var i = 0; i <= aiCol.length; i++) {
if (('' + reqCol[i]).length > 0 && ('' + aiCol[i]).length === 0) {
maxSeq++;
worksheet.getRange(i + 1, aiColIndex).setValue(maxSeq);
sheet2.getRange(sheet2.getLastRow()+1,aiColIndex).setValue(maxSeq);
}
}
}
Get the last row in the sheet that contains data using getLastRow() , then increment it by 1.
Output:

setting alternate columns number format

I have a sheet where we have a product name in column A, row 3. In cells B1 and C1 we have the date and then in B2 stock and C2 price
26/3/21 26/3/21
Thingymabob 3 5
I want to step along the columns C, E, G etc. until the last column formatting them to $#.##
I can't find a way to format column (index) so I've found an old bit of code on here that converts the index to a letter then I've tried to use that letter to say
"var column = sheet.getRange("C2:C")"
"column.setNumberFormat("[$€]#,##0.00");"
No joy though. Here's the function, please help!
function formatPriceColumns() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName("PriceHistory");
var temp = ""
var letter = "";
var lastCol = sheet.getLastColumn();
var lastRow = sheet.getLastRow();
for(i = 3; i <= lastCol; i = i + 2) {
temp = (i - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
i = (i - temp - 1) / 26;
var needString = "\"" + letter + "3" + ":" + letter + lastRow + "\""
var column = sheet.getRange(needString)
column.setNumberFormat("[$€]#,##0.00");
}
}
Well there were a number of issues!
Using i twice was the least among them. Also the scope fo the variables and most importantly, not passing a string.
The corrected code looks like this:
function formatColumns() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName("PriceHistory");
var lastCol = sheet.getLastColumn();
var lastRow = sheet.getLastRow();
for(i = 5; i <= lastCol; i = i + 2) {
var temp = ""
var letter = ""
var column = 0
column = i
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
var column = sheet.getRange(letter + "3:" + letter + lastRow)
column.setNumberFormat("[$€]#,##0.00");
}
}

Group rows using google apps scripts

I am writing code in which a user can automatically generate a template of lesson and sub-topics. Each lesson will have 10 sub-topics.
I also need to group the rows lesson-wise and topic-wise.
But, I am unable to group the rows lesson-wise and topic-wise. Tried using the macro-recorder, but the code does not work while generating multiple lessons.
EDIT: Working code is updated below.
function shiftrowgroupdepth() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
// start from row 6 and column 2
var row = 6;
var col = 2;
//Ask user for the no. of lessons
var shlen = Browser.inputBox("Enter no of lessons", Browser.Buttons.OK_CANCEL);
for (var i = 1; i <= shlen; i++) {
sheet.getRange(row,col).setValue("Lesson " + i);
row++;
Logger.log(spreadsheet.getCurrentCell().getRow())
sheet.getRange(row, 1, 70, sheet.getMaxColumns()).activate()
.shiftRowGroupDepth(1);
// Add sub-topics (1.1, 1.2 ....)
for (var j=1;j<=10;j++){
sheet.getRange(row,col).setValue(i+"."+j);
sheet.getRange(row+1, 1, 6, sheet.getMaxColumns()).activate()
.shiftRowGroupDepth(1);
row=row+7;
}
}
};
The OP code was very close to the mark. The main changes in this answer are:
When using a 'dot' separator for the topic codes, Google sheets treats the resulting value as a number; this creates problems displaying '1.10'. I changed the separator to a 'dash'. No doubt there is another potential approach using toString - but this was quick and easy.
The Lesson grouping is straightforward; 10 topics, 7 rows per topic = 70 rows.
Topic grouping had been complicated by referring to the location of the "current cell" - which could be anywhere on the sheet. I simplified this by using the row variable, which the OP had already (correctly) incremented.
function so5774532602() {
var ss = SpreadsheetApp.getActive();
var sheetname = "OPSheet";
var sheet = ss.getSheetByName(sheetname);
var row = 6;
var col = 2;
//Ask user for the no. of lessons
var shlen = Browser.inputBox("Enter no of lessons", Browser.Buttons
.OK_CANCEL);
for (var i = 1; i <= shlen; i++) {
sheet.getRange(row, col).setValue("Lesson " + i);
// add grouping
// Logger.log("DEBUG: i = "+i+", lesson range = "+sheet.getRange(+(row + 1), 2, 70, 1).getA1Notation());
sheet.getRange(+(row + 1), 2, 70, 1).activate()
.shiftRowGroupDepth(1);
row++;
// Add sub-topics (1.1, 1.2 ....) leave 6 blank rows below each sub-topic. Then, group those blank rows
for (var j = 1; j <= 10; j++) {
// Logger.log("DEBUG: i = "+i+", j = "+j+", row = "+row+", col = "+col); // new
sheet.getRange(row, col).setValue(i + "-" + j);
// add grouping
// Logger.log("DEBUG: range details: row = "+(row + 1) +",column = 1"+"number of rows = "+6+", number of columns = 1");
// Logger.log("DEBUG: topic range = "+sheet.getRange(+(row + 1), 2, 6, 1).getA1Notation());
sheet.getRange(+(row + 1), 2, 6, 1).activate()
.shiftRowGroupDepth(1);
row = row + 7;
}
}
}
Edit
Two minor changes for formatting
sheet.getRange(row,col).setValue("Lesson " + i).setHorizontalAlignment("center");
Centres the Lesson Number in the column.
sheet.getRange(row,col).setNumberFormat("#").setValue(i+"."+j).setHorizontalAlignment("center");
A return to a 'dot' separator but enables the tenth topic to display as 1.10, etc (credit #Tanaike). Will also center the text in the column.

Need to Set_Formula on Insert_Row from IFTTT

Novice Google Apps Scripter here,
I have an IFTTT applet which adds a row to this spreadsheet via email: Data Test
I seem to have the formulas set up correctly, but when a new row is added, the formulas obviously do not auto-populate into that new row. When a row is inserted, in which the corresponding cells in Columns A and B are not blank, I'd like set certain formulas in that row.
The script I have so far (see below) does give me the formulas I want, but only in Row1.
I'd like the script to set those same formulas into corresponding cells of any new row that is inserted.
For example, IFTTT.com automation will populate cells A6 and B6 with text (i.e., next blank row in linked spreadsheet) -- I need all of the formulas currently entered to then apply to B6 (as opposed to B2)
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("C1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("details",$B2)+7,SEARCH(",",$B2)-SEARCH("details",$B2)-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("D1");
cell.setFormula('=IFERROR(TRIM(LEFT(SUBSTITUTE(MID(B2,FIND("$",B2),LEN(B2))," ",REPT(" ",100)),100)),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("E1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("exceed",$B2)+7,SEARCH("%",$B2)-SEARCH("exceed",$B2)-6),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("F1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("due",$B2)+3,SEARCH(";",$B2)-SEARCH("due",$B2)-3),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("G1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("held on",$B2)+7,SEARCH(". Lottery",$B2)-SEARCH("held on",$B2)-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("H1");
cell.setFormula('=IFERROR(MID($B2,SEARCH("posted by",$B2)+9,SEARCH(". ",$B2)-SEARCH("",$B2)-167),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
}
Any assistance will be greatly appreciated!
Try this out:
var ss = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
var items = [
{name: 'Add Row', functionName: 'addrow'},
];
ss.addMenu('Add Row', items);
}
function addrow() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var result = ui.prompt(
'Enter number of Row',
ui.ButtonSet.OK_CANCEL);
// Process the user's response.
var button = result.getSelectedButton();
var rownum = result.getResponseText();
if (button == ui.Button.OK) {
// User clicked "OK".
sheet.insertRowAfter(rownum);
var cell = sheet.getRange("C" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("details",$B' + rownum +')+7,SEARCH(",",$B' + rownum +')-SEARCH("details",$B' + rownum +')-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("D" + rownum);
cell.setFormula('=IFERROR(TRIM(LEFT(SUBSTITUTE(MID(B' + rownum +',FIND("$",B' + rownum +'),LEN(B' + rownum +'))," ",REPT(" ",100)),100)),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("E" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("exceed",$B' + rownum +')+7,SEARCH("%",$B' + rownum +')-SEARCH("exceed",$B' + rownum +')-6),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("F" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("due",$B' + rownum +')+3,SEARCH(";",$B' + rownum +')-SEARCH("due",$B' + rownum +')-3),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("G" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("held on",$B' + rownum +')+7,SEARCH(". Lottery",$B' + rownum +')-SEARCH("held on",$B' + rownum +')-7),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
var cell = sheet.getRange("H" + rownum);
cell.setFormula('=IFERROR(MID($B' + rownum +',SEARCH("posted by",$B' + rownum +')+9,SEARCH(". ",$B' + rownum +')-SEARCH("",$B' + rownum +')-167),HYPERLINK("https://housing.sfgov.org/listings","See Housing Portal"))');
} else if (button == ui.Button.CANCEL) {
// User clicked "Cancel".
} else if (button == ui.Button.CLOSE) {
// User clicked X in the title bar.
}
}
This is something that I've done in the past. I was surprised to learn that there was a setFormula command because I didn't use it in this situation and the below technique is working fine.
for(var i = 0;i < rowA[0].length; i++)
{
var initial_value = rowA[0][i];
//rowA[0][i] = '=ArrayFormula(IF(Row($B:$B)=1,"' + initial_value + '",IF(LEN($B:$B),IF(REGEXMATCH($C:$C,"(?i)(' + initial_value + ')"),$D:$D,""),)))';
rowA[0][i] = '=ArrayFormula(IF(Row(' + sr + ')=1,"' + initial_value + '",IF(LEN(' + sr + '),IF(REGEXMATCH(' + sr + ',"(?i)(' + initial_value + ')"),' + vr + ',""),)))';
}
rowrng.setValues(rowA);
It's a little different from what your doing in that I'm setting all of the array values before running the setValues command. But this has been working for months.

how to add a row in google spreadsheet and reference another cell?

I'm trying to create a function to pull data from google finance and have it automatically log data to multiple sheets of a document. I can't seem to get it to add a function as a function it always adds it as text until i edit the cell
function addLog() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var numLastRows = rows.getLastRow();
sheet.appendRow(['2012/10/28','=b92','=c92','Log (auto)','','=index(GoogleFinance(C92,"price",A92);2;2)','','=h92','=i92','=j92','=k92']);
};
i couldn't figure out how to make it reference the cell above (row 92 in this case) either :(
You will need to use the setFormula() method rather than appendRow(). Perhaps something like:
function addLog() {
var sheet = SpreadsheetApp.getActiveSheet();
var numLastRow = sheet.getLastRow();
//add a row at end if necessary
if (sheet.getMaxRows() == numLastRow) sheet.insertRowAfter(numLastRow);
sheet.getRange(numLastRow + 1, 2, 1, 10)
.setFormulas([['=b' + numLastRow,
'=c' + numLastRow,
'',
'',
'=index(GoogleFinance(C' + numLastRow + ',"price",A' + numLastRow + ');2;2)',
'',
'=h' + numLastRow,
'=i' + numLastRow,
'=j' + numLastRow,
'=k' + numLastRow]]);
sheet.getRange(numLastRow + 1, 1).setValue('2012/10/28');
sheet.getRange(numLastRow + 1, 4).setValue('Log (auto)');
}
To perform this action from the xth sheet through to the yth sheet (using zero-based index), I think the most efficient way would be:
function addAllLog() {
var sheets = SpreadsheetApp.getActive().getSheets();
var x = 1;
var y = 34;
for (var i = x; i <= y; i++) {
addLog(sheets[i]);
}
}
function addLog(sheet) {
var numLastRow = sheet.getLastRow();
//add a row at end if necessary
if (sheet.getMaxRows() == numLastRow) sheet.insertRowAfter(numLastRow);
sheet.getRange(numLastRow + 1, 2, 1, 10)
.setFormulas([['=b' + numLastRow,
'=c' + numLastRow,
'',
'',
'=index(GoogleFinance(C' + numLastRow + ',"price",A' + numLastRow + ');2;2)',
'',
'=h' + numLastRow,
'=i' + numLastRow,
'=j' + numLastRow,
'=k' + numLastRow]]);
sheet.getRange(numLastRow + 1, 1).setValue('2012/10/28');
sheet.getRange(numLastRow + 1, 4).setValue('Log (auto)');
}