Google Sheets Calendar - javascript

I would like some help in pulling certain data from a google form linked to a spreadsheet and set a certain value in the date of a certain employee. For example if he/she marked as Vacation Leave then the letter V will be marked under the Date. I have attached the link to my calendar to give an example, I have tried searching the net and this is my second time posting here.
I started the Code but I am stuck in actually finding the Cell for a certain date and inserting the letter.
https://docs.google.com/spreadsheets/d/1uFTR2_B7T0QBr7fTflByFffmmiszbNj_RaCvLEfYRCA/edit?usp=sharing
function setData(){
//Spreadsheets
var ss = SpreadsheetApp;
var data = ss.getActiveSpreadsheet().getSheetByName("Data");
var calendar = ss.getActiveSpreadsheet().getSheetByName("Calendar");
//Get last row / Individual Cells from Form
var lRow = data.getLastRow();
var lRowData = data.getRange(lRow,1,1,17).getValues();
var approval = data.getRange(lRow,17,1,1).getValue();
var leave = data.getRange(lRow,9,1,1).getValue();
var agentName = data.getRange(lRow, 5,1,1).getValue();
var dateBefore = data.getRange(lRow, 10,1,1).getValue();
var dateAfter = data.getRange(lRow, 11,1,1).getValue();
//Calander Variable Arrays
var allDates = calendar.getRange("LA1:NJ1").getValues();
var allNames = calendar.getRange("A4:A160").getValues();
for(var i = 0; i<allNames.length; i++){
if (approval === "Approved" && allNames[i][0] === agentName){
//Here I need it to insert the dates under the correct name and date with a value of V H S M U T.
};
};
};

You are building a spreadsheet-based Leave Calendar based on information from a form response. Based on your existing Calendar, you are having problems identifying the relevant leave dates, and then filling calendar cells to indicate proposed leave.
The problem is there are no fields in rows 1,2 or 3 of Calendar that have the same date format as the Start Date and End Date fields on Form. As a result, there's no easy way to search for a match of the form data fields.
The solution, in my view, is to change the format of the date fields in rows 2 and 3 and enable a search to be match.
Row 2
the existing format is "d" - day of the month (Numeric)
change the format to match the Form Start/End dates: "d-MMM-yyyy".
the font colour for this field can be used to "hide" these dates, and the column width reduced also.
Row 3
the existing format is "E" - day of the week (Name)
change the format to combine the existing formats of rows #2 and #3 - "E-d"
Aspects of the script
the form data is retrieved as getDisplayValues(). The purpose of this is to get the date as a string to facilitate the search.
Two sets of Calendar data are obtained
1) the dates row (Row#2)
2) the names column (Col #1). The Javascript map method is used to convert names from a 2D array to a 1D array. This creates an array that can be easily searched.
the Javascript indexOf method is used to find the Column match for the start and end dates, and to match the name in the Calendar Column (which yields the Row)
the script loops through the number of days leave to create a temporary array of "V" values.
using the row number and the start and end column numbers, a range can be defined on calendar and then updated from the values in the temporary array.
Presumably your function would be triggered by onFormSubmit(e).
Form data
Calendar - Before
Calendar - After
function so5871726503(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var form = ss.getSheetByName("Form");
var calendar = ss.getSheetByName("Calander");
//get form data
var formdataRange = form.getRange(6,1,1,9);// test data
var formData = formdataRange.getDisplayValues(); // display values to format date as string
//get the employee name, start date and end date
var formName = formData[0][1];
var formSD = formData[0][3];
var formED = formData[0][4];
// Logger.log("DEBUG: name = "+formName+", start date = "+formSD+", end date = "+formED);
//get Calendar variables
var calLR = calendar.getLastRow();
var calLC = calendar.getLastColumn();
var caldateStart = 9;
var calnameStart=4;
// get Calendar dates
var calDateRange = calendar.getRange(2,caldateStart,1,calLC-caldateStart+1);
var calDateValues = calDateRange.getDisplayValues();
// get Calendar names
var calNameRange = calendar.getRange(calnameStart,1,calLR-calnameStart+1);
var calNameValues = calNameRange.getValues();
var calNames = calNameValues.map(function(e){return e[0];});//[[e],[e],[e]]=>[e,e,e]
// there should be some error checking on indexof results = -1 in case there is a mismatch.
// find form start date in calender
var startdateresult = calDateValues[0].indexOf(formSD);
var startdateresultcol = startdateresult+caldateStart;
// Logger.log("DEBUG: start date result = "+startdateresult+", column = "+startdateresultcol);
// find form end date in calender
var enddateresult = calDateValues[0].indexOf(formED);
var enddateresultcol = enddateresult+caldateStart;
// Logger.log("DEBUG: end date result = "+enddateresult+", column = "+enddateresultcol);
// find form name in calender
var nameresult = calNames.indexOf(formName);
var nameresultrow = nameresult+calnameStart;
// Logger.log("DEBUG: name result = "+nameresult+", row = "+nameresultrow)
// calculate number of days leave
var daysleave = enddateresultcol-startdateresultcol+1
// Logger.log("DEBUG: days leave = "+daysleave)
// create array variable to hold leave data
var leave=[];
// loop to create data to fill Calendar
for (i=0;i<daysleave;i++){
leave.push("V");
}
// Logger.log(leave); // DEBUG
// build leave range
var calLeave = calendar.getRange(nameresultrow,startdateresultcol,1,daysleave);
//Logger.log(calLeave.getA1Notation()); //DEBUG
// Update the leave range
calLeave.setValues([leave]);
}

Related

how do i filter by date using google script?

I need to filter my spreadsheet based on today's date.
this is the code I used:
function myFunction() {
var SS = SpreadsheetApp.openById("19nlPw9jF8FCFwY-qYwdBILoGDazrH12c8BgYfhwWSKA");
var Sheet = SS.getSheetByName("All Joiners");
var Jun = SS.getSheetByName("01 Jun");
var data = Sheet.getRange(2, 1,Sheet.getLastRow(),Sheet.getLastColumn()).getValues();
var criteria = SpreadsheetApp.FilterCriteriaBuilder.whenDateEqualTo(new Date(Jun.getRange("A1")))
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(4, criteria);
}
A few things -
Your code retrieves the range of cell A1 on Jun - You also need
to get the value.
FilterCriteriaBuilder is not a function and
should be newFilterCriteria().
spreadsheet.getActiveSheet() should
be SS.getActiveSheet since you declared it as SS
Original Code:
var criteria = SpreadsheetApp.FilterCriteriaBuilder.whenDateEqualTo(new Date(Jun.getRange("A1"))).build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(4, criteria);
Should be:
let criteria = SpreadsheetApp.newFilterCriteria().whenDateEqualTo(new Date(Jun.getRange("A1").getValue())).build();
SS.getActiveSheet().getFilter().setColumnFilterCriteria(4, criteria);
Also, side note - you declared Sheet but didn't use it. If your intention was to update the column filter on that specific sheet and not the currently active sheet, then instead of SS.getActiveSheet(), it should be:
Sheet.getFilter().setColumnFilterCriteria(4, criteria);
If your sheet doesn't currently have a filter, you have to create it. In order to do that, retrieve the Range you want to apply the filter to and then call Range.createFilter(). So that line would be something like (Range being your desired range):
Range.createFilter().setColumnFilterCriteria(4, criteria);
Also, if your A1 cell is a Date (and not a string formatted like a Date) there's no need to use new Date() when setting the criteria:
const criteria = SpreadsheetApp.newFilterCriteria().whenDateEqualTo(Jun.getRange("A1").getValue()).build();

Trying to do Dynamic Equity Split calculations in Google Sheets

new to using javascript in Google Sheets. I am trying to create a sheet that automatically calculates what business partners will receive based upon their dynamic split percentage and the incoming money. The percentage comes from one cell, but each payment made to the partners will be entered in a column. Here's what I have so far:
/**
* Creates a Date Stamp if a column is edited.
* Also performs dynamic split calculations
*/
//CORE VARIABLES
// The column you want to check if something is entered.
var COLUMNTOCHECK = 13;
// Where you want the date time stamp offset from the input location. [row, column]
var DATETIMELOCATION = [0,-1];
// Where the calculations will be performed for the Partners.
var PARTNERONELOCATION = [0, 1];
var PARTNERTWOLOCATION = [0, 2];
var PARTNERTHREELOCATION = [0, 3];
// Sheet you are working on
var SHEETNAME1 = 'Sheet1'
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var partnerOnePercent = sheet.getRange("G2").getValue();
var partnerOnePaySource = sheet.getRange("M2").getValue();
var partnerTwoPercent = sheet.getRange("G3").getValue();
var partnerTwoPaySource = sheet.getRange("M2").getValue();
var partnerThreePercent = sheet.getRange("G4").getValue();
var partnerThreePaySource = sheet.getRange("M2").getValue();
//checks that we're on the correct sheet.
if(sheet.getSheetName() == SHEETNAME1 ) {
var selectedCell = ss.getActiveCell();
//checks the column to ensure it is on the one we want to cause the date and calculations to appear.
if( selectedCell.getColumn() == COLUMNTOCHECK) {
var dateTimeCell = selectedCell.offset(DATETIMELOCATION[0],DATETIMELOCATION[1]);
dateTimeCell.setValue(new Date());
var partnerOneCell = selectedCell.offset(PARTNERONELOCATION[0],PARTNERONELOCATION[1]);
partnerOneCell.setValue((partnerOnePercent/100)*partnerOnePaySource);
var partnerTwoCell = selectedCell.offset(PARTNERTWOLOCATION[0],PARTNERTWOLOCATION[1]);
partnerTwoCell.setValue((partnerTwoPercent/100)*partnerTwoPaySource);
var partnerThreeCell = selectedCell.offset(PARTNERTHREELOCATION[0],PARTNERTHREELOCATION[1]);
partnerThreeCell.setValue((partnerThreePercent/100)*partnerThreePaySource);
}
}
}
The thing I would like it to do is when I enter a payment into the column (column 13), Is for the payment to be split into the partner location cells (var partnerOneCell, var partnerTwoCell, var partnerThreeCell) that are offset from the cell that the payment amount is typed in, and I only want it to be calculated by the percentages as they are at the moment the payment amount is entered. Any help would be appreciated.
Right now it is only calculating based upon cell M2 (row 2, column 13). I want it to be able to calculate based upon the amount I enter in any cell within that column, and only the cell I am currently updating. I think that this has something to do with getActiveRange or something, but I'm not familiar enough with these methods.
Edit: Upon testing, it also seems that row 3 column 14 is reflecting a calculation of partnerOnePaySource*partnerOnePercent with PaySource coming from row 3 column 13 (M3), though I'm not sure why.
Alright everyone, after reading over my code, I realized how I could use the getActiveCell method within the PaySource variables.
var partnerOnePercent = sheet.getRange("G2").getValue();
var partnerOnePaySource = ss.getActiveCell().getValue();
var partnerTwoPercent = sheet.getRange("G3").getValue();
var partnerTwoPaySource = ss.getActiveCell().getValue();
var partnerThreePercent = sheet.getRange("G4").getValue();
var partnerThreePaySource = ss.getActiveCell().getValue();
With this I was able to fix my problem and it now works.

Extract ranges from multiple workbooks / sheets

I have a range of cells (ex: L1:S22) which will send email alert when the values are > 0 in that particular range from active spreadsheet
So far its only sending from the active spreadsheet range. I want it to be called from all other workbooks which is stored in a folder and send email according to that
function CheckSales(){
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
var data=activeSheet.getDataRange().getValues();
var emailAddress=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("B2").getValue();
var resultArr=[];
//To Loop through the whole data Rows
for(var i=1;i<data.length;i++)
{
//Takes columns from L to S (To loop through the Columns)
for(var j=11;j<19;j++)
{
var cellVal=data[i][j];
Logger.log(cellVal)
if(cellVal>0)
{
//Stores the Part No, Month Header Value of the Column, Cell Value which is greater then 0
resultArr.push([data[i][0],data[0][j],cellVal])
}
}
}
if(resultArr.length>0)
{
var subject = 'Range exceeded Alert';
//Creates a body through the obtained values
var body='';
for(var m=0;m<resultArr.length;m++)
{
body+="For Part No "+resultArr[m][0].toString()+" and Month "+resultArr[m][1].toString()+", Value is "+resultArr[m][2].toString()+"<br>";
}
MailApp.sendEmail({to:emailAddress,subject:subject,htmlBody:body});
}
}
now the output showing the part number which have exceeded the values after 6 months.
For Part No 60009257001 and Month 7MO, Value is 800
For Part No 60009259007 and Month 12MO, Value is 28032
For Part No 60009260011 and Month >18MO, Value is 74670
For Part No 60009260012 and Month 12MO, Value is 17600
For Part No 60009260013 and Month 10MO, Value is 26389
I expect the output to show all the part numbers from different workbooks
for (var i in activeSheet) {
SpreadsheetApp.setActiveSheet(activeSheet[i])
var sheet = app.getActiveSheet();
var data = activeSheet[i].getDataRange().getValues();
}
you can loop through the different data ranges in the same way as done here with "data" Variable.
For example,
var data=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Battery').getDataRange().getValues();
//For Loop for data
data2=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Other Sheet").getDataRange().getValues();
//for Loop for data2

Array size issue when copying GoogleSheet to another sheet

I need to get a sheet of data as an array, perform some processing, then save it to another sheet.
Without attempting any intermediate processing,
var booking = getRowsData(sheet); //should create the array
var range = target.getRange(lastDBRow+1,1,numRows); //obtains the destination range (numRows logged as 3)
then
range.setValues([booking]); //tries to save the values but throws an error "Incorrect range height, was 1 but should be 3"
Checking the booking object with
var response = ui.prompt(booking.length + " " + booking[0].length, ui.ButtonSet.OK);
shows length 3 and
booking[0].length (which I understood to be the columns) as undefined....
So why the row length mismatch?
And should the columns value be undefined?
My thanks in advance!
The full code is :
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('New booking');
var headers = sheet.getRange(1, 1,1,sheet.getLastColumn());
var lastRow = sheet.getLastRow();
var numRows= lastRow-1
var target = ss.getSheetByName('Test'); //temp redirect to test sheet
var lastDBRow =target.getLastRow(); //we want to append the data after this
var booking = getRowsData(sheet); // Get data to copy as array object
= ui.prompt(booking.length + " " + booking[0].length, ui.ButtonSet.OK);
// Returns 3 Undefined
var response = ui.prompt(numRows, ui.ButtonSet.OK);
// Returns 3
var range = target.getRange(lastDBRow+1,1,numRows); // Must match range size
range.setValues([booking]);
}
Looks to me like there is no column count defined in this range:
var range = target.getRange(lastDBRow+1,1,numRows); // Must match range size
range.setValues([booking]);
Without being about to use debug, I can't confirm my idea, but I see you are defining the starting row, the starting column and the number of rows, but not the number of columns. I don't know for sure if that error message would be caused by that, but it looks like something to consider.

Combine a Date & a Time Column in Google Sheets for a createEvent() function [duplicate]

This question already has an answer here:
How to merge date and time as a datetime in Google Apps Spreadsheet script?
(1 answer)
Closed 7 years ago.
I need to combine two columns into one dateTime column that can be reading by a createEvent function for startDate.
Column F is the date (mm-dd-yyyy) & Column G is the time (HH:mm PM/AM). I am currently combine them in Column H with the following code:
function conCat() {
var sheet = SpreadsheetApp.getActiveSheet();
var numberOfRows = sheet.getLastRow().toString();
var range = sheet.getRange(2,1,numberOfRows,12);
var values = range.getValues();
var consultedAlreadyFlag = sheet.getRange(2,10,numberOfRows,12);
var sheetName = sheet.getSheetName();
//show updating message
consultedAlreadyFlag.setFontColor('red');
var numValues = 0;
for (var row = 2; row < values.length.toString(); row++) {
//check to see if name and type are filled out - date is left off because length is "undefined"
if (values[row][3].length > 0) {
currentStatus = values[row][1];
//check if it's been entered before
if (values[row][9] != 'EMAIL_SENT'){
sheet.getRange(row+2,8,1,1).setValue('=F' +(row+2)+ '+G' +(row+2));
}
else{
//sheet.getRange(row+2,10,1,1).setValue('EMAIL_SENT');
}
numValues++;
}
//hide updating message
consultedAlreadyFlag.setFontColor('green');
}
}
This code isn't working because when someone submits the form, and the code combines the columns, I cannot get the format to come out as "mm-dd-yyyy HH:mm:ss" which I feel I need in order for my createEvent function to work.
How can I get it to combine the two columns to get the format I need?
I wouldn't bother trying to combine the two columns. There's no point in adding another column, I don't think. You can use JavaScript methods like setHours():
function fncAddToCalender() {
var theEventDate = //To Do - Get the Date
var startMin = value from sheet cell
theEventDate.setHours(15); //Sets event date to 3pm
theEventDate.setMinutes(startMin);
var cal = CalendarApp.getDefaultCalendar();
var event = cal.createEvent(calndrTitle, theEventDate, endDate, {
description : theDescrptn,
location : theLocation,
guests : guestToInvite,
sendInvites : true
});
};
The format in the spreadsheet is probably set to "date". And getting the values with Apps Script will probably return a value that's already in a date format. If you have the columns formatted as text, you'd need to change the values to a date.

Categories