Acumatica分段键动态分配维度名及IF条件失效问题求助
Hey Pedro, let's break down your two Acumatica customization challenges and walk through practical solutions for each:
You're right that Acumatica defaults to hardcoded dimension names or static [PXDimension("VENDOR")] attributes—but there are workarounds to assign dimensions dynamically based on your business logic:
Option 1: Graph Event Handlers for Segmented Key Maintenance
If you need to set dimension names when configuring segmented keys themselves, extend the SegmentedKeyMaint graph to add conditional logic. For example, you can pull dimension names from a custom configuration table or switch based on module context:
public class SegmentedKeyMaintExtension : PXGraphExtension<SegmentedKeyMaint> { protected void _(Events.FieldUpdated<SegmentedKey, SegmentedKey.segmentID> e) { if (e.Row == null) return; // Example: Use a custom config table to pull dynamic dimension names var moduleConfig = PXSelect<CustomModuleConfig, Where<CustomModuleConfig.moduleCode, Equal<Required<CustomModuleConfig.moduleCode>>>> .Select(Base, e.Row.Module); if (moduleConfig != null) { e.Row.DimensionName = moduleConfig.DimensionName; } // Or hardcode conditional logic else if (e.Row.Module == "AP") { e.Row.DimensionName = "CUSTOMAPDIMENSION"; } } }
Option 2: Dynamic Dimension Assignment on Transaction Fields
If you need to switch dimensions for a segmented key field on transactions (like APTran or SOTran), use the RowSelected event to override the dimension context:
public class APTranExtension : PXCacheExtension<APTran> { [PXDimensionSelector("", typeof(Search<SegmentedValue.value, Where<SegmentedValue.dimensionName, Equal<Current<APTran.dynamicDimension>>>>), typeof(SegmentedValue.value), DescriptionField = typeof(SegmentedValue.description))] public string UsrCustomSegment { get; set; } protected void _(Events.RowSelected<APTran> e) { APTran row = e.Row; if (row == null) return; // Set dynamic dimension name based on transaction type row.SetExt<APTranExtension>(ext => ext.UsrCustomSegment = row.TranType == "IN" ? "VENDORINVOICE" : "VENDORPAYMENT"); } }
Since I can't see your attached screenshot, I'll cover the most common scenarios where IF logic fails in Acumatica custom fields:
Scenario 1: Using C# IF in DAC Formula Attributes
Acumatica's PXFormula doesn't support raw C# if statements—you need to use Acumatica's built-in conditional operators like PXCase or IIF:
❌ Wrong (C#-style IF won't work):
[PXFormula(typeof(if<Equal<APTran.tranType, Constant<"IN">>, Constant<"Invoice">, Constant<"Payment">>))]
✅ Correct (use Acumatica's conditional helpers):
// Option 1: PXCase for multi-condition logic [PXFormula(typeof(PXCase< Equal<APTran.tranType, Constant<"IN">>, Constant<"Invoice">, Equal<APTran.tranType, Constant<"PM">>, Constant<"Payment">, Constant<"Other">>))] // Option 2: IIF for simple true/false checks [PXFormula(typeof(IIF<Equal<APTran.tranType, Constant<"IN">>, Constant<"Invoice">, Constant<"Payment">>))]
Scenario 2: IF Logic in Graph Event Handlers
If your IF statement is in a graph event (like FieldUpdated), double-check for syntax or type mismatch issues:
protected void _(Events.FieldUpdated<APTran, APTran.extCost> e) { APTran row = e.Row; if (row == null) return; // Ensure type matching (e.g., don't compare strings to integers) if (row.Qty > 100) { row.ExtCost = row.ExtCost * 0.95m; // Apply 5% discount for large quantities } }
Scenario 3: IF in Generic Inquiries/Reports
For GI or report expressions, use SQL-style CASE WHEN instead of C# IF:
CASE WHEN [APTran.TranType] = 'IN' THEN 'Invoice' ELSE 'Payment' END
内容的提问来源于stack exchange,提问作者Pedro

