Sample Rule 2
The Set Up
The Top Level Item (TLI) is:
and the first child item or sub item (SLI) is:
or;
where the "T" stands for truck; "V" stands for van; and the numbers represent odometer readings. There is nothing else in the line only the "T", or "V", and the two numbers.
Required
To extract the numbers and place them in a separate folder so that the mileage can be determined and other calculations performed for tax purposes.
Discussion
AT this point there are several possible solutions from extraction of the numbers and putting them into appropriate folders to doing calculations on them before putting placing a value in a folder. For this exercise all solutions that were presented in the Ecco_pro Yahoo group will be presented along with an explanation. As not all the information, or at least not all of the requirements were carefully read, was presented in the set up the final solution differs from the first solution. Following the flow of thought should give some insight into rule creation and possibilities.
It should be noted that for anyone who followed the discussion that slang hinted at the solution in the very first response, just not the final answer.
Solutions
For the purposes of this sample it will focus on the truck ("T") only, to make the final solution work for the van ("V") it will be simply a matter of substitution.
First Suggestion
This first suggestion is based on gathering the information from the item text using the string functions and extraction as follows:
- ++:!+:iff(Left(ITT,2)="T ",0.+substr(ITT,10,6)-substr(ITT,3,6),0):[Appointments]
where:
- ++: required
- !+ trigger you may alter depending on what you need
- iff() conditional to test and evaluate based on condition
- Left(ITT,2)="T " checks the left most character for T (Truck. Note the space after the T as any word that begins with T would trigger the rule but "T " is never used, unless we type poorly.
- 0.+substr(ITT,10,6)-substr(ITT,3,6) true condition extracts substrings and subtracts. Note the 0. to force the results to be numeric
- 0 the false condition in this case 0 though you could use "" to force a null value
- [Appointments] conditional that forces the calculation only if the value is in the calendar. If you enter the value in another folder it will have no effect.
The only change you need to make for the Van folder is to change the "T " to V ". One assumption is that the value is always input the same, that is, a Character a blank 6 numbers a blank and then 6 numbers. There may be other characters after the initial string for instance:
- T 123456 234567 travel to Texas and back
The "travel to Texas and back" would be ignored as the extraction is for specific sections of the text starting at 1 and ending at 15.
Second Suggestion
The first suggestion was based on the using string extraction, this second is based on pattern matching as follows:
- ++:!+:0.+match(ITT,"^\s*T\s+\d+\s+(\d+)\s*$")-match(ITT,"^\s*T\s+(\d+)\s+\d+\s*$")
where:
- 0.+ forces the expression to be a number
- match() will extract from a string a specific value
- ITT the item text being matched
- "^ the start of the line
- \s* any number of spaces from 0 to ...
- T the letter T must be the first Character in the line
- \s+ any number of spaces from 1 to ...
- \d+ any number of digits from 1 to ...
- \s+ any number of spaces from 1 to ...
- (\d+) the digits to be extracted therefore surrounded by ()
- \s* any number of spaces from 0 to ...
- $" end of the line
The one draw back to this method, the pattern must be precisely known and invariant. That is if the input were:
It would fail as there is no provision in the pattern to accommodate the last word. If the pattern were to accommodate the word then when the input does have the ending text it it fail as well. It should be noted though that the number of spaces or the number of digits does not matter in this case. So:
works just as well as;
As a variation the following contribution was made but could require a change in the data entry
Second Suggestion Variation
There are two regex pattern expressions in the above example as follows:
- "^\s*T\s+\d+\s+(\d+)\s*$"
- "^\s*T\s+(\d+)\s+\d+\s*$"
I think (not tested) the following should allow throwing away anything past the two sets of digits and (optional spaces)
- "^\s*T\s+\d+\s+(\d+)\s*.*$"
- "^\s*T\s+(\d+)\s+\d+\s*.*$"
where ".*" matches anything (possibly nothing) to end-of-line: $
PCRE regex allows the following construct (using named sub-patterns):
- ^\s*(?<VehicleType>T)\s+(?<StartMiles>\d+)\s+(?<EndMiles>\d+)\s*.*$
and that this replacement instruction:
- Vehicle $1 Start $2 End $3
changing "T 123456 234567 test" to "Vehicle T Start 123456 End 234567"
With this replaced text it would then be possible to parse the item text as follows:
- 0.+parse("^\s*(?<VehicleType>T)\s+(?<StartMiles>\d+)\s+(?<EndMiles>\d+)\s*.*$")match(ITT,$3-$2)
or (better):
- 0.+parse("^\s*(?<VehicleType>T)\s+(?<StartMiles>\d+)\s+(?<EndMiles>\d+)\s*.*$")match(ITT,${EndMiles}-${StartMiles})
For reference some of the above information was cribbed a page from RegexBuddy Help from:
<
http://buralex.googlepages.com/ReplacementTextReferenceJGSoftRegexB.htm> which discusses how various implementations support replacement text references.
Other references:
http://www.pcre.org/pcre.txt
http://lrexlib.luaforge.net/
http://wiki.tcl.tk/2255
Third Suggestion
This suggestion builds are the information from the first two suggestions and provides a final solution that matches the requirements. This solution was as follows:
- ++:P!+-:match(TVC(),"^\s*\T\s+(\d+)\s+\d+\s*$"):
in the truck start folder; and
- ++:P!+-:match(TVC(),"^\s*\T\s+\d+\s+(\d+)\s*$"):
in the Truck end folder, where:
- :P!+-: this flag will only work on the parent item inserting text the first time, any time there is a change and deleting the value if the condition is not met
- TVC() //this forces the parent item to look at the first child item for the string
Final Thoughts
This has been an interesting exercise and the contributions from the group were invaluable. Now if we look at the first response by yoursowelcomethanks:
- "key rules is TVC([cond]) Get item text of the child with condition"
we see that the solution was right before us to begin with. In going through the exercise, the contributions were a great learning tool. Any one reading this is encouraged to follow the entire thread
http://tech.groups.yahoo.com/group/ecco_pro/message/1817 for subtleties as this Sample can not begin to capture all of the development.
Contributers
In order of first contribution to the thread:
- Don Johnson
- yoursowelcomethanks
- Albert Schepers
- Dave Gustafson
- r634718
- - Alec_Burgess Sep 1, 2007 7:34 pm
- Slang