C# Code help anyone?

,

Hi guys, I need a bit of help / advice on a small BPM which I am trying to write. I have a custom field (character03) on the QuoteDtl which holds a comma delimited character string. This string contains location references to be printed on labels. There is a check at the beginning to replace unwanted carriage returns double commas etc to hopefully end up with a string like this;

ref1,ref2,ref3,ref4,ref5…etc etc

So far so good. However, because we are in the construction industry and these references are usually floors of buildings which could have many products my users want to be able to enter the references like this

ref1[25],ref2,ref3[50],ref4,ref5[3]…etc etc.

I am a bit stuck on how to check this. Anybody done anything similar?
Here is where I am at the moment. All help and advice much appreciated.
Adrian.

var ttQuoteDtl_iterator = (from ttQuoteDtl_Row in ttQuoteDtl
                         where (ttQuoteDtl_Row.RowMod == "U")
                         select ttQuoteDtl_Row).FirstOrDefault();

// Check if a row exists.
// If it does make sure there are no extra commas or line feeds
if (ttQuoteDtl_iterator != null)
{
	bool stringCorrect = false;
	string refs = ttQuoteDtl_iterator["Character03"].ToString();
	refs = refs.Replace("\r",",");
	refs = refs.Replace("\n",",");
	refs = refs.Replace(", ,",",");
	refs = refs.Replace(",,",",");
	ttQuoteDtl_iterator["Character03"] = refs;

// Get quantity required
	int qty = Convert.ToInt32(ttQuoteDtl_iterator.OrderQty);
	
// Get number of refs in string;
	int qtyRefs = refs.Split(',').Count();

	if ((qty >= 1 && qtyRefs  == 1) || qty == qtyRefs)
		{
			stringCorrect  = true;
		}
 
//Diagnostic message
string msg = "Ref string is " + refs  + "\r\n"
						+ "Order Qty is  " + qty + "\r\n"
						+ "Qty of refs is " + qtyRefs  + "\r\n"
						+ "Refs correct is " + stringCorrect;
throw new Ice.Common.BusinessObjectException( 
new Ice.Common.BusinessObjectMessage(msg) 
	{ 
		Type = Ice.Common.BusinessObjectMessageType.Information, 
	});
this.PublishInfoMessage(msg, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", "");
}
1 Like

I’m not sure I follow what you are trying to accomplish. Can you explain that last bit?
What is it that you want to do with this

ref1[25],ref2,ref3[50],ref4,ref5[3]…etc etc.
1 Like

I took it to mean
ref1,ref1,ref2,ref2,ref2,ref2,ref2,,ref3
would be
ref1[2],ref2[5],ref3

1 Like

Hi Jose, sorry for not being very clear. The problem we have is that users do not always enter the correct number of references for the quantity of products Each product has a specific location reference, the label printing software will not print anything if the quantity of references does not match the order quantity, unless the quantity of references is 1, then it will print the same reference on all the labels.
At present, if we have an order line with a qty of 200 for example, using the part string above and 25 were going to ref1, the user has to type ref1 25 times, 1 time for ref2, 50 times for ref3, 1 time for ref4 and 3 times for ref5, a total of 83 labels. It is quicker and easier to spot mistakes in the above string but harder to check.
Adrian.

Yes Calvin you are correct :slight_smile:

Whoops… I deleted it to avoid confusion. Now how to undelete a post?

I’m getting old or something I still don’t understand LoL

I think he wants to combine the “refs” with a ref count in brackets, instead of having the same one repeated.

If the order line is for 10, and the 5 each go to floors 1, 2, 3, 4, 5 and (5) go to floor 10: The “ref” stored in the ud field is
ref1,ref2, ref3, ref4, ref5, ref10, ref10, ref10, ref10, ref10

which he wants to be converted to

ref1,ref2,ref3,ref4,ref5,ref10[5]

Got it, thank you @ckrusen sorry my brain is fried.
Your best bet here is to spilt on the comma’s and then maybe use RegEx to get a Group inside the brackets (count) otherwise default to 1.

Almost right Calvin, but the other way around. I want

ref1,ref2,ref3,ref4,ref5,ref10[5]

converted to

ref1,ref2, ref3, ref4, ref5, ref10, ref10, ref10, ref10, ref10

I would

  1. Remove the CRs, LF, spaces and double commas (and check for a trailing comma)
  2. Convert the string to an array
  3. Sort the array
  4. Step through the array and keep a running count when the element is the same as the last, and reset to 1 on change of element value

Do the opposite of what I suggested above :wink:

Convert to an array, step through each element, concat the “ref” part on to a new string. If it has the “[]”, do the concat that many (minus 1) more times.

string refs = "ref1,reff2,ref3,ref4,ref5,ref10[5]";
		
	string[] arr = refs.Split(',');
	string exp = "";
	
	foreach( string el in arr){
		//exp = exp + el + ',';
		int j;			// num in brackets for counting
		string s="";	// the prat before the brackets
		
		
		Regex r = new Regex(@"^(?<rf>.+)\[(?<c>.*)\]",RegexOptions.None, TimeSpan.FromMilliseconds(150));
		
		Match m = r.Match(el);
		 if (m.Success){
			 s = r.Match(el).Result("${rf}");
			 j = Convert.ToInt32(r.Match(el).Result("${c}"));
			 while(j>0){
				 exp = exp + s + ',';
				 j--;
				 }
			 }
		else{
			 exp = exp + el + ',';
			}
		}	
  1. It breaks the original string refs into an array arr.
  2. Steps through array arr (with each element tempo assigned to el).
  3. Does a Regex to see if it is in the for s[d]
  4. If it is break it into the s part and assign j to the value in the bracket, and loop through j times: appending s to the output exp
  5. Else append el to output exp

EDIT:

With refs = “ref1,reff2,ref3,ref4,ref5,ref10[5]”

exp is set to “ref1,reff2,ref3,ref4,ref5,ref10,ref10,ref10,ref10,ref10,”

This will leave a trailing comma, which needs to be cleaned off

2 Likes

take the final string and…

myFinalString = myFinalString.Trim(',');
1 Like

I’m not really good at C# (more of an K&R C guy). So a quick check of the code above would be appreciated.

What about… using Epicor’s CSV Cleanser which already fixes all kinds of issues =)

string refs = "ref1,reff2,ref3,ref4,ref5,ref10[5]"; 
string[] arr = refs.Split(',');
string readyOrNothereICome = Ice.Lib.SharedUtilities.ImportExport.CsvWriter.GetCSVLine(arr);

You will have to Add Ref to Ice.Lib.Shared I believe…

The beauty of Ice.Lib.SharedUtilities.ImportExport.CsvWriter is that it will handle the character escapes for you! You just pass it an Array.

Col1, 123, “Col\”3”, Col4_IDontNeedToBeEscapesSoIDontNeed Quotes


Might not fit this, issue; but it exists just FYI :slight_smile:

2 Likes

Thanks Calvin, you were much quicker than me. I was still working on creating and splitting my array (with a lot of help from Google). I like your way better but the compiler doen’t like the ‘Match’ syntax, what do I need to do to it?

Not exactly sure about the match syntax. I did my testing on expander | C# Online Compiler | .NET Fiddle

I think @hkeric.wci would be the best to make it “Epicor friendly”

edit: did you add using System.Text.RegularExpressions; ??

Just found it, I will add and test tomorrow. I’m off home now. Thank you and @hkeric.wci (the Guru) for all your help. Saved me loads of time!!
Adrian.

It works perfectly! Now I am struggling to update the content of ‘Character03’ with the new text string (exp). I’ve tried calling a post processing method and setting the field there, I tried setting the field in the pre processing and I tried moving all the custom code to a post processing method. Nothing worked.
Here is the code as it stands at the moment.

var ttQuoteDtl_iterator = (from ttQuoteDtl_Row in ttQuoteDtl
                         where (ttQuoteDtl_Row.RowMod == "U")
                         select ttQuoteDtl_Row).FirstOrDefault();

// Check if a row exists.
// If it does make sure there are no extra commas or line feeds
string msg = "";
if (ttQuoteDtl_iterator != null)
{
	bool stringCorrect = false;
	string refs = ttQuoteDtl_iterator["Character03"].ToString();
	refs = refs.Replace("\r",",");
	refs = refs.Replace("\n",",");
	refs = refs.Replace(", ,",",");
	refs = refs.Replace(",,",",");
	

// Get quantity required
	int qty = Convert.ToInt32(ttQuoteDtl_iterator.OrderQty);
	

//string refs = "ref1,reff2,ref3,ref4,ref5,ref10[5]";
		
	string[] arr = refs.Split(',');
	string exp = "";
	
	foreach( string el in arr){
		//exp = exp + el + ',';
		int j;			// num in brackets for counting
		string s="";	// the prat before the brackets
		
			
		Regex r = new Regex(@"^(?<rf>.+)\[(?<c>.*)\]",RegexOptions.None, TimeSpan.FromMilliseconds(150));
		
		Match m = r.Match(el);
		 if (m.Success){
			 s = r.Match(el).Result("${rf}");
			 j = Convert.ToInt32(r.Match(el).Result("${c}"));
			 while(j>0){
				 exp = exp + s + ',';
				 j--;
				 }
			 }
		else{
			 exp = exp + el + ',';
			}
		}
	// Get number of refs in string;
	exp = exp.Trim(',');
	int qtyRefs = exp.Split(',').Count();	

	if ((qty >= 1 && qtyRefs  == 1) || qty == qtyRefs)
		{
			stringCorrect  = true;
			callContextBpmData.Character01 = exp;
			callContextBpmData.Checkbox01 = true;
 ttQuoteDtl_iterator["Character03"] = exp;
//Diagnostic message
	 msg = "Ref string is " + exp  + "\r\n"
						+ "Order Qty is  " + qty + "\r\n"
						+ "Qty of refs is " + qtyRefs  + "\r\n"
						+ "Refs correct is " + stringCorrect;
							throw new Ice.Common.BusinessObjectException( 
						new Ice.Common.BusinessObjectMessage(msg) 
						{ 
							Type = Ice.Common.BusinessObjectMessageType.Information, 
						});
							this.PublishInfoMessage(msg, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", "");		
	}
	else
	{
		msg = "References do not match! "  + "\r\n"
					+ "Qty of refs is " + qtyRefs  + "\r\n"
					+ "Order Qty is " + qty  + "\r\n"
					+ "Please check all commas are present and in the correct place.";
						throw new Ice.Common.BusinessObjectException( 
						new Ice.Common.BusinessObjectMessage(msg) 
						{ 
							Type = Ice.Common.BusinessObjectMessageType.Error, 
						} );
	}	
}
else
{
	msg = "No quote found";
						throw new Ice.Common.BusinessObjectException( 
						new Ice.Common.BusinessObjectMessage(msg) 
						{ 
							Type = Ice.Common.BusinessObjectMessageType.Error, 
						} );
}