Every time I work with it, I love IronPython in Select, it is clearly a replacement for most of what happens in formulas. I wrote an introductory piece a few months back. I then took the concept of Document Formatting Options, like LD and LDR to control how date fields render to built an IronPython module that emulates most of the Document Formatting Options available. I added a couple more like Pad left or right with any character.
If you or someone you know is interested in learning about IronPython this tool would be an excellent starter for setting system default values. It provides an easy way to create automated legal descriptions, mortgage clauses, or any other text based field. It handles formatting of data allowing the developer to easily add information. The entire set is over 500 lines of code and includes examples of automating the values for escrow brief legal and existing liens. At the end of this article, I’ll include the output from the test tool. The test tool is also included in the package as a source of examples.
Why it’s cool
As an example the formula to create our Escrow Brief Legal is in excess of 150 lines. In IronPython using this tool a developer defines 16 lines. Controlling the output in that few lines is both easy and quick. Making it run is simple.
Come along for the ride
So thinking about the legal description we start with Lots or Units. To do that with this tool takes 2 lines of code that intelligently deals with plurals for multiples. That looks like this:
AddObjectNumber(sb, args.Context.Lots, 'Lot ', 'Lots ', ' ' , ', ') AddObjectNumber(sb, args.Context.Units, 'Unit ', 'Units ', ' ' , ', ')
Both Lots and Units have a child item called Number, so we call a tool function named AddObjectNumber.
The parameters are,
sb is a required variable, our final text and previously setup with sb = StringBuilder().
Slight digression here, StringBuilder should be used for most text manipulation in IronPython, include "from System.Text import StringBuilder"
Second we send in the multiple that is to be processed. (args.Context .Lots or .Units)
Third is the text that should appear if there is one item.
Fourth is the multiple item text.
Fifth is the string to appear after all multiples are dealt with.
Last is the separator string. In this case comma space.
Those last 2 are in reverse order, I might have to change that. If there are no Lots or Units nothing is added to sb.
Continuing on with our Legal Description, Block and Building are next which are a little simpler to add
AddTextSingle(sb, args.Context.Block, 'Block ', ' ' ) AddTextSingle(sb, args.Context.Building, 'Building ' , ' ' )
The first 2 parameters are the same, followed by the text to put before, then after the value of Block or Building if one exists.
The next section is interesting, if there is a subdivision, then if there is a Block, we want the Block on a new line. This requires a little more code to determine if there was a subdivision.
preSubdivision = sb.Length #Save current length AddTextSingle(sb, args.Context.Subdivision, '\r\n', ' ')
First we save the length of our text string to compare it after we add Subdivision.
Next using the same AddTextSingle that Block used, we add the subdivision.
if preSubdivision == sb.Length: #Length didn't grow, put Condo on separate line AddTextSingle(sb, args.Context.Condo, '\r\n', ' ') else: AddTextSingle(sb, args.Context.Condo, '', ' ')
Now we compare our lengths, if something was added use the same AddTextSingle function putting a carriage return linefeed before the Condo. Otherwise, just add the Condo.
The demo legal description continues with putting a Section on a new line if it exists, and adding a Phase.
AddTextSingle(sb, args.Context.Section, '\r\nSection ', ' ') AddTextSingle(sb, args.Context.Phase, 'Phase ' , ' ' )
Finally using a function like Block and Units called AddObjectIdentification add Parcel ID's and or Tax Map Id's each on their own new line.
AddObjectIdentification(sb, args.Context.Parcels, '\r\nParcel ID ','\r\nParcel IDs ', ' ' , ', ') AddObjectIdentification(sb, args.Context.TaxMaps, '\r\nTax/Map ID ','\r\nTax/Map IDs ', ' ' , ', ')
Finally set the value of the field
args.Value = sb.ToString()
Easy updates and changes
Moving things around is simple, just move a few lines about in the short function. So to put Building before Block it is a simple edit.
Change this
AddTextSingle(sb, args.Context.Block, 'Block ', ' ' ) AddTextSingle(sb, args.Context.Building, 'Building ' , ' ' )
To this
AddTextSingle(sb, args.Context.Building, 'Building ' , ' ' ) AddTextSingle(sb, args.Context.Block, 'Block ', ' ' )
And Building will appear before Block in the final rendered field.
So that's how to build a brief legal description in Select that is quick to build and easy to manage.
Other Field types
Date Fields are handled in a similar fashion Add a regular date field with
AddDateSD(sb, field, pre, post)
That will render 08/17/15
The parameters are the same as AddTextSingle
AddDateLDW renders - Wednesday, June 03, 2015
AddDateLDWS renders - Wednesday, June 3, 2015
Or you can use AddDateLDR which renders - 3rd day of June, 2015
There are number formatters for Currency and decimal places as well as functions that will enter underscores if no text exists.
Clearly there is a lot more with IronPython in Select, these tools allow a wider audience of developers or technicians to build IronPython modules for Select users.
Everything that is included is shown below. This output was created by a test module and includes more valuable examples of some of what can be done with IronPython in Select. It was formatted for display.
Demo output of test tool
DVF Value Tools Test and IronPython Demo
Most of the Document Formatting Options are duplicated in this module. New thoughts are added
During usage Data Type is important if a string is tossed to a number or date function it will error
Parameter Information
sb is the stringBuilder where the final output is built
field changes during the operation
The variable pre is set to a space, post is set to line feed
Objects or Contexts which have a Number child are labelled for single or multiple, with everything definable in the call
AddObjectNumber(sb, args.Context.Lots, Lot, Lots, commaSpace, space) renders - Lots 7665, 334
Identification style Contexts are handled the same way
AddObjectIdentification(sb, args.Context.Parcels, single, multiple, betweenMultiples, afterLabel) renders - Parcel ID 34-445-1233
field changed to PersonalProperty Amount
AddCurrency(sb, field, pre, post) renders - $543,111.23
AddNumberNoComma(sb, field, pre, post) renders - 543111.23
AddNumber2(sb, field, pre, post) renders - 543,111.23
AddNumber5(sb, field, pre, post) renders - 543,111.23000
field changed to ParkingSpaces
AddTextSingle(sb, field, pre, post) renders - Parking Spaces
AddTextFill(sb, field, pre, post, size=22) renders - ********Parking Spaces
AddTextLeftPad(sb, field, pre, post, size=25, pad=.) renders - ...........Parking Spaces
AddTextRightPad(sb, field, pre, post, size=20, pad=#) renders - Parking Spaces######
AddTextBlankLine(sb, field, pre, post, numberUnderscore = 32) renders - Parking Spaces
AddTextNA(sb, field, pre, post) renders - Parking Spaces
field changed to Condo which is empty to test Empty Conditions on the above 2
AddTextBlankLine(sb, field, pre, post, numberUnderscore=35) renders - ___________________________________
AddTextNA(sb, field, pre, post) renders - N/A
field changed to ParkingSpaces
AddTextLC(sb, field, pre, post) renders - parking spaces
AddTextUC(sb, field, pre, post) renders - PARKING SPACES
field changed to MapReferenceRecording RecordedDate
AddDateSD(sb, field, pre, post) renders - 06/03/15
AddDateSD4(sb, field, pre, post) renders - 06/03/2015
AddDateLD(sb, field, pre, post) renders - June 03, 2015
AddDateLDS(sb, field, pre, post) renders - June 3, 2015
AddDateLDT(sb, field, pre, post) renders - June 03rd, 2015
AddDateLDTS(sb, field, pre, post) renders - June 3rd, 2015
AddDateLDW(sb, field, pre, post) renders - Wednesday, June 03, 2015
AddDateLDWS(sb, field, pre, post) renders - Wednesday, June 3, 2015
AddDateLDR(sb, field, pre, post) renders - 3rd day of June, 2015
AddDateMNAME(sb, field, pre, post) renders - June
AddDateM(sb, field, pre, post) renders - 6
AddDateMM(sb, field, pre, post) renders - 06
AddDateMT(sb, field, pre, post) renders - 6th
AddDateDT(sb, field, pre, post) renders - 3rd
AddDateD(sb, field, pre, post) renders - 3
AddDateDD(sb, field, pre, post) renders - 03
AddDateYY(sb, field, pre, post) renders - 15
AddDateYYYY(sb, field, pre, post) renders - 2015
AddDateWD(sb, field, pre, post) renders - Wednesday
AddDateT(sb, field, pre, post) renders - 9:05 AM
AddDateTS(sb, field, pre, post) renders - 9:05:00 AM
AddDateT24(sb, field, pre, post) renders - 9:05
AddDateTS24(sb, field, pre, post) renders - 9:05:00
AddDateH(sb, field, pre, post) renders - 9
AddDateHH(sb, field, pre, post) renders - 09
AddDateH24(sb, field, pre, post) renders - 9
AddDateHH24(sb, field, pre, post) renders - 09
AddDateMIN(sb, field, pre, post) renders - 05
AddDateSec(sb, field, pre, post) renders - 00
AddDateAMPM(sb, field, pre, post) renders - AM
So have you played with IronPython in Select?
Price
Pricing is based on installation locations, for the typical agent with 5 or fewer office locations the cost is $150.00. For larger installations contact sales at 937-424-5734 to discuss options.
Full distribution rights for this code tool are also available, contact sales for more information.
I’m also available for one on one training sessions at a reasonable fee.