.Net Interoperability – String Manipulation

I was recently afforded the opportunity to attend a NAV 2009 R2 Technical Deepdive session at Microsoft TVP. Whilst I had been exposed to many of the new features via many blogs from various people, it was interesting to be walked through the various areas by Microsoft specialists themselves. In particular there was a good session by Lars Lohndorf-Larsen on the new features from a development perspective.

One area stood out of course, and it was on the subject of .NET interoperability using the new DotNet variable type within R2. Seeing the demonstration got me thinking about a common problem in NAV, and something that I am often frustrated by. It centres around the parsing of long strings of text into fixed length fields – something like taking a couple of sentences in Excel or a text file, and populating a comment-like table structure in NAV.

I am well aware that there are many ways of doing this in NAV, but if I am correct this sort of string manipulation which respects words (ie. doesn't chop them half way through) actually requires a fair few lines of code.

I am also aware of some fantastic functionality built in to .NET called Regular Expressions, which make this sort of thing possible with a single function call. Wouldn't it be fantastic if we could call the regular expression function to do the job in NAV for us?

With R2 this is actually quite easy! (I am sure it was also possible using COM etc etc previously, but now even I can understand what is required).

To keep this simple I will assume that we can get the text into the following simple table structure:

Field No.

Field Name

Data Type

Length

1

Entry No.

Integer

 

2

Text 1

Text

250

3

Text 2

Text

250

4

Text 3

Text

250

5

Text 4

Text

250

 

    *Of course we could also import the text on the fly rather than save it into a table.

Then create a little data in the table:

Entry No.

Text 1

Text 2

Text 3

Text 4

1

This is some text in the first field of our table to demonstrate how we can use .NET interoperability to split our text into manageable segments. We should be able to insert the results of the call to the .NET DLL into something like the Comment Lin

e table (97) in NAV. You will note how the words have been split as this text was imported into this table. As we import more and more text, so the text will continue to be split across the fields we have available. Of course we could be doing thi

s using INSTREAM, dataports or xmlports, but in order to keeps things simple here we have decided to simply use this table. Of course we could go on and on inserting more and more text in here but I am struggling to find something sensible to say.

Perhaps this is actually enought text to do prove the concept.

 

250 chars

250 chars

250 chars

62 chars

 

So now for the fun... the .NET which we will call out to do the legwork!

Create a new C# Class Library in Visual Studio (I'm using VS2008)

Write the following code (of course some of it will automatically be created when you create the class):

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Text.RegularExpressions;

 

namespace StringManipulation

{

    public class SplitIt

    {

        public string[] SpltTexttoArray(string NAVText)

        {

            //This is the magical line which returns a collection respecting word breaks etc

            MatchCollection matches = Regex.Matches(NAVText, @"(?<Line>.{1,79})(?:\W|$)");

 

            //Create a new string array which is the size as defined by

            //a count of the elements in the collection

            string[] sa = new string[matches.Count];

 

            //Create a loop to store each string section in an element in

            //the array which is what NAV will then use

            for (int i = 0; i < sa.Length; i++)

            {

                sa[ i] = matches[i ].Value;

            }

            return sa;

        }

    }

}

Next remember to copy the DLL to the relevant Add-ins folders.

Create a new codeunit in NAV with the following variables:

Name

DataType

Subtype

Length

DotNetFunc

DotNet

'StringManipulation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.StringManipulation.SplitIt

myDotNetFunc

DotNet

'StringManipulation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.StringManipulation.SplitIt

myNetFuncArray

DotNet

'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Array

stringtosplit

Text

1024

ImportedText

Record

Imported Text

CommentLine

Record

Comment Line

i

Integer

 

And the following basic code (I know not optimal J):

OnRun()

//Call the constructor

myDotNetFunc := DotNetFunc.SplitIt();

 

//Get the text we want to split

ImportedText.GET(1);

stringtosplit := ImportedText."Text 1" +

ImportedText."Text 2" +

ImportedText."Text 3" +

ImportedText."Text 4";

 

CLEAR(myNetFuncArray);

//Call out to our .NET DLL

//and store the result in a System array (another .NET construct)

myNetFuncArray := myDotNetFunc.SpltTexttoArray(stringtosplit);

 

//Loop around the array and populate the comment

//(for Item 10000 in this case - hardcoded!)

FOR i := 1 TO myNetFuncArray.Length() DO BEGIN

CommentLine."Table Name" := CommentLine."Table Name"::Item;

CommentLine."No." := '1000';

CommentLine."Line No." += 10000;

CommentLine.Comment := FORMAT(myNetFuncArray.GetValue(i-1));

CommentLine.INSERT;

END;

 

The last step before we see the results of our labour is to simply add a call to this new codeunit to a page in NAV (of course this does not run from forms and only from the RTC – nevertheless we can use it for processing as we are now).

I added the call to my default Order Processor Role Center using a new action.

 

Then simply running the function from the RTC page yields the following result:

Comment List
Related
Recommended