why two combined image collections show 0 elements in the console of the google earth engine? - element

I used the .combine command to convert two image collections into a two-band image collection (in the last line) to use in a function in the next step. This command is executed but writes 0 elements in the console. Where does this problem come from?
code link :
https://code.earthengine.google.com/5ebed42b397e764e3229e3f224c8b643
code :
var Rad1 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2018-10-24','2019-05-20'))
.select('surface_solar_radiation_downwards');
var Rad2 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2019-05-20','2019-06-30'))
.select('surface_solar_radiation_downwards');
var Rad1_Mj = Rad1.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad1_Mj);
var Rad2_Mj = Rad2.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad2_Mj);
// time frame change function for median collection
var daily_product_median = function(collection, start, count, interval, units){
var sequence = ee.List.sequence(0, ee.Number(count).subtract(1));
var origin_date = ee.Date(start);
return ee.ImageCollection(sequence.map(function(i){
var start_date = origin_date.advance(ee.Number(interval).multiply(i),units);
var end_date =
origin_date.advance(ee.Number(interval).multiply(ee.Number(i).add(1)),units);
return collection.filterDate(start_date, end_date).median()
.set('system:time_start',start_date.millis())
.set('system:time_end',end_date.millis());
}))};
// daily radiation product
var daily_Rad_1 = daily_product_median(Rad1_Mj,'2018-10-24', 208 , 24 , 'hour');
// print(daily_Rad_1);
//Map.addLayer(daily_Rad_1, {min: 17.38, max: 26.07, palette :
['white','yellow','orange']},
'Daily solar shortwave radiation 1' );
var daily_Rad_2 = daily_product_median(Rad2_Mj,'2019-05-20', 41 , 24 , 'hour');
// print(daily_Rad_2);
// Map.addLayer(daily_Rad_2, {min: 23.77, max: 26.64, palette :
['white','yellow','orange']},
'Daily solar shortwave radiation 2');
var daily_Rad_total = daily_Rad_1.merge(daily_Rad_2);
//print(daily_Rad_total);
var START = '2018-10-24';
var END = '2019-06-30';
var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
'2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
'2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
'2019-06-27'];
var addTime = function(x) {
return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};
var final_Rad = ee.ImageCollection(daily_Rad_total)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print(final_Rad);
var ndvi = function(img){
var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
.clip(geometry);
var index = bands.normalizedDifference(['B8','B4']);
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
.map(ndvi);
print(S2);
var NDVI_and_Rad = S2.combine(final_Rad, false);
print(NDVI_and_Rad);

Try it here
You may use merge instead of combine to get a new image collection
var Rad1 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2018-10-24','2019-05-20'))
.select('surface_solar_radiation_downwards');
var Rad2 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
.filter(ee.Filter.date('2019-05-20','2019-06-30'))
.select('surface_solar_radiation_downwards');
var Rad1_Mj = Rad1.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad1_Mj);
var Rad2_Mj = Rad2.map(function(img){
var bands = img.multiply(0.000001);
var clip = bands.clip(geometry);
return clip
.copyProperties(img,['system:time_start','system:time_end']); });
//print(Rad2_Mj);
// time frame change function for median collection
var daily_product_median = function(collection, start, count, interval, units){
var sequence = ee.List.sequence(0, ee.Number(count).subtract(1));
var origin_date = ee.Date(start);
return ee.ImageCollection(sequence.map(function(i){
var start_date = origin_date.advance(ee.Number(interval).multiply(i),units);
var end_date = origin_date.advance(ee.Number(interval).multiply(ee.Number(i).add(1)),units);
return collection.filterDate(start_date, end_date).median()
.set('system:time_start',start_date.millis())
.set('system:time_end',end_date.millis());
}))};
// daily radiation product
var daily_Rad_1 = daily_product_median(Rad1_Mj,'2018-10-24', 208 , 24 , 'hour');
// print(daily_Rad_1);
//Map.addLayer(daily_Rad_1, {min: 17.38, max: 26.07, palette : ['white','yellow','orange']}, 'Daily solar shortwave radiation 1' );
var daily_Rad_2 = daily_product_median(Rad2_Mj,'2019-05-20', 41 , 24 , 'hour');
// print(daily_Rad_2);
// Map.addLayer(daily_Rad_2, {min: 23.77, max: 26.64, palette : ['white','yellow','orange']}, 'Daily solar shortwave radiation 2');
var daily_Rad_total = daily_Rad_1.merge(daily_Rad_2);
//print(daily_Rad_total);
var START = '2018-10-24';
var END = '2019-06-30';
var DATES = [ '2018-12-19', '2018-12-29', '2019-01-23', '2019-02-12', '2019-03-04',
'2019-03-19', '2019-04-08', '2019-04-13', '2019-05-13', '2019-05-18', '2019-05-23',
'2019-05-28', '2019-06-02', '2019-06-07', '2019-06-12', '2019-06-17', '2019-06-22',
'2019-06-27'];
var addTime = function(x) {
return x.set('Date', ee.Date(x.get('system:time_start')).format("YYYY-MM-dd"))};
var final_Rad = ee.ImageCollection(daily_Rad_total)
.filter(ee.Filter.date(START, END))
.map(addTime)
.filter(ee.Filter.inList('Date',ee.List(DATES)));
print("final_Rad",final_Rad);
var ndvi = function(img){
var bands = img.select(['B2','B3','B4','B8']).multiply(0.0001)
.clip(geometry);
var index = bands.normalizedDifference(['B8','B4']);
return index
.copyProperties(img,['system:time_start','system:time_end','system:index']);
};
var S2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(geometry)
.filterDate('2018-10-24','2019-06-30')
.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',20))
.map(ndvi);
print("S2", S2);
var NDVI_and_Rad = S2.merge(final_Rad);
print('Both image collection', NDVI_and_Rad);

Related

How to use for loop one under the last row of the other using google app script?

I need to take data from a basic excel form and paste it on a data table as many times as one of the cells form the form says.
This is the form:
Form
I've tried this:
function COPIARPEGAR() {
var Libro = SpreadsheetApp.getActiveSpreadsheet();
var Form = Libro.getSheetByName("Form")
var CON = Form.getRange('J18').getValue();
var Disciplina = Form.getRange('J20').getValue();
var Masculino = Form.getRange('L22').getValue();
var TituloMasculino = Form.getRange('L20').getValue();
var Femenino = Form.getRange('N22').getValue();
var TituloFemenino = Form.getRange('N20').getValue();
var BBDD = Libro.getSheetByName("BBDD2");
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length
for(var filamasc=UltimaFila+1;filamasc<=Masculino+1;filamasc++) {
BBDD.getRange(filamasc,1).setValue(Disciplina)
BBDD.getRange(filamasc,2).setValue(CON)
BBDD.getRange(filamasc,3).setValue(TituloMasculino)
for(var filafem=UltimaFila+1;filafem<=Femenino+1;filafem++) {
BBDD.getRange(filafem,1).setValue(Disciplina)
BBDD.getRange(filafem,2).setValue(CON)
BBDD.getRange(filafem,3).setValue(TituloFemenino)
}
Logger.log(UltimaFila);
Logger.log(CON);
Logger.log(Disciplina)
}
And as result I always get the smaller number overwrited by the largest number like this:
result
Thanks for yur help!
Your loops are the issue in that you aren't starting at the same rows. Consider running your code in debug mode so you can see your variables value on the right hand part of the screen (such as UltimaFila = 1). I looked at your code, and I think this would work with modifications, but again look at your variables on the right side of your code, and run in debug mode.
function COPIARPEGAR() {
var Libro = SpreadsheetApp.getActiveSpreadsheet();
var Form = Libro.getSheetByName("Form")
var CON = Form.getRange('J18').getValue();
var Disciplina = Form.getRange('J20').getValue();
var Masculino = Form.getRange('L22').getValue();
var TituloMasculino = Form.getRange('L20').getValue();
var Femenino = Form.getRange('N22').getValue();
var TituloFemenino = Form.getRange('N20').getValue();
var BBDD = Libro.getSheetByName("BBDD2");
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length;
//Updated the ending point
for (var filamasc = UltimaFila + 1; filamasc <= Masculino + 1 + UltimaFila; filamasc++) {
BBDD.getRange(filamasc, 1).setValue(Disciplina)
BBDD.getRange(filamasc, 2).setValue(CON)
BBDD.getRange(filamasc, 3).setValue(TituloMasculino)
}
//See the starting points change
var DisciplinaBBDD = BBDD.getRange('A1:A').getValues()
var UltimaFila = DisciplinaBBDD.filter(String).length
//Updated the ending point
for (var filafem = UltimaFila + 1; filafem <= Femenino + 1 + UltimaFila; filafem++) {
BBDD.getRange(filafem, 1).setValue(Disciplina)
BBDD.getRange(filafem, 2).setValue(CON)
BBDD.getRange(filafem, 3).setValue(TituloFemenino)
}
Logger.log(UltimaFila);
Logger.log(CON);
Logger.log(Disciplina)
}
How To Debug Your Code

set values after sending mail

I want the script to send an email to those mail addresses where unchecked boxes are in the row - This works fine. But I want the value of the checkbox to be set “True” after the mails were sent.
My Problem is that I need the last for-loop to stop after all checkboxes are checked. In other words: The last loop has to stop when an empty cell appears.
First of all I manually trigger the script - later I will start it with the help of a button in the menu (function onOpen...)
Appreciate any help – thanks a lot!
Check out the sheet and the code below:
function sendmail() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Sheet1');
var r = s.getRange('C:C'); //Checkboxes
var v = r.getValues();
for(var i=v.length-1;i>=0;i--)
if(v[0,i]=='false') {
var range = ss.getRange("A1:D4");
var UserData = range.getValues();
var UserData = range.getValues();
var row = UserData[i];
var name = row[0];
var email = row[1];
MailApp.sendEmail(row[1], "Test", "Hello " + name + ", This is an email");
var response = ui.alert("mail was send to ", ui.ButtonSet.OK);
}
for (k=1; k < 20; k++) { //loop which has to stop
s.getRange(k, 3).setValue("True");
}
}
A couple of major changes in your script.
The condition for the loop is wrong. Change to:
for(var i=v.length-1;i>0;i--)
The UI response is missing the recipient name. Change to:
var response = ui.alert("mail was send to "+name, ui.ButtonSet.OK);
var UserData = range.getValues(); is declared twice: delete one row
Immediately after the UI alert (and still within the IF loop), add a line to update the checkbox: UserData[i][2] = true;
Simplify the updating of checkboxes.
Delete the existing lines:
for (k=1; k < 20; k++) {
s.getRange(k, 3).setValue("True");
}
Substitute:
range.setValues(UserData)
Revised Script
function sosendmail() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Sheet1');
var r = s.getRange('C:C'); //Checkboxes
var v = r.getValues();
for(var i=v.length-1;i>0;i--)
if(v[0,i]=='false') {
var range = ss.getRange("A1:D4");
var UserData = range.getValues();
var row = UserData[i];
var name = row[0];
var email = row[1];
// MailApp.sendEmail(row[1], "Test", "Hello " + name + ", This is an email");
Logger.log("mail sent")
var response = ui.alert("mail was send to "+name, ui.ButtonSet.OK);
UserData[i][2] = true;
}
range.setValues(UserData)
}
Alternative Script
The following script is offered as an alternative. It avoids multiple getRange()/getValue statements and uses a more conventional top-down loop.
function sosendmail01() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Sheet1');
// get the number of rows (Alast)
var Avals = ss.getRange("A2:A").getValues();
var AlastRow = Avals.filter(String).length;
// Logger.log("DEBUG: number of rows = "+AlastRow)
// get the data range
var r = s.getRange(2, 1, AlastRow, 3);// get all the data
// Logger.log("DEBUG: the data range = "+r.getA1Notation())
var v = r.getValues(); // get the data
// loop through the rows of data
for (var i = 0;i<AlastRow;i++){
if (v[i][2] != false) {
// the checkbox is ticked Don't sent an email
// Logger.log("DEBUG: i:"+i+", name = "+v[i][0]+" - the checkbox is ticked");
} else{
// the checkbox IS NOT ticked - send an email
//Logger.log("DEBUG: i:"+i+", name = "+v[i][0]+" checkbox = "+v[i][2]+" - the checkbox is NOT ticked");
var name = v[i][0];
var email = v[i][1];
//MailApp.sendEmail(email, "Test", "Hello " + name + ", This is an email");
Logger.log("DEBUG: mail sent to "+name+" at "+email)
var response = ui.alert("mail was send to "+name, ui.ButtonSet.OK);
v[i][2] = true;
}
}
r.setValues(v);
}

Struggle to pull email with reminder message on date count down

I have tried over and over to get this 'simple' script to work. I would like to scan over a column of dates and if a pre set 'days due' is today, it will then pull the email from the same row with a reminder message stating the task is due. For whatever reason, when I do this I cannot get multiple emails to fire to different owners and my loop keeps stacking the tasks due on the same day. I can SHARE SHEET HERE. any help is appreciated!!
function checkReminder() {
// get the spreadsheet object
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// set the first sheet as active
SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
// fetch this sheet
var sheet = spreadsheet.getActiveSheet();
// figure out what the last row is
var lastRow = sheet.getLastRow();
// the rows are indexed starting at 1, and the first row
// is the headers, so start with row 2
var startRow = 2;
// grab column 5 (the 'days left' column)
var range = sheet.getRange(2,5,lastRow-startRow+1,1 );
var numRows = range.getNumRows();
var days_left_values = range.getValues();
// Now, grab the reminder name column
range = sheet.getRange(2, 1, lastRow-startRow+1, 1);
var reminder_info_values = range.getValues();
//Range A2:End of rows and columns
data = sheet.getRange(2, 6, lastRow-startRow+1,1);
//Now, grab the emails
var email_values = data.getValues();
//Logger.log(email_values)
//Logger.log(reminder_info_values)
//=======================Above this line works
fine====================================
for (k in email_values){
var row = email_values[k];}
//var emailAddress =row[5]
var warning_count = 0;
var msg = "";
// Loop over the days left values
for (var i = 0; i <= numRows - 1; i++) {
var days_left = days_left_values[i][0];
if(days_left == 7) {
// if it's exactly 7, do something with the data.
var reminder_name = reminder_info_values[i][0];
var emailAddress = row[6]
msg = msg + "Reminder: "+reminder_name+" is due in "+days_left+"
days.\n";
}
}
warning_count++;
if(warning_count) {
//MailApp.sendEmail(emailAddress,
//"Reminder Spreadsheet Message", msg);
Logger.log(emailAddress);
Logger.log(msg);
}
}

From Google Forms to Google Calendar - Date and TIme issues

I am trying to modify a script I found online that seems to make the event an all day event, which I don't want, I want it to be just the time specified in the form/spreadsheet.
The spreadsheet is located here - https://docs.google.com/spreadsheet/ccc?key=0ApxazoOhNSK-dGFvZVhVOTQ1X3F3aWh4QTh3Wm9sbFE#gid=0
Here is the script I am using, but its not adding...
//this is the ID of the calendar to add the event to, this is found on the calendar settings page of the calendar in question
var calendarId = "<removed for privacy>";
//below are the column ids of that represents the values used in the spreadsheet (these are non zero indexed)
var startDtId = 4;
var endDtId = 4;
var titleId = 2;
var titleId2 = 3;
var descId = 7;
var tstart = 4;
var tstop = 5;
var formTimeStampId = 1;
function getLatestAndSubmitToCalendar() {
var start = new Date(sheet.getRange(lr,tstart,1,1).getValue());
var end = new Date(sheet.getRange(lr,tstop,1,1).getValue());
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var lr = rows.getLastRow();
var subOn = "Submitted on :"+sheet.getRange(lr,formTimeStampId,1,1).getValue()+" by "+sheet.getRange(lr,titleId,1,1).getValue();
var desc = "Comments: "+sheet.getRange(lr,descId,1,1).getValue()+"\n"+subOn;
var title = sheet.getRange(lr,titleId,1,1).getValue()+" "+sheet.getRange(lr,titleId2,1,1).getValue();
createEvent(calendarId,title,start,end,desc);
}
function createEvent(calendarId,title,start,end,desc) {
var cal = CalendarApp.getCalendarById(calendarId);
var start = new Date(sheet.getRange(lr,tstart,1,1).getValue());
var end = new Date(sheet.getRange(lr,tstop,1,1).getValue());
var loc = 'Computer Center';
var event = cal.createEvent(title, start, end, {
description : desc,
location : loc
});
};
The original article is located here: http://bruceburge.com/2012/09/05/automatically-adding-events-to-a-google-calendar-from-a-google-form-submission/
I just can't seem to get the dates to work at all... If I use the original code it works fine, but the time is the full day, not the specified time... I seem to have broken it in an attempt to make it work... Any help would be appreciated...
It was a lot simpler than I though... I just removed some of his lines (the ones that set the hour and minutes to 0. Once I removed that and changed a few things, I get the following which works just great:
//this is the ID of the calendar to add the event to, this is found on the calendar settings page of the calendar in question
var calendarId = "alcc.ccenter#gmail.com";
//below are the column ids of that represents the values used in the spreadsheet (these are non zero indexed)
var startDtId = 4;
var endDtId = 5;
var titleId = 2;
var titleId2 = 3;
var descId = 7;
var formTimeStampId = 1;
function getLatestAndSubmitToCalendar() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var lr = rows.getLastRow();
var startDt = sheet.getRange(lr,startDtId,1,1).getValue();
//set to first hour and minute of the day.
var endDt = sheet.getRange(lr,endDtId,1,1).getValue();
//set endDt to last hour and minute of the day
var subOn = "Added :"+sheet.getRange(lr,formTimeStampId,1,1).getValue()+" by: "+sheet.getRange(lr,titleId,1,1).getValue();
var desc = "Comments :"+sheet.getRange(lr,descId,1,1).getValue()+"\n"+subOn;
var title = sheet.getRange(lr,titleId,1,1).getValue()+" - "+sheet.getRange(lr,titleId2,1,1).getValue();
createEvent(calendarId,title,startDt,endDt,desc);
}​
function createEvent(calendarId,title,startDt,endDt,desc) {
var cal = CalendarApp.getCalendarById(calendarId);
var start = new Date(startDt);
var end = new Date(endDt);
var loc = 'Computer Centre';
var event = cal.createEvent(title, start, end, {
description : desc,
location : loc
});
};
My form has the following Columns - Timestamp, Name, Absence, Start, End, Reason, Comments. They didn't need to be ne word but I changed them to one word headings because of the video example I was trying to follow... But the above code works miracles.
I had to modify the way Forms handles dates to accommodate Calendar
function createEvent() {
var form = FormApp.getActiveForm();
var cal = CalendarApp.getDefaultCalendar();
var responses = form.getResponses();
var len = responses.length;
var last = len – 1;
var items = responses[last].getItemResponses();
var email = responses[last].getRespondentEmail();
var name = items[0].getResponse();
var bring = items[1].getResponse();
var date = items[2].getResponse();
Logger.log(date);
var replace = date.replace(/-/g,”/”);
Logger.log(replace);
var start = new Date(replace);
Logger.log(‘start ‘+start);
//Logger.log(newStart.getHours());
var endHours = 2+0+start.getHours();
//Logger.log(start.getDay());
var day = start.getDate();
var minutes = start.getMinutes();
var year = start.getFullYear();
var month = start.getMonth();
var hours = start.getHours();
var d = new Date(year, month, day, endHours, minutes);
Logger.log(d);
var event = cal.createEvent(‘Class Party ‘+name+’ brings ‘+bring, start, d)
.addGuest(email)
.setDescription(name+’ you will be bringing ‘+bring+’ to the party.’);
GmailApp.sendEmail(email, name + ’ a Google Calendar invite has been created for you’, name + ’ You filled out the Google Form for the date of ‘ + start + ’. Check your Google Calendar to confirm that you received the invite.\n’);
}

Check date range vs. some other date ranges for missing days

Here is what I want to do:
I got a date range from e.g. 03.04.2013 to 23.04.2013 - that's my main range.
Now I have the possibility to create some own time ranges (e.g. 04.04.2013 to 09.04.2013 and 11.04.2013 to 23.04.2013). Those have to cover the whole main range, so every day of the main range (excluding weekens) needs an corresponding day in my own time ranges.
My plan would be to create an Array for the main range. Then I check each day of my own time ranges against the main range. If there is an accordance, I would remove the day from the main range.
So in the end, if everything is ok, there would be an emtpy array, because all days are covered by my own time ranges. If not, then the days not covered would still be in the main range and I could work with them (in this example: 03.04.2013, 10.04.2013)
Does anybody have an better idea to solve this problem? NotesDateTimeRanges?
I would add the dates into a sorted collection and then a "pirate algorithm". Look left, look right and if any of the looks fails you can stop (unless you want to find all missing dates).
Off my head (you might need to massage the final list to store the value back):
var AbsenctSince:NotesDateTime; //Start Date - stored in the NotesItem
var endDate:NotesDateTime; // Return, could be in Notes or Today
var wfDoc:NotesDocument = docApplication.getDocument();
var responseCDs:NotesDocumentCollection = wfDoc.getResponses();
var docResponse:NotesDocument;
var nextResponse:NotesDocument;
//Get the date, which limits the function - if there is a return information, then this is the limit, else today
AbsenctSince = wfDoc.getDateTimeValue("AbsentSince") ;
if (wfDoc.hasItem("ReturnInformationDat")) {
endDate = wfDoc.getDateTimeValue("ReturnInformationDat");
} else {
endDate = session.createDateTime("Today");
}
//Get all days between two dates - as pure Java!
var dateList:java.util.List = getWorkDayList(AbsenctSince.toJavaDate(), endDate.toJavaDate());
// Looping once through the reponse documents
var docResponse = responseCDs.getFirstDocument();
while (docResponse != null) {
nextResponse = responseCDs.getNextDocument(docResponse);
var CDValidSince:NotesDateTime = docResponse.getDateTimeValue("CDValidSince");
var CDValidTill:NotesDateTime = docResponse.getDateTimeValue("CDValidTill");
// Now we need get all days in this range
var removeDates:java.util.List = getWorkDayList(CDValidSince.toJavaDate(),CDValidTill.toJavaDate());
dateList.removeAll(removeDates);
docResponse.recycle();
docResponse = nextResponse;
}
// Both docs are null - nothing to recycle left
// Now we only have uncovered dates left in dateList
docApplication.replaceItemValue("openDates", dateList);
// Cleanup
try {
AbsenctSince.recycle();
endDate.recyle();
wfDoc.recycle();
responseCDs.recycle();
} catch (e) {
dBar.error(e);
}
function getWorkDayList(startDate, endDate) {
var dates:java.util.List = new java.util.ArrayList();
var calendar:java.util.Calendar = new java.util.GregorianCalendar();
calendar.setTime(startDate);
while (calendar.getTime().before(endDate)) {
var workDay = calendar.get(calendar.DAY_OF_WEEK);
if (workDay != calendar.SATURDAY && workDay != calendar.SUNDAY) {
var result = calendar.getTime();
dates.add(result);
}
calendar.add(java.util.Calendar.DATE, 1);
}
return dates;
}
I've done it this way now (seems to work so far):
var dateArray = new Array();
var responseCDs:NotesDocumentCollection = docApplication.getDocument().getResponses();
var dt:NotesDateTime = session.createDateTime("Today");
var wfDoc = docApplication.getDocument();
dt.setNow();
//Get the date, which limits the function - if there is a return information, then this is the limit, else today
var AbsenctSince:NotesDateTime = session.createDateTime(wfDoc.getItemValue("AbsentSince").toString().substr(0,19));
if (wfDoc.hasItem("ReturnInformationDat")) {
var endDate:NotesDateTime = session.createDateTime(wfDoc.getItemValue("ReturnInformationDat").toString().substr(0,19));
} else {
var endDate:NotesDateTime = session.createDateTime("Today");
}
//Get all days between two dates
dateArray = getDates(AbsenctSince, endDate);
for (var i=dateArray.length-1; i >= 0 ; i--) {
var checkDate:NotesDateTime = session.createDateTime(dateArray[i].toString().substr(0,19));
var day = checkDate.toJavaDate().getDay();
//Remove weekends first
if ((day == 6) || (day == 0)) { //6 = Saturday, 0 = Sunday
dBar.info("splice: " + dateArray[i]);
dateArray = dateArray.splice(i,1);
} else {
var docResponse = responseCDs.getFirstDocument();
//Work through all response docs to check if any date is covered
while (docResponse != null) {
var CDValidSince:NotesDateTime = session.createDateTime(docResponse.getItemValue("CDValidSince").toString().substr(0,19));
var CDValidTill:NotesDateTime = session.createDateTime(docResponse.getItemValue("CDValidTill").toString().substr(0,19));
//checkDate covered? If yes, it will be removed
if (checkDate.timeDifference(CDValidSince)/86400 >= 0 && checkDate.timeDifference(CDValidTill)/86400 <= 0 ) {
dBar.info("splice: " + dateArray[i]);
dateArray = dateArray.splice(i,1);
}
docResponse = responseCDs.getNextDocument();
}
}
}
docApplication.replaceItemValue("openDates", dateArray);
And I'm using this function (adopted from this question here):
function getDates(startDate:NotesDateTime, endDate:NotesDateTime) {
var dateArray = new Array();
var currentDate:NotesDateTime = startDate;
while (endDate.timeDifference(currentDate) > 0) {
dateArray.push( currentDate.getDateOnly() );
currentDate.adjustDay(1);
}
return dateArray;
}