Acumatica定制:如何通过反射获取Cache内的字段值
Acumatica Graph中根据配置字段名获取DAC字段值实现方案
核心原因
无法获取字段值的核心逻辑缺口是:PXCache的字段取值方法必须绑定当前操作的具体实体记录对象,现有代码仅遍历了Cache的字段元数据,没有传入取值对应的数据源实体,因此无法拿到实际业务值。
核心取值API
Acumatica PXCache原生提供两个按字段名字符串取值的方法,可直接调用:
PXCache.GetValue(object dataRecord, string fieldName):获取字段的数据库存储值,例如CustomerID字段返回int类型的主键IDPXCache.GetValueExt(object dataRecord, string fieldName):返回字段的PXFieldState扩展对象,其Text属性为界面上展示的格式化文本,例如CustomerID字段返回对应的客户编号CD值
修正后的可运行代码
public PXAction<FSAppointment> myExtForms; [PXUIField(DisplayName = "MyXForm", MapEnableRights = PXCacheRights.Select)] [PXButton] public virtual void MyExtForms() { List<String> fieldValues = new List<string>(); // 配置项(后续可直接替换为外部文件加载逻辑) String DACNameForPassing = "FSAppointment"; // 注意修正原配置拼写错误,实际DAC类名无末尾s List<String> PassFields = new List<string> { "RefNbr", "AppointmentID", "CustomerID" }; var allCaches = Base.Caches.Caches; foreach (PXCache pxCache in allCaches) { // 不区分大小写匹配目标DAC缓存 if (!string.Equals(pxCache.GetName(), DACNameForPassing, StringComparison.OrdinalIgnoreCase)) { continue; } // 获取当前界面正在操作的实体记录,作为取值数据源 object currentRecord = pxCache.Current; if (currentRecord == null) { continue; } // 遍历字段匹配配置项 foreach (string fieldName in pxCache.Fields) { // 用等值匹配替代Contains,避免部分匹配导致字段误判 bool isTargetField = PassFields.Any(f => string.Equals(f, fieldName, StringComparison.OrdinalIgnoreCase)); if (isTargetField) { // 取字段存储值 object rawValue = pxCache.GetValue(currentRecord, fieldName); // 若需要取界面显示值,替换为以下代码: // PXFieldState fieldState = pxCache.GetValueExt(currentRecord, fieldName) as PXFieldState; // string displayValue = fieldState?.Text; fieldValues.Add(rawValue?.ToString() ?? string.Empty); } } } // 后续拼接外部URL、页面跳转逻辑可在此处实现 }
注意事项
- 原配置中的DAC名拼写有误:现场服务模块的预约主DAC类名为
FSAppointment,没有末尾的s,拼写错误会导致无法匹配到目标Cache - 字段匹配建议使用不区分大小写的等值比较,不要用
Contains方法,避免字段名部分重合导致的误匹配,例如同时存在CustomerID和CustomerIDLoc字段时会出现匹配错误 - 如果需要传递给外部系统的是界面展示的可读值(而非数据库存储的主键/编码值),请使用
GetValueExt方法取显示文本 - 后续替换为外部配置加载逻辑时,建议增加字段值类型配置项,标记每个字段是取存储值还是显示值,适配不同外部系统的参数要求
内容的提问来源于stack exchange,提问作者MarkJoel60
相关产品推荐
相关产品推荐

