Infopath codeless programming (walkthrough) 2
Other parts: 1, 3.
Bookmark that post
Updated: 3 more forms added at the bottom: “work days calculation (excluding weekends and holidays)”, “day of the week calculation” and “Days since form was created”.
Special thanks: Karl D. Swartzendruber
So what about so called “codeless programming” in InfoPath? As we all probably know, InfoPath can performed only 16 calulations without user interaction. But what if your business rules require you to iterate through 17 repeating elements? You will get a message box from InfoPath with phrase “The rules or code may be causing an infinite loop”. Yes, in InfoPath 16 is a very big number and 17 is considered infinite. To you and I this might seem stupid and arbitrarily restrictive, but Microsoft’s wisdom is greater than ours. Perhaps they know that 17th iteration would give us developers too much power. It would break the fine balance of Microsoft applications, make other development tools obsolete, and become unbearable for non InfoPath developers. But let’s drop the light irony and just accept that InfoPath already has more codeless programming power than mere mortals should ever need.
Today’s challenge is to find the difference in days between 2 datepicker controls disregarding the absence of datediff() function in InfoPath. We are going to show that the 16 iterations limit just can’t stop the true codeless programmer.
Disclaimer: During developing cycle author has been having in mind “finite automates” principles as well as primitive binary search.
Anyway, lets get to the business. Date Difference Calculation. Form to download.
Our recipy is the following: We will need 3 fields. 2 of them are date type fields with datepicker controls (startDate, endDate) and one (dayDifference) is a text type field represented by a simple textbox. All rules have exactly 1 action.
startDate rule:
condition expession: ../my:endDate != ""
field: dayDifference
string value: 0;4096
endDate rule:
condition expession: ../my:startDate != ""
field: dayDifference
string value: 0;4096
dayDifference rules:
MainRule:
condition expession:
xdDate:AddDays(../my:startDate, substring-before(., ";")) != ../my:endDate and contains(., ";")
field: dayDifference
xPath expression: concat(substring-before(., ";") + substring-after(., ";") * ((translate(xdDate:AddDays(../my:startDate, substring-before(., ";")), "-", "") < translate(../my:endDate, "-", "")) * 2 – 1), ";", substring-after(., ";") div 2)
finalize rule:
condition expession: contains(., ";")
field: dayDifference
xPath expression: substring-before(., ";")

Your form is ready!
What else can be done by applying same principles:
Here is form that shows amount of days since it was created
Form that shows current day of the week and day of the week from Date Picker control.
The tricky one: Work days calculation (business days)
That’s it. Happy codeless programming!
Posted under tags: Infopath, Date Picker Control
January 7, 2009 at 4:02 pm
Hello,
i like your steps and it is exact what i need. However when an user is filling out my form in our intranet the dayDifference field shows: NaN;NaN
I ma using infopath 2007.
Do you have an idea what i am doing wrong?
M.
January 7, 2009 at 7:16 pm
When you do copy/paste XPath expressions (not values like 0;4096) into action vindow, make sure you’ve pressed fx button and then checked “Edt XPath(advanced)” checkbox.
January 14, 2009 at 2:55 pm
Hi very thanks for this cool sharing. I follow the step but was encountered with the error: Some rules were not applied
AFter i click on the OK button.
day diff = 0.5;0.25
for Start Date=14-Jan-09, End Date=15-Jan-09
I though this should return me 1 day in different? Any thing wrong?
January 14, 2009 at 6:33 pm
There is link in my post where you can download working form.
Looking at result it seems like your condition on MainRule is not working.
January 15, 2009 at 8:45 pm
Hi,
Is there anyway we can calulate months between two dates?
Please help if you know.
Thanks
IA
January 15, 2009 at 10:05 pm
>Please help if you know.
Knowing is overrated. But I can help you even if I don’t initially know.
It’s somthing like (substring(date1,1,4) -substring(date2,1,4))*12 +substring(date1,6,2)-substring(date2,6,2)
January 16, 2009 at 2:40 am
Alecpojidaev thanks a lot!
January 16, 2009 at 3:52 pm
Thanks for your reply alecpojidaev.
Can you point me where should I have to put this code. I tried in rules, condition. I might doing somethign wrong if you can point me will be realy helpfull.
Thanks again
Imran
January 16, 2009 at 4:11 pm
To: Imran
Actions inside rules are the right places.
You will need to replace date1 and date2 with the actual field names on your form as well.
January 16, 2009 at 8:14 pm
Hi alecpojidaev,
I tried in it but no luck. If its possible can you send me the file if you test on your end.
Thanks again for you help
Imran
January 16, 2009 at 8:46 pm
To: Imran
http://cid-e5a123fca40349ad.skydrive.live.com/self.aspx/.Public/monthCheck.xsn
January 21, 2009 at 1:39 pm
Hi alecpojidaev,
is it possible to exclude weekends? I only want calculate workdays.
Thanks for help.
plimp
January 21, 2009 at 2:14 pm
To: Plimp
I’m not sure about that. It would be posible if we have know information about days of the weeks of both date picker controls.
January 21, 2009 at 2:26 pm
Hi,
is it possible to get informations from datepickers?
When i have to calculate the date from picker 1 with 01/21/09 and date from picker 2 with 01/28/09 then i have 7 day´s between the picker. In this case it should strip 2 day´s. When i have 14 day´s it should strip 4 day´s.
Did this work with rules?
January 21, 2009 at 2:56 pm
To:Plimp
Ya thats how it should be calculated. But without knowing at least one day of the week at either one date picker you cant be sure how many weekends between 2 dates. the formula (date1-date2)*5/7 gives you the result with precision +/-2 working days.
January 21, 2009 at 2:40 pm
Thanks alecpojidaev.
It works like a charm. Only issue getting is when I entered 01/01/2009 to 31/12/2009 it calculates 11 months but if you see these are 12 months.
Do you have any solution?
Thanks
Imran
January 21, 2009 at 2:45 pm
To:Imran
As for me 11 is correct. But if you want to feel free to add +1 to each formula.
January 21, 2009 at 4:18 pm
Hi,
could it work when the format of the date pickers are “wed 01/21/09″.
If this would work, how?
January 21, 2009 at 5:48 pm
To:Plimp
I believe the internal representation will always be yyyy-mm-dd. The output format is a different story.
January 26, 2009 at 8:45 pm
I am in the same boat as Imran, the weird thing is I can see how yours works, but I can’t get mine to work. Something to do with the set field to in the second rule on the date2 has a set fields value: y = concat(substring(., 1, 4), substring(../my:date2, 1, 4), substring(., 5, 2), substring(../my:date2, 5, 2))
I’m not sure how you are pointing to the field called ../my:y in your rule. how is that accomplished.
January 26, 2009 at 9:34 pm
To:murphy tha dog
You can remove action where ..my:y is involved. It’s not used anymore (Sorry, hanging wires of fast developing).
January 26, 2009 at 10:18 pm
But you do need both rules in both date fields right?
January 26, 2009 at 10:27 pm
In that design yes. But you can reduse amount of actions to just 1 by transferreng action to a button and removing all actions from controls. In that case you will need to press button to perform calculation. The paths to the fields has to be updated respectfully.
January 26, 2009 at 10:31 pm
I like how yours is automatic so I will keep it that way, but my result is NAN in the Nmonths field I can’t seem to reproduce the correct calc.
January 26, 2009 at 10:54 pm
i did however get it to work in a new clean xsn file. so i will try again tomorrow. thanks
February 3, 2009 at 3:54 pm
Can you post the latest XSN file to review how you accomplished removing the weekends. I have a form very similar to this and have yet to get this to work. Thanks
February 3, 2009 at 6:22 pm
I hadn’t accopmplished it. You can’t do it without knowing the day of the week on at least one datepicker. I don’t know how to get that info without using external data sources (i.e. sharepoint).
Update: Now I know how to do that. Still need to fight my laziness to finish the thing.
February 3, 2009 at 6:30 pm
Is there a way to make is so that when you click on Monday and then on Friday and the difference will show 5 days. Right now I get 4 days.
February 3, 2009 at 7:46 pm
modify finalize rule as following:
substring-after(., “;”)+1
February 26, 2009 at 4:35 pm
These are pretty good. :) Hope there are more coming.
March 11, 2009 at 1:33 pm
very very good arcticle, exactly matching for my application. But this is not supported with Infopath 2003. Is it possible to open in Infopath form 2003.
March 11, 2009 at 2:49 pm
Sorry, IP 2007 only.
April 9, 2009 at 9:47 pm
Is there an updated place to download the xsn files? They show that they are unavailable. thanks
April 10, 2009 at 1:44 pm
Sorry, looks like Microsoft constantly changing links to the files in SkyDrive. I replaced direct file downloads with links to the folders.
April 15, 2009 at 4:38 am
Hello. For some reason day difference returns 0;4096, any idea?
April 15, 2009 at 5:09 am
To: Hector Cuevas
Nope. No idea. I even don’t know have you created the form from scratch or you talking about form available for download.
May 6, 2009 at 3:23 pm
can you please publish the code for the daysOfTheWeek xml file used in the demonstration for showing day of the week in the data connection in the demo form?
I have an immediate need for this application. Thanks!
Jared
May 6, 2009 at 4:48 pm
Sorry… I finally see where you used the xml data source file… still need the code for the xml file, if you can, please.
Thank you!
Jared
May 6, 2009 at 5:44 pm
Whats the problem to extract secondary data source XML file from the template? Are you getting any errors when you doing
Manage Data connections -> Modify daysOfTheWeek -> Resource Files -> Export?
Or just save as Source Files.
May 7, 2009 at 2:41 pm
Ah… thanks for the tip… I’ve never noticed the export feature before.
Thanks!
May 11, 2009 at 1:55 am
I’ve just downloaded the form you’ve created to calculate the day of the week and have been trying to put the formula’s from the downloaded form into my other one, i think i’ve got all the little bits and pieces required for it to work yet when i preview the page it only comes up with 0;4096. Is there anything commonly left out, or have you created a step by step in setting this up?
Thanks heaps for all your codeless solutions, they really help with taming Infopath 2007
May 11, 2009 at 2:26 am
Issue fixed, on my conditions i had is equal to “;” instead of contains.
Thanks Again.
May 19, 2009 at 12:01 pm
Dear Alec,
Thank you for this nice tool…
Im new to the world of InfoPath and I have tried following your “step by step” above. However, I run into a small problem. No matter which dates i select in my date picker, the resault always end at 0;4096
What am I doing wrong?
Your help will be appriciated :-)
May 19, 2009 at 1:06 pm
Try to find difference between what you trying to do and the form available for download.
May 19, 2009 at 1:17 pm
I did that… I copy/pasted every thing…
May 19, 2009 at 1:26 pm
Well… if you copy/pasted everything then we are witnesses of a miracle.
May 19, 2009 at 5:18 pm
If I add a simple calculation field to your form, dayDifference * 3.33, I get an error message that reads ” A calculation in the form has not been completed. The number of calculations used for a single action exceeded the maximum limit.”
Any ideas
May 19, 2009 at 5:42 pm
Thats how it suppoused to be. dayDifference is already almost at the limit of allowed amount of calculations. Adding one more field with calculation involved dayDifference stops things working right away. Same error because of the same reason you will see if you’ll try to mesure amount of days between dates with day difference more then 23 years on unchenged form.
May 19, 2009 at 5:59 pm
Thanks for the response. Is there any way to include the diffDays field in a caluculation? Or, is the diffDays calc the only one I can have on the form?
Thanks again for your help.
Rob
May 19, 2009 at 6:28 pm
If you need to do some after calculations use “finalize” rule action.
You can have as many calculating controls as you want on the form. The only limitations is the amount of automatic calculations after user action (16).
May 19, 2009 at 8:56 pm
Thanks for the info. It works like a champ.
Rob
June 1, 2009 at 12:22 pm
Great post this has been really useful. I’ve used your technique to work out the working days in a holiday request form but I have an issue if the begin date is a Sunday. The calculation comes back with decimal number eg 6.7142857. I’ve downloaded your example form and it does the same in there, everything else is fine. Any ideas what’s causing this.
June 1, 2009 at 1:36 pm
Fixed and uploaded new form.
June 8, 2009 at 12:30 pm
Thanks for uploading your form, there are helpful. I’ve got a problem when i try to do the workdayscalculation form. When i have to make the last rule for the workday, i can’t do
“compte(hday[traduire(BeginDate; "-"; "") = traduire(@hdayn; "-"; "")]) “,
and error occured there is the error :
“xdXDocument:GetDOM(“daysOfTheWeek”)/somestuff/holydays/my:BeginDate » ne pointe pas vers le chemin d’accès valide d’un champ ou d’un groupe.”
It’s in french but it’s saying that doesn’t point to a validated path of a field or a group, i don’t know what i do wrong, everything else seems ok, thanks in advance
Ced
June 8, 2009 at 1:09 pm
Have you included XML file with French holydays in your form? You can extract copy of it using instructions in my previous responses.
June 8, 2009 at 1:51 pm
I included the same XML file you used to my form, i extract it to you form …. something strange, if in your form i change compte(hday[traduire(BeginDate; “-”; “”) to compte(hday[traduire(@name; “-”; “”)
it’s working to, but in my form it still calculte the number of days but it doesn’t take care about workday or not
thanks in advance
Ced
June 8, 2009 at 2:03 pm
Well… at that point it’s getting kind of hard to say what is wrong. Looks like all your troubles are related to secondary data source. So I would sugest maybe better solution in your situation would be using InfopPath UI for manualy picking up fields from secondary datasource.
June 8, 2009 at 2:10 pm
I’m doing this aswell, i always use InfoPath UI for avoiding synthax error, thanks anyways i’ll try to find out where is the problem.
June 8, 2009 at 2:14 pm
Also, why i can’t remake your form ? it’s the same error as me when i try to do the
“compte(hday[traduire(BeginDate; "-"; "") = traduire(@hdayn; "-"; "")]) “,
i pick field from infopath ui etc … but it’s still getting me the same error, i think it’s because in Holidays/hday/ there is no BeginDate, so it can’t work, i really don’t know how you do this.
June 8, 2009 at 2:50 pm
At that point you have to use absolute path not relative. Thats why it’s always better to copy when ” edit avanced” check box is checked.
In my advanced view BeginDate looks like:
xdXDocument:get-DOM()/my:myFields/my:BeginDate
and because of error yours path structure is different probably.
June 8, 2009 at 3:11 pm
Thanks a lot, i can compile my form now, but there is another problem. Now the weekend are determinate by the startdate,
example : if start date is a monday -> weekend = sunday and monday
example2 : if startdate is a sunday -> weekend = saturday and sunday
Any thought about this please ?
Ced
June 8, 2009 at 3:26 pm
Sorry I can’t understand what your problem is.
June 8, 2009 at 3:53 pm
well i have 2 datepicker, one for the begindate and one for the enddate, in workdaycalculation you don’t count weekends (saturday and sunday) into date calculation.
My problem is the weekends aren’t saturday and sunday, the 2 days which are considered as weekend are determinated by the datepicker of begindate. this means if i choose today ( 8 june ) as begindate, the calcul will be like this :
enddate 9 june -> workday = 2
enddate 10 june -> workday = 3
enddate 11 june -> workday = 4
enddate 12 june -> workday = 5
enddate 13 june -> workday = 6 saturday it should be 5 here
enddate 14 june -> workday = 6 sunday it should be 5 here
enddate 15 june – > workday = 6
i wish you understand my problem,
thanks in advance
Ced
June 8, 2009 at 4:05 pm
I can’t reproduce that. My form shows
enddate 13 june -> workday = 5 as it should be.
June 8, 2009 at 4:48 pm
I really don’t know why my form does this error, i’ve exactly the same codeless programming of your form but it’s doing the thing i described in my previous post, anyways if you have any ideas of what can be wrong for doing this error, thanks to share me.
Ced
June 9, 2009 at 3:23 pm
Ok i resolve this problem, now the form calculate workdays like your. But now i’ve a new problem … my form doesn’t count the holidays.
Basically, if in your form i extract the xml file and i rename this. when i create a new connection to the new xml file and change BegDateWN condition to rule 1 xdXDocument:GetDOM(“daysOfTheWeek”) to xdXDocument:GetDOM(“newnameofXML”), and i change the path of the basepoint of this rule to the new path basepoint. Then i also change in rule 2 of workdays the path to hday and @hdayn to the new path.
The result is it don’t count the holidays of the XML file, what I am doing wrong ?
thanks in advance
June 9, 2009 at 4:19 pm
Try to troubleshoot it by extacting the holyday part of the formula into an expressionbox and see what result you are getting
June 10, 2009 at 5:46 am
hello
i ve jus copy pasted this from ur form.
when i add a rule for the workday textbox i get the error as
Node-test expected.
(substring-before(/my:myFields/my:txtHiddendayscount, “;”) + /my:myFields/my:FromDateValue) mod 7 – ((substring-before(/my:myFields/my:txtHiddendayscount, “;”) + /my:myFields/my:FromDateValue) mod 7 = 6) + 1 – /my:myFields/–>my:FromDateValue- <–(/my:myFields/my:FromDateValue= 0) + (substring-before(/my:myFields/my:txtHiddendayscount, ";") – ((substring-before(/my:myFields/my:txtHiddendayscount, ";") + /my:myFields/my:FromDateValue) mod 7 – /my:myFields/my:FromDateValue)) * 5 div 7 – count(/somestuff/holydays/hday[translate(/my:myFields/my:datLeaveFrom, "-", "") = translate(/somestuff/holydays/hday/@hdayn, "-", "")])
June 10, 2009 at 11:04 am
I found my error, it’s when i’ve to do
compte(hday[traduire(BeginDate; "-"; "") = traduire(@hdayn; "-"; "")])
for doing this i enter
compte(xdXDocument:getDOM(“daysOfTheWeek”)/somestuff/holydays/hday[traduire(/my:myFields/BeginDate; "-"; "") = traduire(xdXDocument:getDOM("daysOfTheWeek")/somestuff/holydays/hday/@hdayn; "-"; "")])
there is no error for the form but when i enter this it doesn’t count the holidays, what is your method for enter this please ?
June 10, 2009 at 11:58 am
Just in the case you don’t understand my problem, delete compte(hday[traduire(BeginDate; "-"; "") = traduire(@hdayn; "-"; "")])
and explain how do you do for rewrite this,
thanks
Ced
June 10, 2009 at 7:05 pm
To: Ced and Prasanna
For some reason the formula in my form in that fragment looks a bit different:
count(hday[translate(BeginDate, "-", "") <= translate(@hdayn, "-", "") and translate(EndDate, "-", "") >= translate(@hdayn, "-", "")])
Same with XPath:
count(xdXDocument:GetDOM(“daysOfTheWeek”)/somestuff/holydays/hday[translate(xdXDocument:get-DOM()/my:myFields/my:BeginDate, "-", "") <= translate(@hdayn, "-", "") and translate(xdXDocument:get-DOM()/my:myFields/my:EndDate, "-", "") >= translate(@hdayn, "-", "")])
June 11, 2009 at 7:03 am
Ok Alec it’s working now, thanks a lot
Ced
June 15, 2009 at 4:41 am
Hello its working.thanks a lot and i ve one more doubt.the form is all about excluding the weekends.but dont want to exclude first and last saturday of the month.can u help me out with this.
thanks in advance
June 15, 2009 at 1:11 pm
It’s definatly possible. However I’m not skilled enouth to help you in any reasonable amount of time.
June 15, 2009 at 7:41 pm
Hey–can you adapt this so that it returns the number of specific days in the date range? (i.e., the number on Mondays between the start time and end time?) Or even can you choose Monday as a options and only populate a drop down that shows dates in the specified range that are Mondays?
I tried, but since I’m not familiar enough with xpath functions, I couldn’t figure it out.
Thanks!
June 15, 2009 at 7:55 pm
It’s definatly possible. However I’m not skilled enouth to help you in any reasonable amount of time.
July 15, 2009 at 7:18 pm
I was wondering what changes I need to make to use this in a repeating table?
July 15, 2009 at 8:37 pm
Edit: Check my new DateCheck form with repeating table primer.
In repeating table it shouldnt be too different. Just use
preceding-sibling
.
following-sibling
functions instead of hardcoded field names. You also have to avoid linked calculations (i.e recalculating all fields in repeating table on some event) because you can easily get over the limit of allowed calculations.
July 21, 2009 at 2:48 am
Hey there!
The “What Day is Today/Anyday” code works but I have the fields on a repeating table and when I add a new row, the “day of the week” field is left blank. Is there a way to make the code operational on the added rows?
Thanks!!!
August 7, 2009 at 3:37 pm
Hi – thank you for the code – the concept is great, especially doing it without code. When I followed your instructions and previewed the form it looks/works great. However, when I publish the form to a form library in Sharepoint and launch the form via browser – I get the following error. Any ideas?
“An error occurred in the form’s rules or code. The number of rule actions or the number of calls to the OnAfterChange event for a single update in the data exceeded the maximum limit. The rules or code may be causing an infinite loop. To prevent this, ensure that the rule action or event handler does not update the data which causes the same rule action or event handler to execute. “
August 7, 2009 at 6:37 pm
It would be nice to know what form are you talking about. That post has 4 of them.
August 10, 2009 at 3:35 pm
Hi sorry – the question was in respective to counting the number of days between two date pickers (inclusive of weekends). Specifically the instructions abover about startDate rule, endDate rule, and dayDifference rules. Like i mentioned in my original question – the form works perfectly until I publish the form to a browser-enabled forms library in Sharepoint. When I launch the form from that location, I get the error mentioned above.
August 10, 2009 at 3:01 pm
I’m interested in the “TodayIs” field and funciton alone where it auto sets today as it’s value then it formats itself as the day of the week. I downloaded the “WhatDayIsToday” template and see how with one resource file, and then 2 rules with conditions this deal is done. I’ve created the very same field named “TodayIs”, I uploaded the resource file on my form and added it as a dataconnection, I then using the fx button have copied the formula (while having the edit xpath pressed) to simply recreate via copy paste the same funtion but mine never works.
The Rule 1 if left alone on mine gives me no value, and if I enter into the field “;” I get “nan,nan”. The second rule after copy/paste always is upset about the formula, the very same one working right in my face… AhHH..lol…. What step might I be missing?
I make a field called “TodayIs”, I extract then upload the resource file, add it as datasource, I copy/paste the conditions and rules using the xpath advanced while copy and while paste and no dice.
Thanks for you help on this.
August 10, 2009 at 3:28 pm
It’s hard to tell whats wrong with your form. Probably data types are mismatched. Make sure all field types are the same as in my form.
Also may be you could try to modify the form from the other end? Use my form as starting point then add the logic you need. I’ve tested that form in browser enabled forms it works just perfect.
August 10, 2009 at 5:44 pm
Hello again.. :)
We’ll I’m trouble shooting and narrow it down and left my text field “TodayIs” with just the first rules copied expression “cut/paste” and the if “TodayIs” contains “;”, then in testing I had the aciton set my date field to “1″. This did not work making me see that the expression when copied and pasted does not work for me. I do have the resource file as a secondary data connection to recieve also.
So, regarding the query:
xdDate:AddDays(xdXDocument:GetDOM(“daysOfTheWeek”)/somestuff/basepoint, substring-before(., “;”)) != xdDate:Today()
I’m just choosing for my rule’s condition the option of “The Expression” and pasting in the expression, the creating the simple if the field includes the “;”, and it does not work for me. What can I do with this expression to duplicate it on my form please?
October 23, 2009 at 11:41 am
When i enter start date as Friday and End date as Monday then my field only calculates 2 days of my working day. Dont calculates the sat and sun. how can i perform this.. thnX Advance
October 23, 2009 at 2:17 pm
Thats how working days are calculated. Monday and Friday are 2 working days so they have to be counted.
July 21, 2009 at 1:06 pm
The main example DateCheck.xsn has XPath adopted to the repeating table. You will have to combine both XPaths from 2 forms to get what you need.
August 10, 2009 at 3:52 pm
Edit: Unsupported function problem fixed.
August 10, 2009 at 6:29 pm
Make sure your secondary datasource has the same name (case sensitive).