
【场景】格式化单据上的基础资料的弹性域字段,与单据界面保持一致
【说明】没有必要最好不要这么做,需要模拟物料界面才能得到真实的格式化
【案例】打印采购入库单上的物料的仓位
(0)数据准备,演示效果


(1)套打模板准备,增加动态字段

(2)表单插件

```csharp
using Kingdee.BOS;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DynamicFormPlugIn.NotePrint
{
[Kingdee.BOS.Util.HotUpdate]
public class NotePrintPlugIn_FormatInnerFlex : AbstractBillPlugIn
{
/*
* 单据套打格式化基础资料中的弹性域字段
* 案例:采购入库单,格式化 物料中的仓位字段
*/
public override void OnPrepareNotePrintData(PreparePrintDataEventArgs e)
{
//明细时生效
if (!string.Equals(e.DataSourceId, "FInStockEntry", StringComparison.OrdinalIgnoreCase))
return;
if (e.DataObjects.Length <= 0)
return;
//判断是否有目标字段
string targetKey = "WL_CWZ";
string srcKey = "FMaterialId_Ref";
if (!e.DataObjects[0].DynamicObjectType.Properties.ContainsKey(srcKey))
return;
if (!e.DataObjects[0].DynamicObjectType.Properties.ContainsKey(targetKey))
return;
FlexFormatHelper helper = new FlexFormatHelper(this.Context, "BD_Material", "FStockPlaceId");
foreach (var rowObj in e.DataObjects)
{
DynamicObject wlObj = rowObj[srcKey] as DynamicObject;
if (wlObj == null)
continue;
object wlId = wlObj[0];
// 使用物料内码取值,会加载完整数据包,如果你的数据包中包含仓库和仓位,可以直接传入
var formatVal = helper.GetValueByPkId(wlId);
//var formatVal = helper.GetValueByDataObj(wlObj);
rowObj[targetKey] = formatVal;
}
}
}
public class FlexFormatHelper
{
private readonly Context QueryCtx;
private readonly string FormId;
/// <summary>
/// 元数据
/// </summary>
private FormMetadata formMetadata;
/// <summary>
/// 弹性域字段的关联字段
/// </summary>
private BaseDataField baseDataField;
/// <summary>
/// 弹性域字段
/// </summary>
private RelatedFlexGroupField flexField;
/// <summary>
/// 弹性域字段
/// </summary>
private RelatedFlexGroupFieldAppearance flexFieldApp;
private IDynamicFormView view;
private IDynamicFormView FormatView
{
get
{
if(view == null)
{
view = CreateView(QueryCtx);
}
return view;
}
}
public FlexFormatHelper(Context ctx, string formId, string fieldKey)
{
QueryCtx = ctx;
FormId = formId;
formMetadata = Kingdee.BOS.ServiceHelper.MetaDataServiceHelper.Load(QueryCtx, FormId) as FormMetadata;
if (formMetadata == null)
throw new Exception("formId error");
flexField = formMetadata.BusinessInfo.GetField(fieldKey) as RelatedFlexGroupField;
if (flexField == null)
throw new Exception("fieldKey error");
baseDataField = formMetadata.BusinessInfo.GetField(flexField.RelatedBaseDataFlexGroupField) as BaseDataField;
if(baseDataField == null)
throw new Exception("fieldKey error");
flexFieldApp = formMetadata.GetLayoutInfo().GetFieldAppearance(flexField.Key) as RelatedFlexGroupFieldAppearance;
}
/// <summary>
/// 传入基础资料内码得到格式化后的值
/// </summary>
/// <param name="pkid"></param>
/// <returns></returns>
public object GetValueByPkId(object pkid)
{
var pkIds = new object[] { pkid };
var dataObj = Kingdee.BOS.ServiceHelper.BusinessDataServiceHelper.Load(QueryCtx, pkIds, formMetadata.BusinessInfo.GetDynamicObjectType());
if (dataObj == null || dataObj.Length <= 0)
return null;
return GetValueByDataObj(dataObj[0]);
}
/// <summary>
/// 传入基础资料数据包得到格式化后的值,方便外层做缓存,避免频繁取数
/// </summary>
/// <param name="pkid"></param>
/// <returns></returns>
public object GetValueByDataObj(DynamicObject dataObj)
{
if (dataObj == null)
return null;
DynamicObject baseDataObj = GetFieldObj(dataObj, baseDataField) as DynamicObject;
DynamicObject flexObj = GetFieldObj(dataObj, flexField) as DynamicObject;
if (baseDataObj == null || flexObj == null)
return null;
return GetValueNew(flexObj, baseDataObj, FlexType.EnumDisplayNameSpecies.NAME);
}
/// <summary>
/// 获取数据包中的字段值
/// </summary>
/// <param name="dataObj"></param>
/// <param name="field"></param>
/// <returns></returns>
private object GetFieldObj(DynamicObject dataObj, Field field)
{
var entity = field.Entity;
if(field.Entity is HeadEntity)
{
if(dataObj.DynamicObjectType.Properties.ContainsKey(field.PropertyName))
{
return field.DynamicProperty.GetValue(dataObj);
}
}
else if(field.Entity is SubHeadEntity)
{
if (!dataObj.DynamicObjectType.Properties.ContainsKey(entity.EntryName))
return null;
DynamicObjectCollection subEntityObjs = dataObj[entity.EntryName] as DynamicObjectCollection;
if (subEntityObjs == null || subEntityObjs.Count <= 0)
return null;
DynamicObject rowObj = subEntityObjs[0];
if(rowObj.DynamicObjectType.Properties.ContainsKey(field.PropertyName))
{
return field.DynamicProperty.GetValue(rowObj);
}
}
return null;
}
/// <summary>
/// 新版取值,支持多语言类型返回
/// </summary>
/// <param name="flexValue"></param>
/// <param name="baseDataObj"></param>
/// <param name="displayType"></param>
/// <returns></returns>
private object GetValueNew(DynamicObject flexValue, DynamicObject baseDataObj,
FlexType.EnumDisplayNameSpecies displayType = FlexType.EnumDisplayNameSpecies.CODEANDNAME)
{
List<string> orderFields = GetDisplayOrderSubFieldList(baseDataObj);
//取定义的显示顺序
bool hasLocale = false;
List<object> displayList = new List<object>();
foreach (var flexSubFieldKey in orderFields)
{
Field flexSubField = flexField.RelateFlexBusinessInfo.GetField(flexSubFieldKey);
object flexSubVal = GetValueSingleNew(flexValue, flexSubField, displayType);
if (flexSubVal == null || flexSubVal.IsNullOrEmptyOrWhiteSpace())
continue;
if (flexSubVal is LocaleValue)
hasLocale = true;
displayList.Add(flexSubVal);
}
if (!hasLocale)
return string.Join(flexField.BDFlexType.Separator, displayList);
LocaleValue printLocaleValue = FormatLocaleVal(displayList);
return new List<LocaleValue>() { printLocaleValue };
}
/// <summary>
/// 获取单一维度的值
/// </summary>
/// <param name="flexValue">维度数据包</param>
/// <param name="subFlexField">子维度字段</param>
/// <param name="displayType">显示类型(仅针对基础资料型)</param>
/// <returns></returns>
private object GetValueSingleNew(DynamicObject flexValue, Field subFlexField,
FlexType.EnumDisplayNameSpecies displayType)
{
if (subFlexField == null || subFlexField.PropertyName.IsNullOrEmptyOrWhiteSpace())
return null;
if (!flexValue.DynamicObjectType.Properties.ContainsKey(subFlexField.PropertyName))
return null;
object flexSubVal = flexValue[subFlexField.PropertyName];
BaseDataField subFlexLookUpField = subFlexField as BaseDataField;
if (subFlexLookUpField != null)
{
DynamicObject flextSubObj = flexSubVal as DynamicObject;
if (flextSubObj == null)
return null;
flexSubVal = GetFlexSubVal(flextSubObj, subFlexLookUpField, displayType);
}
return flexSubVal;
}
/// <summary>
/// 获取基础资料型子维度值(编码、名称、类型名称、编码名称)
/// </summary>
/// <param name="flexSubObj"></param>
/// <param name="subFlexLookUpField"></param>
/// <param name="displayType"></param>
/// <returns></returns>
private object GetFlexSubVal(DynamicObject flexSubObj, BaseDataField subFlexLookUpField,
FlexType.EnumDisplayNameSpecies displayType)
{
object val;
object flextName;
LocaleValue flexNameLocaleVal;
switch (displayType)
{
case FlexType.EnumDisplayNameSpecies.NAME:
val = GetFlexSubName(flexSubObj, subFlexLookUpField);
break;
case FlexType.EnumDisplayNameSpecies.CODE:
val = GetFlexSubNumber(flexSubObj, subFlexLookUpField);
break;
case FlexType.EnumDisplayN