问题
I have a customer utilizing the User Defined fields. I found that the values are located in KvExt tables in the database, but I have not found a way to access those directly through DACs or DAC extensions. Is there a way I can access that field and add it to a base Acumatica page?
The specific target in my case is the ARTran.RefNbr selector in the ARPayments page.
回答1:
As you probably know the User Defined Fields are actually using the Attributes defined in the system. The User Defined Field and actual record (for example ARInvoice
) are bound by NoteID
of the record (ARInvoice
) and RecordID
of the User Defined Field. And the FieldName
of the User Defined Field is storing word 'Attribute' + AttributeID
.
Below SQL Queries show that references:
SELECT CompanyID, RefNbr, DocType, DocDesc FROM ARRegister WHERE RefNbr='AR007092';
SELECT CompanyID, RecordID, FieldName, ValueNumeric, ValueDate, ValueString, ValueText FROM ARRegisterKvExt where RecordID='78A9D6DE-52C4-E911-B2FD-FC017C8C8936';
SELECT CompanyID, AttributeID, Description, ControlType, EntryMask, RegExp, List, IsInternal, ContainsPersonalData FROM CSAttribute WHERE'AttributeBURDEN' LIKE '%'+AttributeID;
And the result sets:
After knowing the references shown above, we can create a DAC to the ARRegisterKvExt
table like below:
[PXCacheName("AR Register Attributes")]
[Serializable]
public class ARRegisterKvExt : IBqlTable
{
public abstract class recordID : BqlGuid.Field<recordID> { }
[PXDBGuid(IsKey = true)]
public Guid? RecordID { get; set; }
public abstract class fieldName : BqlString.Field<fieldName> { }
[PXDBString(50,IsKey = true)]
[PXUIField(DisplayName ="Name")]
public string FieldName { get; set; }
public abstract class valueNumeric : BqlDecimal.Field<valueNumeric> { }
[PXDBDecimal(8)]
[PXUIField(DisplayName = "Value Numeric")]
public decimal? ValueNumeric { get; set; }
public abstract class valueDate : BqlDateTime.Field<valueDate> { }
[PXDBDate]
[PXUIField(DisplayName = "Value Date")]
public DateTime? ValueDate { get; set; }
public abstract class valueString : BqlString.Field<valueString> { }
[PXDBString(256)]
[PXUIField(DisplayName = "Value String")]
public string ValueString { get; set; }
public abstract class valueText : BqlString.Field<valueText> { }
[PXDBString]
[PXUIField(DisplayName = "Value Text")]
public string ValueText { get; set; }
}
And write a PXSelector
with Left Joins to our DAC and CSAttribute
like below:
[PXSelector(typeof(Search2<ARInvoice.refNbr, LeftJoin<ARRegisterKvExt, On<ARInvoice.noteID,Equal<ARRegisterKvExt.recordID>>, LeftJoin<CSAttribute, On<ARRegisterKvExt.fieldName,Contains<CSAttribute.attributeID>>>>>), new[] { typeof(ARInvoice.refNbr), typeof(ARInvoice.docType), typeof(CSAttribute.description), typeof(ARRegisterKvExt.valueString)}, DescriptionField = typeof(ARInvoice.docDesc))]
As a result, you will see lookup like below:
As you can see the AR Invoices which don't have value for the User Defined Fields don't have the Name of the field too. This is caused by the way Acumatica is handling the User Defined Fields. The record for the User Defined Fields is being written to the database only when you set a value. And deletes that record if you clear the value.
The bad side of using the User Defined Fields in the lookups is that if you have 2 User Defined Fields for AR Invoice then the same Invoice will be shown twice, but only if the values for both User Defined Fields are set.
来源:https://stackoverflow.com/questions/57597280/is-there-a-way-to-get-user-defined-fields-into-selectors