Insert specific number of rows in a google sheet - google-apps-script

I am trying to insert a specific number of cells into a Google sheet based on a number that is saved as a range. For example, the number in the range is 52, so on sheet 'Master' I want to insert 52 rows after row A3. This range is found on the sheet 'Staff' and changes according to how many staff were present each day, therefore, making it dynamic.
I am looking for some gscript to do this. I have been able to do this using a macro in Excel VBA but would like to move this from Excel to Google Sheets. The VBA code looks like this:
Sheets("Master").Select
Range("A3").EntireRow.Resize(Range("staff_count").Value).Insert CopyOrigin:=xlFormatFromRightOrBelow
Would be very grateful if anyone could help.
Thanks

You want to insert a given number of rows after row 3 on "Master". The number of rows is the value of a range on another sheet "Staff". This value will change from day to day.
In the following example, the range on Staff is cell "B1" and its value is 52.
There are several methods of doing this. In this example, I've used insertRowsAfter(afterPosition, howMany)doc. However, you could also use insertRows(rowIndex, numRows) doc.
function so5910073802() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var mastersheetname = "Master";
var master = ss.getSheetByName(mastersheetname);
var staffsheetname = "Staff";
var staff = ss.getSheetByName(staffsheetname);
// Staff range and value
var staffAttendRange = staff.getRange("B1");
var staffAttendValue = staffAttendRange.getValue(); // value = 52
// Logger.log("DEBUG: Staff attendance = "+staffAttendValue);
// Master variables
var headerRows = 3;
// insert the rows on Master based on value from Staff
master.insertRowsAfter(headerRows, staffAttendValue);
}
Before vs After
The value on row 4 and row 56 is =row()
BEFORE
AFTER

Related

Macro Google Sheet Copy and Paste on Every day

needs help regarding the macro
I currently have such a code
function getDynamicRows(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('B.Wioski');
var sourceRange = sheet.getRange('A1:F26500');
var data = sourceRange.getValues(); // Array of arrays [[Row1],[Row1],[Row3]]
// add data to next empty row in the static sheet.
var targetSheet = ss.getSheetByName('TW');
data.forEach(function(row){
targetSheet.appendRow(row)
}) ;
}
but the google sheet has a problem because the macro works max 6 min and it reads a maximum of 400 lines
and I would need a Macro that would copy A1 cells to F26500 where it would perform this activity 4 times a day every 6h for a maximum of 7 days and then on the 8th day it would delete the first day or overwrite the cells again
Instead of appendRow() use setValues().
If you keep exceeding the 6 mins, you can create multiple triggers (Row 1-5000, 5001-1000...) or copy the entire sheet and set formulas in your 'TW' sheet making reference to the copied sheets.

How do I automatically copy formules from above row in Google Sheets?

I have made a simple user interface to get user data. It gets a few entries, puts it into the designated database and clears the form. That works fine. While columns 0 to 6 are user data, columns 7 to 11 are formulas using data from 0 to 6. I'm looking for a solution that the user does not have to put in data and then manually needs to copy the above formulas. I don't want to put in the formulas before hand, because I think I will have a problem since the script looks for the last row.
So in short: it needs to find the last row on the sheet, write the data in to a new row and copy formulas in column 7 to 11 from the row above it to the new row. Total noob here, does this make sense?
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Form");
var datasheet = ss.getSheetByName("Database");
var values = [[formSS.getRange("d3").getValue(),
formSS.getRange("d5").getValue(),
formSS.getRange("d7").getValue(),
formSS.getRange("d9").getValue(),
formSS.getRange("d11").getValue(),
formSS.getRange("d13").getValue()]]
datasheet.getRange(datasheet.getLastRow()+1,1,1,6).setValues(values)
formSS.getRange("d3").clearContent();
formSS.getRange("d5").clearContent();
formSS.getRange("d7").clearContent();
formSS.getRange("d9").clearContent();
formSS.getRange("d11").clearContent();
formSS.getRange("d13").clearContent();
}
There are several options for solving your task:
Option 1: When generating an array of data for the row to be inserted, you can read the formulas from the previous row and add them to the array before inserting
...
var values = [formSS.getRange("d3").getValue(),
formSS.getRange("d5").getValue(),
formSS.getRange("d7").getValue(),
formSS.getRange("d9").getValue(),
formSS.getRange("d11").getValue(),
formSS.getRange("d13").getValue()],
lastRow = datasheet.getLastRow(),
formulas = datasheet.getRange(lastRow,7,1,5).getFormulasR1C1();
datasheet.getRange(lastRow+1,1,1,11).setValues([[...values,...formulas[0]]])
...
Option 2. You can insert formulas directly in the script without reading them from the sheet
...
var values = [[formSS.getRange("d3").getValue(),
formSS.getRange("d5").getValue(),
formSS.getRange("d7").getValue(),
formSS.getRange("d9").getValue(),
formSS.getRange("d11").getValue(),
formSS.getRange("d13").getValue(),
'=FormulaR1C1 for column 7',
`=IMPORTXML(R1C2&R[0]C[-6]&"/","//div[#class='priceValue ']")`,
'=FormulaR1C1 for column 9',
'=FormulaR1C1 for column 10',
'=FormulaR1C1 for column 11',]]
datasheet.getRange(datasheet.getLastRow()+1,1,1,11).setValues(values)
...

Google Sheets: Updating data in an existing row

I am just a couple of weeks into my coding adventure. I am trying to build a sheet that will edit values in existing cells based on the value in another cell. I was able to write a script that would write a new row in the database based on the values in the dashboard when the script was run.
function submitClientContact() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("New Client Form"); //Form Sheet
var datasheet = ss.getSheetByName("Info for Sales"); //Data Sheet
//Input Values
var values = [[formSS.getRange("E4").getValue(),
formSS.getRange("E3").getValue(),
formSS.getRange("E5").getValue(),
formSS.getRange("C8").getValue(),
formSS.getRange("C9").getValue(),
formSS.getRange("C10").getValue(),
formSS.getRange("C11").getValue(),
formSS.getRange("C12").getValue(),
formSS.getRange("C13").getValue(),
formSS.getRange("C14").getValue(),
formSS.getRange("C16").getValue(),
formSS.getRange("C17").getValue(),
formSS.getRange("C18").getValue(),
formSS.getRange("C19").getValue(),
formSS.getRange("C20").getValue(),
formSS.getRange("C21").getValue(),
formSS.getRange("C22").getValue(),
formSS.getRange("C24").getValue(),
formSS.getRange("C25").getValue(),
formSS.getRange("C26").getValue(),
formSS.getRange("C27").getValue(),
formSS.getRange("C28").getValue(),
formSS.getRange("C29").getValue(),
formSS.getRange("C30").getValue(),
formSS.getRange("E8").getValue(),
formSS.getRange("E9").getValue(),
formSS.getRange("E10").getValue(),
formSS.getRange("E11").getValue(),
formSS.getRange("E12").getValue(),
formSS.getRange("E13").getValue(),
formSS.getRange("E14").getValue(),
formSS.getRange("E16").getValue(),
formSS.getRange("E17").getValue(),
formSS.getRange("E18").getValue(),
formSS.getRange("E19").getValue(),
formSS.getRange("E20").getValue(),
formSS.getRange("E21").getValue(),
formSS.getRange("E22").getValue(),
formSS.getRange("E24").getValue(),
formSS.getRange("E25").getValue(),
formSS.getRange("E26").getValue(),
formSS.getRange("E27").getValue(),
formSS.getRange("E28").getValue(),
formSS.getRange("E29").getValue(),
formSS.getRange("E30").getValue()]];
datasheet.getRange(datasheet.getLastRow()+1, 1, 1, 45).setValues(values);
var sheet = SpreadsheetApp.getActive().getSheetByName("New Client Form");
sheet.getRange("E3:E5").clearContent();
var sheet = SpreadsheetApp.getActive().getSheetByName("New Client Form");
sheet.getRange("C8:C30").clearContent();
var sheet = SpreadsheetApp.getActive().getSheetByName("New Client Form");
sheet.getRange("E8:E30").clearContent();
}
I now need a script to edit the cells in the database. The sheet will have 3 primary functions. 1 dropdown containing all of the clients in the database (cell A1), 1 row to show the data that is in the database for that client (column A), and one row that would be used to edit that existing data (column B). I can build the lookup equations easily, but I need help with the script to edit the database.
I basically need a script that will use the data in the drop down (A1) to reference the row in the database in which data needs to be edited, followed by editing all 45 columns but leaving blank cells (blank in column B) alone.
I assume it is just a couple of lines that I am missing to make this work, but I have been struggling with this for far too many hours.

Google Sheets, fill data from form sheet into specific cells on other sheets

I'm new to coding in general (other than experience with MATLAB which I don't think counts) but I'm starting with trying to code in the Google Sheets API for some advanced functionality.
The code I'm trying to write is for a spreadsheet that I track all my car expenses on. I have it doing a bunch of number crunching for MPG currently, but don't want to have to find the row and column each time to enter the date. Instead I'd like one sheet that is clean and simple that I enter the variables on (Miles driven, gallons pumped, price per gallon, estimated MPG from the car computer) and it fills the other sheets in the document with that information automatically when I hit save, then clears the form so I can do it again next time.
Here is what I have so far.
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName('Fill-Up'); //Form Sheet
var datasheet1 = ss.getSheetByName('Mileage Stats'); //Data Sheet 1
var datasheet2 = ss.getSheetByName('Costs and Savings'); //Data Sheet 2
//Input Values 1
var values1 = [[formSS.getRange('B3').getValue(),
formSS.getRange('B6').getValue()]];
datasheet1.getRange(datasheet1.getLastRow()+1, 2, 1, 2).setValues(values1);
//Input Values 2
var values2 = [[formSS.getRange('B4').getValue(),
formSS.getRange('B5').getValue()]];
datasheet2.getRange(datasheet2.getLastRow()+1, 2, 1, 2).setValues(values2);
}
It works with the exception of two issues that I haven't been able to solve yet.
1) It writes the information to a new row at the bottom of the page, not the next empty row.
2) It isn't writing the information in B6 to the correct cell. I want B3 written to column B in "Mileage Stats" sheet, and it is, B4 is written to column B in "Costs and Savings" as I want, and B5 is written to column C in "Costs and Savings" as I want, but B6 is written to column C in "Mileage Stats" but I want it in column G, and can't figure out how to change that with my current code, or any other code I can find.
Any help anyone can give would be awesome!
Are you using any ArrayFormulas on the sheets that you are trying to use getLastRow()? If so, ArrayFormula will add data into the cells for the whole range.
You may want to look at using the Sheet.appendRow() method like below and remove all the empty rows on your data sheets. appendRow() will add a new row at the bottom of the sheet with that data passed to the method.
datasheet1.appendRow(values1);
datasheet2.appendRow(values2);
Cells with functions are counted as data cells, that's why you're inserting the rows at the bottom of the sheet. To solve this, you can use getNextDataCell() method to a column range without functions (e.g. a cell in column B), which returns the last cell with data for a given direction. I tested the below code and worked for inserting the data in the last row with data in column B:
function submitData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName('Fill-Up'); //Form Sheet
var datasheet1 = ss.getSheetByName('Mileage Stats'); //Data Sheet 1
var datasheet2 = ss.getSheetByName('Costs and Savings'); //Data Sheet 2
//Input Values 1
var values1 = [[formSS.getRange('B3').getValue(),
formSS.getRange('B6').getValue()]];
var lastRowInB = datasheet1.getRange("B6").getNextDataCell(SpreadsheetApp.Direction.DOWN).getLastRow();
datasheet1.getRange(lastRowInB+1, 2, 1, 2).setValues(values1);
//Input Values 2
var values2 = [[formSS.getRange('B4').getValue(),
formSS.getRange('B5').getValue()]];
lastRowInB = datasheet1.getRange("B7").getNextDataCell(SpreadsheetApp.Direction.DOWN).getLastRow();
datasheet2.getRange(lastRowInB+1, 2, 1, 2).setValues(values2);
}

Google Sheets (Google Finance) - Get stock price once and track

I would like to, upon data being entered into a new row (from external sheet - date, time, stock ticker), use google finance to get the current price of the stock into a cell and then no longer update the price in that cell. In the cell next to it, I want to track the price and in the cell next to that, I want to track the high, since creation (the highest value of the 'current price' cell).
Here is my sheet https://docs.google.com/spreadsheets/d/1EUU1bZnIfBatNI8H9pPk202PCD1g8wWXt5M0wx6S-jM/edit?usp=sharing
All I've got so far is a high value tracker that runs on the first row only for the right cells. Embarrasingly enough I can't figure out how to apply it to the entire columns.
So in summary, date time and stock will be entered into column A B and C. When that happens, I want to get the current price of the stock in C, and have that number no longer update. In D I want the price to be tracked, like Google Finance normally functions, and in E, the highest value of the D, in the same row.
That's the goal. Any help would be very much appreciated :)
All I've got so far is a high value tracker that runs on the first row
only for the right cells. Embarrasingly enough I can't figure out how
to apply it to the entire columns.
The code bound to your spreadsheet is
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("D2:E2");
var values = range.getValues()[0];
range.setValues([[values[0], Math.max(values[0], values[1])]]);
}
What does this code do?
It sets the range to work with always to D2:E2 - no matter what the actual edited range is
It works only with the first row of the range (range.getValues()[0])
It compares the 0 and 1 columns of the range (e.g. columns D and E) and assigns the value of column D back to column D (is it necessary?) and the higher of the two values to column E
How to modify your code?
It is not quite clear from your description how column D is populated and what you want to do with column F, but to give your general advice:
If you want your function to run on all rows:
Modify your range and expand it until the last row. Subsequently loop
through all rows:
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var range = sheet.getRange("D2:E"+lastRow);
for (var i = 0; i < lastRow-1; i++){
var values = range.getValues()[i];
range.setValues([[values[0], Math.max(values[0], values[1])]]);
}
}
If you want you code to run only on the currently edited row:
Use the event object e.range to find out which is the edited row and work on this row:
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var range = e.range;
var row = range.getRow();
var values = sheet.getRange(row, 4, 1, 2).getValues()[0];
range.setValues([[values[0], Math.max(values[0], values[1])]]);
}
Note: getRange(row, 4, 1, 2) is the notation to get the range starting with the defined row and column 4 (D), 1 row long and two columns wide, see here.
IMPORTANT: If your sheet is being populated automatically from an
external sheet - the onEdit trigger will not work for you (it only
fires on manual, human-made edits). In this case you will need a
workaround as described here.