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.
Related
I have a sheet "Sheet1" where a user inputs data in cells A3:E3. The goal is to then move that data into "Sheet2" where column A4:A34 is a numeric value for the day of the month. I want to move the data inputted on "Sheet1" into "Sheet2" on the row that corresponds with the current day of the month. Then "Sheet1" would clear itself for the next day ahead.
I'll be honest I'm not great with functions and I'm mainly looking for help on where to look to find a solution. I've tried different code that I do know how to use like Query but the issue is it doesn't lock the value in place and as soon as the values are wiped in Sheet1 they are then removed via the query.
You will need to run a function on a time-driven trigger. The function can use Range.getValues() to read the data, get the current date's day number with const dayNumber = new Date().getDate(), look up the day number in Sheet2 with Range.getValues().flat().indexOf(dayNumber), write the data with Range.setValues() and finally clear the source range with Range.clearContent().
It is unclear what the purpose the day numbers in Sheet2 serve, because the data would in any case be written once a day. It would seem simpler to always append the most recent data at the first available row and include a timestamp.
For an example of how to do this, see the appendRowsToArchiveSheet script.
Since the task is rather simple, here is the code that does the work:
// add menu Scripts
function onOpen() {
SpreadsheetApp.getUi().createMenu('🔨 Scripts')
.addItem('✅ Copy to archive', 'copy_range_to_archive')
.addItem('❌ Erase', 'erase_range')
.addToUi();
}
// erase the range A3:E3
function erase_range() {
SpreadsheetApp.getActiveSpreadsheet()
.getSheets()[0]
.getRange("A3:E3")
.clearContent();
}
// copy the range A3:E3 to Sheet 2
function copy_range_to_archive() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const src_range = ss.getSheets()[0].getRange("A3:E3");
const data = src_range.getValues();
const dest_sheet = ss.getSheets()[1];
const today = new Date().getDate();
const dest_range = dest_sheet.getRange(3 + today, 2, 1, data[0].length);
dest_range.clearContent();
dest_range.setValues(data);
}
It makes the menu 'Scripts' and two command 'Copy to archive' (the range A3:E3) and 'Erase' (the same range).
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);
}
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
Every day we put all of the times our product is sent in column B of Sheet 1. Would it be possible at close of play every day (say 23:55) to copy the contents of column B to a column in Sheet 2?
The big problem here is every day it would move along a column in sheet 2. So Monday would be pasted into B, Tuesday C, and so on.
Basically want to use sheet 2 to keep a record of all our send times.
Here is a script that copies column B of Sheet1 to a new column in Sheet2. I think the variable names and method names are self-explanatory. To have it run daily, in the script editor go to "Edit > this project's triggers" and set a time-driven trigger to run daily between 23:00 and midnight. (You don't get to choose the exact minute; it will be about the same every day but Google chooses it itself at the time of trigger creation).
function copyData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceRange = ss.getSheetByName("Sheet1").getRange("B:B");
var targetSheet = ss.getSheetByName("Sheet2");
targetSheet.insertColumnAfter(targetSheet.getLastColumn());
var targetRange = targetSheet.getRange(1, targetSheet.getLastColumn()+1);
sourceRange.copyTo(targetRange);
}
Is it possible to write a google script that will delete a row in a Google Sheet, based on cell values for a given range, in another google sheet?
I've done some research on how to do this all in the same google sheet, but my limited experience with writing google sheet scripts has prevented me from understanding if what I described is possible, and how.
This is a script I have so far. This will delete rows in a range of my active spreadsheet if a cell in Column F contains the word "id:123456". What I'd like to be able to do, is to modify this code so that if the word "id:123456" is found, it will look in another column of another Google Sheet, and delete rows that contain "id:123456".
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Sheet1'); // change to your own
var values = s.getDataRange().getValues();
for (var row in values)
if (values[row][6] == 'id:123456')
s.deleteRow(parseInt(row)+1);
};
I haven't tested this code, so you might need to do some modifications to run successfully. But the basic idea is simple: have two sheets open at once, and based on the if from the first sheet make changes in the second sheet.
var ss1 = SpreadsheetApp.getActiveSpreadsheet();
var ss2 = SpreadsheetApp.getByID(0); //Change to the other sheet's ID, or somehow open it.
var s1 = ss1.getSheetByName('Sheet1'); // change to your own
var s2 = ss2.getSheetByName('Sheet1'); // change to your own
var values = s1.getDataRange().getValues();
for (var row in values)
if (values[row][6] == 'id:123456')
var other_values = s2.getDataRange().getValues();
for (var other_row in other_values)
if (other_values[row][6] == 'id:123456')
s2.deleteRow(parseInt(other_row)+1);
Main thing to be worried about and test: I copied your delete code, but since we're deleting rows, unless we start from the bottom we might start missing. (Suppose rows 4 and 8 out of 10 contain something to be deleted; you might end up deleting 4, which turns 8 to 7, but then we still delete row 8--meaning that we've missed a row we should have deleted and deleted a row we shouldn't have.)