Skip to main content
Answer

PXFormula Concat Decimal and String

  • June 2, 2025
  • 6 replies
  • 113 views

Forum|alt.badge.img

I have a custom non-persisted field defined on the CRQuote DAC:

public class usrDays: Constant<string> { public usrDays() : base(" working day(s) to ship") { } }

[PXString(60)]
[PXUIField(DisplayName="Lead Days Description")]
[PXFormula(typeof(Add<CRQuoteExt.usrRevLeadDays, usrDays>))]

CRQuoteExt.usrRevLeadDays is:

[PXDecimal(0)]
[PXUIField(DisplayName="Lead Days (Rev)")]
[PXDBCalced(typeof(
IsNull<
CR.Standalone.CRQuoteExt.usrLeadDays, CR.Standalone.CRQuoteExt.usrRevLeadDays
>
), typeof(decimal))]

usrDays is a string, as defined above. I want to concatenate the decimal and the string in the PXFormula. I have tried many combinations of Add, Concat, Use, and have not been able to get these fields combined. The current configuration publishes, but when I try to load CRQuotes, I get:

System.FormatException
Message:
Input string was not in a correct format.

 

I cannot find any examples of casting types, or combining strings with decimals in PXFormula. Can anyone help?

Thank you for reading.

Best answer by darylbowman

Did you add the PXFormula to the string DAC definition? Does the decimal commit changes? And when you make a change to the decimal field, does it still not return anything? If you want it to return something without changing the decimal, you’ll have to use [PXUnboundDefault] instead. This will run in RowSelecting instead of only when inserting (or the decimal is changed).

6 replies

darylbowman
Captain II
Forum|alt.badge.img+15

Instead of using PXFormula to run the calculation, set [PXDefault(PersistingCheck = PXPersistingCheck.Nothing)] on your string field DAC definition and use the FieldDefaulting event handler to set the concatenated value into your field. This way you can handle the casting, etc.

Also put [PXFormula(typeof(Default<decimalField>))] on your string field DAC definition, referencing the decimal field. If the decimal changes, the defaulting event will run again for the string and display the new decimal value (providing the decimal field is committing changes).


Forum|alt.badge.img
  • Author
  • Jr Varsity II
  • June 3, 2025

@darylbowman Thank you for your reply and a new direction to try. I added this method to a QuoteMaint graph extension:

protected virtual void CRQuote_UsrLeadDaysDesc_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{

e.NewValue = "my new value";

}

And I modified the field definition to:

[PXString(60)]
[PXUIField(DisplayName="Lead Days Description")]
[PXDefault(PersistingCheck = PXPersistingCheck.Nothing)]
[PXFormula(typeof(Default<usrRevLeadDays>))]

I am worried that any or all of these factors are the reason I get no data in the field where I am looking for it:

  1. CRQuote is a Projection, so maybe there is something I need to do with the Standalone?
  2. UsrRevLeadDays is non-persisted, so maybe it won’t trigger FieldDefaulting events?
  3. The place I want the value to appear is in the Email Template used when you click the Send button on the CR604500.rpx report. The Email Template is using screen CR.30.45.00, which uses the QuoteMaint graph, but I’m not sure FieldDefaulting events on QuoteMaint are triggered when this email template is building?

In the basic Sales Quotes GI, I am displaying UsrLeadDaysDesc and it is always empty as well, but I expect that it should be blank because the QuoteMaint graph is not involved in the GI display? Is there another place I can check the FieldDefaulting event is working? I also tried adding the field to the Sales Quotes form just to see if it filled in and it was still blank:

 


darylbowman
Captain II
Forum|alt.badge.img+15

You need to set e.Cancel = true in the event handler to overwrite the default value assigned by the [PXDefault] attribute.

 

​...UsrRevLeadDays is non-persisted...

I’m a little confused. The decimal field is unpersisted, but you’re attempting to use the resulting value in an Email Template? How is the decimal value going to be set?


Forum|alt.badge.img
  • Author
  • Jr Varsity II
  • June 3, 2025

@darylbowman Sorry, I oversimplified in the attempt I showed. My first try looked like this and also gave me a blank description:

protected virtual void CRQuote_UsrLeadDaysDesc_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
e.NewValue = "my new value";
e.Cancel = true;
}

UsrRevLeadDays coalesces CRQuote.UsrLeadDays (a user-specified override) with UsrQuoteRevision.LeadDays (a stored calculation). The SQL looks like this:

select  
[CRQuote_CRQuote].[UsrLeadDays],
ISNULL(
[CRQuote_CRQuote].[UsrLeadDays],
(
SELECT
TOP (1) [UsrQTRevision].[LeadDays]
FROM
[UsrQTRevision] [UsrQTRevision]
WHERE
([UsrQTRevision].[CompanyID] = 2)
AND ([UsrQTRevision].[CompanyID] = 2)
AND (
[UsrQTRevision].[QuoteNbr] = [CRQuote_CRQuote].[QuoteNbr]
AND [UsrQTRevision].[RevNbr] = [CRQuote_CRQuote].[UsrRevNbr]
)
ORDER BY
[UsrQTRevision].[LeadDays]
)
) AS [UsrRevLeadDays]
from CRQuote [CRQuote_CRQuote]

 


darylbowman
Captain II
Forum|alt.badge.img+15
  • Answer
  • June 4, 2025

Did you add the PXFormula to the string DAC definition? Does the decimal commit changes? And when you make a change to the decimal field, does it still not return anything? If you want it to return something without changing the decimal, you’ll have to use [PXUnboundDefault] instead. This will run in RowSelecting instead of only when inserting (or the decimal is changed).


Forum|alt.badge.img
  • Author
  • Jr Varsity II
  • June 4, 2025

@darylbowman We got there, thank you so much!

I did have PXFormula on the string DAC function. The UsrQTRevision.LeadDays decimal is persisted through a custom form, and the CRQuote.UsrLeadDays decimal is in the QuoteMaint form, but CRQuote.UsrRevLeadDays isn’t (PXDBCalced), and neither is UsrLeadDaysDesc. I did want to return something without changing the decimal, so I changed to PXUnboundDefault:

[PXString(60)]
[PXUIField(DisplayName="Lead Days Description")]
[PXUnboundDefault]

And changed the FieldDefaulting handler to a FieldSelecting handler in QuoteMaint:

protected virtual void CRQuote_UsrLeadDaysDesc_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
CRQuote row = e.Row as CRQuote;
if (row == null) return;

var rowExt = row.GetExtension<CRQuoteExt>();

switch(rowExt.UsrRevLeadDays){
case null:
e.ReturnValue = "";
break;
case 0:
e.ReturnValue = "All items in stock";
break;
case 99:
e.ReturnValue = "Lead time is negotiable";
break;
default:
e.ReturnValue = rowExt.UsrRevLeadDays + " working day(s) to ship";
break;
}
}

This is working great and is so much easier to deal with than the BQL I was working with. Thank you again for your expertise and patience.