TimRayburn.CustomFunctoids - FormatDate

Today's functoid addresses another classic "scripting" problem within the BizTalk Mapper. Often when mapping I find that I am being given dates in an established format (often "yyyyMMdd" the EDI standard) and need to translate that date into another format used by the destination schema (usually "MM/dd/yyyy").  A perfectly reasonable thing to need to do within a data transformation engine.  Normally this would take a scripting functoid when done correctly (when done incorrectly it can involve a dozen or more string functoids).  This functoid will add to the Conversion group and take three parameters, the first is a date, the second is the format in which the date is currently formatted, and the third is the desired format of the date. For those more interested in the .NET than the functoid, you will note I used the little known DateTime.ParseExact in this functoid.  This requires us to provide an IFormatProvider.  Since BizTalk is a service, I opted to use the System.Threading.Thread.CurrentThread.CurrentCulture.  The other option would have been CurrentUICulture, but that could provide very strange results. Download TimRayburn.CustomFunctoids v1.0    10     class FormatDateFunctoid : BaseFunctoid   11     {   12         public FormatDateFunctoid()   13         {   14             // Assign a "unique" id to this functiod   15             this.ID = 24604;   16    17             // Setup the resource assembly to use.   18             SetupResourceAssembly(   19               "TimRayburn.CustomFunctoids.CustomFunctoidsResources",   20               Assembly.GetExecutingAssembly());   21    22             SetName("IDS_FORMATDATEFUNCTOID_NAME");   23             SetTooltip("IDS_FORMATDATEFUNCTOID_TOOLTIP");   24             SetDescription("IDS_FORMATDATEFUNCTOID_DESCRIPTION");   25             SetBitmap("IDB_FORMATDATEFUNCTOID_BITMAP");   26    27             this.SetMinParams(3);   28             this.SetMaxParams(3);   29    30             SetExternalFunctionName(this.GetType().Assembly.FullName,   31               "TimRayburn.CustomFunctoids.FormatDateFunctoid",   32               "FormatDate");   33    34             this.Category = FunctoidCategory.Conversion;   35             this.OutputConnectionType = ConnectionType.AllExceptRecord;   36    37             AddInputConnectionType(ConnectionType.AllExceptRecord);   38             AddInputConnectionType(ConnectionType.AllExceptRecord);   39             AddInputConnectionType(ConnectionType.AllExceptRecord);   40         }   41         public string FormatDate(string inDate, string inFormat, string outFormat)   42         {   43             System.Globalization.CultureInfo ci =    44               System.Threading.Thread.CurrentThread.CurrentCulture;   45             DateTime lDate = System.DateTime.ParseExact(inDate, inFormat, ci);   46             return lDate.ToString(outFormat,ci);   47         }   48     }

TimRayburn.CustomFunctoids - Trimmed Value Exists

 Today's functoid is one which I've created in the past for several clients working with BizTalk 2004 and flat files, especially position files.  Often you will encounter a situation where the disassembler will give you a value of "         ".  In BTS 2006 you have the option of setting a fill character that is ignored by the disassembler, but on '04 you've got to deal with this in the map. The premise then in simple, to avoid the common pattern of a Trim -> Size -> Greater Than -> Value Mapping we roll up the first three of these into this single functoid.  The code is presented below, and you can follow the link to the source code download. Download TimRayburn.CustomFunctoids v1.0     9     class TrimmedValueExistsFunctoid : BaseFunctoid   10     {   11         public TrimmedValueExistsFunctoid(): base()   12         {   13             // Assign a "unique" id to this functiod   14             this.ID = 24603;   15    16             // Setup the resource assembly to use.   17             SetupResourceAssembly(   18               "TimRayburn.CustomFunctoids.CustomFunctoidsResources",   19               Assembly.GetExecutingAssembly());   20    21             SetName("IDS_TRIMMEDVALUEEXISTSFUNCTOID_NAME");   22             SetTooltip("IDS_TRIMMEDVALUEEXISTSFUNCTOID_TOOLTIP");   23             SetDescription("IDS_TRIMMEDVALUEEXISTSFUNCTOID_DESCRIPTION");   24             SetBitmap("IDB_TRIMMEDVALUEEXISTSFUNCTOID_BITMAP");   25    26             this.SetMinParams(1);   27             this.SetMaxParams(1);   28    29             SetExternalFunctionName(this.GetType().Assembly.FullName,   30               "TimRayburn.CustomFunctoids.TrimmedValueExistsFunctoid",   31               "TrimmedValueExists");   32    33             this.Category = FunctoidCategory.Logical;   34             this.OutputConnectionType = ConnectionType.AllExceptRecord;   35    36             AddInputConnectionType(ConnectionType.AllExceptRecord);   37         }   38         public string TrimmedValueExists(string inputVal)   39         {   40             if (inputVal.Length.Equals(0))   41               return "true";   42             else   43             {   44               string trimmedVal = inputVal.Trim();   45               if (trimmedVal.Length.Equals(0))   46                     return "true";   47               else   48                     return "false";   49             }   50         }   51     }

TimRayburn.CustomFunctoids - If ... Else

This post is part of an ongoing series, the explanation of which can be found here. This one should be of more use to our friends using BizTalk Server 2006.  Today we tackle a problem that anyone who has ever mapped an EDI 837 I/P/D has had to deal with, and probably solved with hundreds of "Value Mapping" functoids and Logical Not (if you are on 2006) functoids. The out of the box functoid set gives you a very nice "Value Mapping" functoid which is great because it compiles to an xsl:if tag.  But if you want to do a simple If A then B else C type logic you are left with either two value map functoids and a Logical Not (or Logical Equal in 2004) functoids, or you are writing a scripting functoid.  Either way you have hampered the readability of your map, and in the case of the value map solution you've netted yourself a compiler warning for two links to one node for each and every node you had to do this with.  If it is an 837 that you're doing this with, that is a TON of nodes in the 2300 and 2400 loops. The solution?  IfElseFunctiod of course!  This class, added to the TimRayburn.CustomFunctoids project, takes three parameters.  The first is a boolean, the second is the value returned if true, the third is the value returned if false.  It is important to note that in any case, if connected directly to the output schema this will produce a node.  It is not a XSLT functoid and cannot suppress the output node.  For now if you need to do that, you're still stuck with putting in a Value Mapping functoid. The newly added class can be found below.  It is nearly identical to last night's functoid of course.  Interestingly, I tried to refactor this class and the other to create a base class that handled assigning the ID and resources.  When I did so, BizTalk stopped recognizing that the assembly contained any functoids.  Apparently your custom functoids must not simply inherit from BaseFunctoid, they must be direct children of BaseFunctoid. Download v1.0 of TimRayburn.CustomFunctoids    10     class IfElseFunctoid : BaseFunctoid   11     {   12         public IfElseFunctoid()   13         {   14             // Assign a "unique" id to this functiod   15             this.ID = 24602;   16    17             // Setup the resource assembly to use.   18             SetupResourceAssembly(   19               "TimRayburn.CustomFunctoids.CustomFunctoidsResources",   20               Assembly.GetExecutingAssembly());   21    22             SetName("IDS_IFELSEFUNCTOID_NAME");   23             SetTooltip("IDS_IFELSEFUNCTOID_TOOLTIP");   24             SetDescription("IDS_IFELSEFUNCTOID_DESCRIPTION");   25             SetBitmap("IDB_IFELSEFUNCTOID_BITMAP");   26    27             this.SetMinParams(3);   28             this.SetMaxParams(3);   29    30             SetExternalFunctionName(this.GetType().Assembly.FullName,   31               "TimRayburn.CustomFunctoids.IfElseFunctoid",   32               "IfElse");   33    34             this.Category = FunctoidCategory.ValueMapping;   35             this.OutputConnectionType = ConnectionType.AllExceptRecord;   36    37             AddInputConnectionType(ConnectionType.AllExceptRecord);   38             AddInputConnectionType(ConnectionType.AllExceptRecord);   39             AddInputConnectionType(ConnectionType.AllExceptRecord);   40         }   41    42         public string IfElse(string booleanValue, string trueValue, string falseValue)   43         {   44             bool bVal = System.Convert.ToBoolean(booleanValue);   45             if (bVal)   46               return trueValue;   47             else   48               return falseValue;   49         }   50     }