维度关联字段介绍(开发向)原创
金蝶云社区-_Tmp
_Tmp
35人赞赏了该文章 8567次浏览 未经作者许可,禁止转载编辑于2020年05月22日 21:46:52
封面

维度关联字段是一个对基础资料的属性的补充属性字段,支持维度扩展,下面介绍下维度关联字段的工作逻辑。



一、当拖入一个维度关联字段配置好后,我们实际上关联了什么?

下图就是一个我们系统出厂的辅助属性字段配置以及其xml元数据显示,两个比较重要的属性,一个“维度关联字段”等价于该字段被维度关联字段控制,另一个维度数据表单则是我们这个问题要介绍的重点。

image.png

维度数据表单支持选择辅助属性、仓位、核算维度,我们能够通过元数据xml快速定位对应的关联数据表单的标识,如辅助属性——BD_FLEXSITEMDETAILV,仓位——BD_FLEXVALUESDETAIL,核算维度——BD_FLEXITEMDETAILV

image.png

得到了这个标识之后我们用这个标识在设计器中查找对应的业务对象,以辅助属性BD_FLEXSITEMDETAILV为例,查找之后得到一个很简单的界面,这时候我们需要找到对应的业务对象的叶子节点

image.png

得到这个我们先验证是否与系统的"辅助属性列表"上一致,你们可以对比下这里我就不提供截图了,然后我们很快就可以发现,辅助属性列表上的一个手工输入型属性,在这个辅助属性维度数据表单中就会用一个文本字段表示;一个辅助资料型属性,则会用一个单选辅助资料列表字段;一个基础资料型属性则会用一个基础资料字段标识。(可以验证在对应辅助属性列表增加属性,对应的这个表单是否动态增加字段,当然一定不能是在生产环境验证)

这里可以这么理解,我们的维度关联字段,针对其类型等价于我们关联了一个特定的基础资料,这个基础资料能够支持动态增加属性。



二、维度关联字段的数据库取数逻辑

在销售出库单中创建了一个测试数据如下:

image.png

首先我们在数据库中根据销售出库单单据头、单据体、辅助属性维度数据表的物料表得到一个这样的结果

image.png

对应关联的辅助属性维度数据的物理表T_BD_FLEXSITEMDETAILV的列可能我们难以理解,这时候我们回过头去看回辅助属性维度数据的业务对象,我们能够看到存在一个字段(文本、单选辅助资料列表、基础资料)的字段名与数据库列名一一对应,那么对应列上的值其实就是我们这个字段的值,文本就是文本值本身,单选辅助资料列表、基础资料则为对应关联业务对象的内码。

image.png



三、维度关联字段的数据包结构

针对维度关联字段位于明细信息表体,同时还作为一个复杂字段关联一个业务对象,因此其在表体数据包中与基础资料的结构类似,一个内码,一个复杂数据包

image.png

image.png

维度关联字段本身的数据包结构,其实就与我们读取的数据库结构一致

image.png

image.png



四、插件中的维度关联字段的重要属性

与基础资料BaseDataField一样,维度关联字段RelatedFlexGroupField需要加载其对应复杂对象的数据包,肯定依赖于一个动态实体类型DynamicObjectType。

与数据相关的属性RefFormDynamicObjectType,就是维度关联字段复杂数据包对应的动态实体类型image.png

与元数据相关的属性,

RelatedBaseDataFlexGroupField 维度关联字段标识

RelatedBDFlexItemLinkField 维度数据表单标识

RelatedFlexBusinessInfo 维度数据表单的完整元数据

image.png



五、前后端传输的维度关联字段子维度标识

还是销售出库单,辅助属性——等级这个字段在销售出库单元数据中是不存在的,而且像直接调拨单这种单据体存在两个相同维度数据表单标识一样的仓位字段(调入仓位、调出仓位),那么前后端以什么为标识区分维度关联字段的子维度的呢。

下面做一个小验证:

image.png

image.png

可以简单推测子维度标识为“$$维度关联字段标识__子维度标识”。



六、一个二开示例,修改直接调拨单的固定列的仓位标题,用作区分子维度仓位为调入仓位还是调出仓位

image.png

由于并非所有都需要加上字段区分,该表单上还存在一个辅助属性字段,如果都加上后会导致列宽过长或者无法看到列描述等,因此方案是针对同一个维度数据表单(也就是同一类维度字段,如仓位),存在大于等于两个的情况下才进行标题补充。

效果如下

image.png


image.png

public class TmpDynamicFormPlugIn: AbstractDynamicFormPlugIn
{
    public override void AfterBindData(EventArgs e)
    {
        var entryEntitys = this.View.BillBusinessInfo.Entrys.
            Where(x => x.ElementType == Kingdee.BOS.Core.Metadata.ElementMetadata.ElementType.ELEMENTTYPE_BILLBODY);
        foreach (var entity in entryEntitys)
        {
            //存在维度数据表单 固定列
            var flexGroupFields = entity.Fields.OfType<RelatedFlexGroupField>().
                Where(x=>x.BDFlexType!=null && x.FlexDisplayFormat == FlexType.Format.FIXEDCOLUMN);
            if (flexGroupFields.Count() <= 0)
                continue;
            var flexGroupFieldGroup = flexGroupFields.GroupBy(x => x.BDFlexType.FormId);//维度关联字段依据维度表单分组
            EntryGrid entryGrid = null;
            try                
            {                    
                entryGrid = this.View.GetControl(entity.Key) as EntryGrid;                
            }                
            catch { }
            if (entryGrid == null)
                continue;
            foreach (var groupItem in flexGroupFieldGroup)
            {
                if (groupItem.Count() <= 1)//针对同一类弹性域存在多个才进行标题修改
                    continue;
                foreach (var flexGroupField in groupItem)
                {
                    var flexGroupApp = this.View.LayoutInfo.GetAppearance(flexGroupField.Key) as RelatedFlexGroupFieldAppearance;
                    if (flexGroupApp == null)                            
                        continue;
                    var flexSubFieldApps = flexGroupApp.RelateFlexLayoutInfo.GetFieldAppearances();
                    foreach (var flexSubApp in flexSubFieldApps)
                    {
                        string colKey = string.Format("$${0}__{1}", flexGroupField.Key.ToUpper(), flexSubApp.Field.FieldName);
                        string caption = string.Format("{0}.{1}", flexGroupApp.Caption, flexSubApp.Caption);
                        entryGrid.UpdateHeader(colKey, caption);
                    }
                }
            }
        }           
    }
}
赞 35