I want to solve this problem in simplest way.
How to daily increment value in specified cell or range of cells. For exemple in cell 'A1' i insert today value 15. Tommorow this value will be 16, day after tommorow 17 etc.
I dont think anything exists which will automatically go in to your spreadsheets and fiddle with your values. But you can use a formula based on some start date:
=DATEDIF(DATE(2015, 1, 6), TODAY(), "D")
This will calculate how many days there have been since 2015 Jan 6. Today for me the answer is 15, and tomorrow it will be 16.
Another option is to add a time trigger or an onOpen() trigger to your spreadsheet. When you open your spreadsheet, the function would check the cell you are incrementing, get the last value, check if the last value is the value for the current day, and if it isn't add a new value.
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheets()[0];
var cellValue = sheet.getRange("A1");
var theDate = new Date().getDay();
Logger.log('theDate: ' + theDate);
var todaysNumber = theDate;
if (cellValue != todaysNumber) {
cellValue.setValue(todaysNumber);
};
};
Please try in A1:
=now()-42010
format as number, no decimals and in File, Spreadsheet settings... ensure Recalculation: is set to On change and something.
Related
Please Forgive me if this has been covered couldn't find it. But Does anyone have an idea on how to get a weekday (monday, Tues, Ect...) in this Script i have running.
function newColumn() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Song of the Day');
sheet.insertColumnAfter(1);
sheet.getRange("B1").setValue(new Date()).setNumberFormat('mmm/d/yyyy');
}
Currently ^ It makes a new column B and adds the date in cell B1 Every day I would just like that date to remain the same but also display the day of the week beside it also Thanks in advance!
Display Day of Week:
function DisplayDayOfWeek() {
Logger.log(["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][new Date().getDay()])
}
If I understand right you want Column B to contain the date, and you want that to format like 'mmm/d/yyyy' and then you want column C to also have the date but to be formatted to show the Name of the Day.
I would modify your script to place the date unformatted into both columns B and C, and then use the formatting controls in your spreadsheet to display them how you want to.
Your code would change to:
function newColumn() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Song of the Day');
sheet.insertColumnAfter(1);
sheet.getRange("B1").setValue(new Date());
sheet.insertColumnAfter(2);
sheet.getRange("C1").setValue(new Date());
}
On Your spreadsheet choose the Column C, then from Format>Custom Date and Time choose one with the Name of the Day listed, and remove the parts you don't want until it looks like this:
custom date image "Day Name Only"
If you wanted to format it with code then as shown here Javascript in Google Sheets script: help using setNumberFormat
you should grab the cell and format the cell:
var cell = sheet.getRange("B1");
cell.setNumberFormat('mmm/d/yyyy');
var cell = sheet.getRange("C1");
cell.setNumberFormat('dddd+');
Date number Formattings found here: https://developers.google.com/sheets/api/guides/formats
I see lots of for (var i + code written but I have never been able to understand it. I can set a formula but I dont know how to manipulate it.
My current struggle is that I want my script setFormula(=A1+B2+X) to work by grabbing a value and minusing 1 from it. As I understand it would probably end up as setFormula(=A1+B2+" + i + ")"
In my specific case, X can either be 1 of the 2 following (ideally the 2nd one) to be 24 (by getting the value of 25 and then minusing 1 from it). The date on the sheet is the 25th of the month is in cell A1, and the tab (sheet) name is xxx25. I need to be able to have X as 25-1: we want to end up with it printing =A1+B2+24 into the cell.
1: Day(A1)-1 (if the day in A1 was 25th of a month, this would give us the result of 24)
So in cell A1 on the current sheet it has DD MMMM YYYY so lets say if its the 25th of a month and year, it will set the formula in the sheet as =A1+B2+24
2: The tab (sheet) name is xxx25. This tab will always have 3 letters followed by the day of the month.
(In my case I have 1 for each day of the month, such as xxx1 xxx2 .. xxx9 xxx10. If this needs to be changed on my side to xxx01 xxx02 .. etc I can do that if required.)
So I guess this method would grab the last 2 values of the sheetname (the date, which in the example is 25th) so it extracts(?) it from xxx25 and now remembers 25, minuses 1 from it, and places it into the formula to become =A1+B2+24
Thanks, please let me know if any explanation more is needed.
Will this be a user-executed function that runs in the currently open sheet? If so, you could grab the active sheet's name and extract all but the first 3 characters from it:
function myFunc() {
let sheet = SpreadsheetApp.getActiveSheet();
let cell = sheet.getRange('C1'); // Replace with the desired cell
let sheetName = sheet.getName();
let onlyDate = sheetName.substring(3);
cell.setFormula(`=A1+B2+${onlyDate-1}`);
}
Using the value of A1:
Here I created a script that will create a custom menu. Whenever the menu is clicked, it will get the active range, use it to get the current sheet, get the value of A1, parse it and use its value in setFormula.
Code:
function onOpen() {
/*
This function will add a custom menu in Google Sheets
named Set Formula and will execute setFormula function
*/
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Set Formula', 'setFormula')
.addToUi();
}
function setFormula() {
var range = SpreadsheetApp.getActiveRange(); //get the active range
var sheet = range.getSheet(); //get the sheet of active range
var date = sheet.getRange('A1').getDisplayValue(); //get the value of A1
var day = date.split(" ")[0] //split using space and get the first element of array
range.setFormula(`=A1+B2+${day-1}`); //set formula to the active range
}
Demo:
References:
Custom Menu
I have a Google Sheets document that has 36 formulas across a row in the "Historical Data" tab. When I run the script each morning it populates the next empty row with the formulas in the previous row and then makes the previous row a value (so as to remove the formulas). I have an issue sometimes that the row with formulas loses the values and display "#N/A". I believe this is because the data is pulled from GoogleFinance.
Error in the image below.
I am curious if there is a method to do the following:
Define the formulas for each column in the code.
Run the script each morning and populate the next empty row with the values of the formulas.
The biggest item I need help with is adding the following formulas to the code so they will not be present in the worksheet. Additionally, some of the formulas rely on the value in a cell. For example the first formula is to create the date based on the date in the last row cell (A). The remaining formulas use the date from the new row columnm (a) and inputs from other columns in the new row. So when you see A2736 that is in last row and A2737 is the new row that was create when I last ran the script.
//DATE(A)=workday(A2736,1,'NYSE Holidays'!$A$2:$A$27)
//VIX9D(B)=INDEX(GOOGLEFINANCE("INDEXCBOE:VIX9D","close",$A2737),2,2)
//VIX1D(C)=INDEX(GOOGLEFINANCE("INDEXCBOE:VIX","close",$A2737),2,2)
//VIX3M(D)=index(GOOGLEFINANCE("INDEXCBOE:VIX3M","close",$A2737),2,2)
//VIX6M(E)=index(GOOGLEFINANCE("INDEXCBOE:VIX6M","close",$A2737),2,2)
//VIX1Y(F)=index(GOOGLEFINANCE("INDEXCBOE:VIX1Y","close",$A2737),2,2)
//VVIX(G)=index(GOOGLEFINANCE("INDEXCBOE:VVIX","close",$A2737),2,2)
//SPX(H)=index(GOOGLEFINANCE("INDEXSP:.INX","close",$A2737),2,2)
//VIX9D:VIX(I)=B2737/C2737
//VIX:VIX3M(J)=C2737/D2737
//VIX:VIX6M(K)=C2737/E2737
//VIX:VIX1Y(L)=C2737/F2737
//CORR, SPX , VVIX, 5(M)=correl(H2733:H2737,G2733:G2737)
//CORR, SPX , VIX, 10(N)=correl(H2728:H2737,C2728:C2737)
//Contango VIX2:VIX1(O) No formula yet
//Vix4:Vix7 Contango(P) No formula yet
//Log Ret(Q)=ln(H2737/H2736)
//V10(R)=stdev(Q2728:Q2737)
//V20(S)=stdev(Q2719:Q2737)
//HV10(T)=sqrt(252)*R2737
//HV20(U)=sqrt(252)*S2737
//VIX - HV10(V)=C2737-(T2737*100)
//VIX - hv20(W)=C2737-(U2737*100)
//VIX9D % Rank(X)=PERCENTRANK(B$2:B,B2737)
//VIX1D % Rank(Y)=PERCENTRANK(C$2:C,C2737)
//VIX3M % Rank(Z)=PERCENTRANK(D$2:D,D2737)
//VIX6M % Rank(AA)=PERCENTRANK(E$2:E,E2737)
//VIX1Y % Rank(AB)=PERCENTRANK(F$2:F,F2737)
//VVIX % Rank(AC)=PERCENTRANK(G$2:G,G2737)
//VIX9D Median(AD)=MEDIAN(B$2:B)
//VIX1D Median(AE)=MEDIAN(C$2:C)
//VIX3M Median(AF)=MEDIAN(D$2:D)
//VIX6M Median(AG)=MEDIAN(E$2:E)
//VIX1Y Median(AH)=MEDIAN(F$2:F)
//VVIX Median(AI)=MEDIAN(G$2:G)
//VDelta (VIX-VIX9D)(AJ)=C2737-B2737
Current code is below.
// Add Run button to menu
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu("Auto Trigger")
.addItem("Run","runAuto")
.addToUi();
}
// Define function to run with menu button
function runAuto() {
recordValue()
}
function createTimeDrivenTrigger() {
// Trigger every Weekday at 09:00.
ScriptApp.newTrigger('recordValue')
.timeBased()
.onWeekDay(ScriptApp.WeekDay)
.atHour(9)
.create();
}
// Record history from a cell and append to next available row
function recordValue() {
if (isNotHoliday()){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Historical_Data");
var lastRow = sheet.getLastRow();
var oldDate = sheet.getRange(lastRow,1).getValue();
var rng = sheet.getRange(lastRow,1,1,36);
rng.copyTo(sheet.getRange(lastRow+1,1,1,36));
rng.setValues(rng.getValues());
}
}
function isNotHoliday(){
var yesterday = new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()-1);
var formattedDate = Utilities.formatDate(yesterday, Session.getScriptTimeZone(), "M/d/yy")
var holidays = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('NYSE Holidays').getRange('A2:A').getDisplayValues().join().split(",");
return (! ~holidays.indexOf(formattedDate))
}
If you wish to run the script once every morning you could use programmatically triggers. This way you can easily set up a script run inside your desired time frame. Then you only would need to get the range of the last row and paste the formula there. I see that the script already gets the range, so you only need Range.setFormula() to drop the formula.
There is a much simpler way to do this - which is to flip time the other way.
You leave the google finance formulas in row 2 along with a =TODAY() in cell B2, with headers in row 1.
every night at 11pm, your sheet inserts a row above row 3, copies the values from row 2 into the new row 3 as values only.
That's it. super simple. you never need to copy formulas at all.
The newest prices are always at the top. This is how most people track portfolios.
I have a google sheet containing a date and time (eg. 02/07/2016 15:06:00) in column B.
I am wanting to highlight rows based on the 'hour' portion of the cell - typically anything between 12:00 and 12:59 to be highlight in one colour and anything else to be highlighted in another colour.
I have the following code which is working as expected, however it is based on a string value not a date value:
function Formatting1() {
var sheet = SpreadsheetApp.getActiveSheet();
var columnO = sheet.getRange(2, 1, sheet.getLastRow()-1, 1);
var oValues = columnO.getValues();
for (var i = 0; i < oValues.length; i++) {
if (oValues[i][0] == 'No call received') {
sheet.getRange(i + 2, 1, 1, 6 ).setBackgroundColor('#FF3300');
}
}
}
It's the handling of the date/time range that has me stumped! Any help would be hugely appreciated!
You can do this using conditional formatting and the formula rule =HOUR(D2) = 12 applied to B2:B.
If you want to use the function you just need to change the if statement to
if (oValues[i][0].getHours() === 12)
Assuming the first column of oValues contains the date.
Google Apps Script reads Spreadsheet dates as Javascript dates.
Be careful about timezones though, the timezone of a spreadsheet can be different from the time zone the script operates in so the conditional formatting option has less potential for headaches.
I am using a Google Sheet to track my portfolio and I have a cell that calculates the total current market value of my portfolio from various parts of the sheet.
I am trying to see if it is possible to create a script that will record the date as well as the market value (the value only, not the formula) automatically from this cell every day. I know it is possible to set a trigger to run the code weekly/daily, but am having trouble with the code itself.
I can think of 2 approaches. I wasn't sure how to code the second implementation, and what I have so far for the first implementation is below.
1) (First, use Cell A1 as a counter. Set initial value to, say, 3.)
function recordValue() {
//read the counter in Cell A1
var counter = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ThisSheet").getRange("A1")
//record current date in cell B&(contents of cell A1)
var dateCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ThisSheet").getRange("B"&counter)
outputRange.setValues(Utilities.formatDate(new Date(), Session.getTimeZone(), 'MM-dd-yyyy'));
//read the current market value in 'Summary'!A1 and record it in cell C&(contents of cell A1)
var marketValue = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Summary").getRange("A1:A1");
var outputCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ThisSheet").getRange("C"&counter);
outputCell.setValues(marketValue);
//add 1 to the counter in cell A1
counter.setValues(counter + 1);
};
2) Record the current date in the cell directly below, then read the current market value in 'SheetA'!A1 and record it in the cell to the right of the date. Then create a new, empty row directly below (ie pushing the recently written data down by one row)
I'm new to Google Sheets and don't have much programming knowledge. Will either of the above approaches work (and work well with a time-driven trigger)? What's wrong with the current code I have for the first implemetation?
Thanks!
I made some changes in your code because you don't use the getValue() .
I don't really understand exactly what you want to do but the code below works :
function recordValue() {
//read the counter in Cell A1
var counter = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ThisSheet").getRange("A1");
//record current date in cell B&(contents of cell A1)
var dateCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ThisSheet").getRange("B"+counter.getValue());
dateCell.setValue(new Date());
//read the current market value in 'Summary'!A1 and record it in cell C&(contents of cell A1)
var marketValue = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Summary").getRange("A1");
var outputCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("ThisSheet").getRange("C"+counter.getValue());
outputCell.setValue(marketValue.getValue());
//add 1 to the counter in cell A1
counter.setValue(counter.getValue() + 1);
}