05
2024
07
11:24:16

Python表达式常用技巧:遍历单据体获取数据,进行统计/加工/判断。

c9eda411ed5d6ad6fd926ced0d9f019d_0100a24c03ce1ea84a6282aa0eeb2ad8453a.jpg

金蝶云星空许多地方可以通过设置Python表达式来实现功能需求,无需写插件,无需重启系统,即刻生效,真的很香很好用。

支持设置Python表达式的地方有:实体服务规则、值更新事件服务、操作校验规则、各类前置条件、工作流设计器、流程配置中心启动条件、单据转换、反写规则等。

学好用好Python表达式,可以减少大量开发工作量,将有助于轻巧快速的解决问题。




  • 需求案例演示

本文,将以《销售订单》为例,试讲下列六项需求案例的实现:

(注:点击图片可放大清晰看)

需求案例1:获取单据体文本字段多行集合,以指定分隔符拼成单行文本,赋值给单据头文本字段。

b93a5bf7e7da3d48fc0ef26d7ff84a23_01002b5a72f9969c4f7f8d48f54aaea9f9f9.gif

需求案例2:获取单据体文本字段多行集合,去除其中重复值后,以指定分隔符拼成单行文本,赋值给单据头文本字段。


89588ab3e5e929e2ddea93466d925774_01007846d822ecbf41aca6a4ce33a936b072.gif

需求案例3:对单据体字段多行集合,进行判断,是否存在满足指定条件的行值。

a8e8b28ce8e2a688cf8f500926a3b80e_0100f37686a1cfac48b4917dc5b2f6a9004b.gif

需求案例4:对单据体字段多行集合,进行判断,是否全部行值均满足指定条件。


f217e68a5ebca2cd05bb7bff0f7c209f_0100f32c8be7fdf8403d8bf422a7458dd0fb.gif

需求案例5:对单据体字段多行集合,进行判断,是否行值完全一致。


a74960b681f0a948d9c37ade1015f526_010031e8158a4f914967852a998f313609a6.gif

需求案例6:获取单据体【基础资料/辅助资料字段】多行集合,取出【基础资料/辅助资料字段】.绑定实体属性(例如物料名称)的值集,以指定分隔符拼成单行文本,赋值给单据头文本字段。

426a76b7bc77caedebb3923dfa54824b_01009112261052764c18b9c64d076a439e44.gif

  注:例如获取基础资料-物料的名称,需要用.Name(名称字段绑定实体属性),而非.FName(名称字段标识)。



  • 实现步骤:

1.前期准备

    1.1 使用BOSIDE,在《销售订单》单据头(基本信息)上依次添加下列6个字段:

中文名称字段标识绑定实体属性字段类型
取单据体备注文本字段值集合FEntryFieldsCollectionFEntryFieldsCollection文本
是否存在ZF_ShiFouCunZaiZF_ShiFouCunZaiZ复选框
是否全部为ZF_ShiFouYiZhiWeiZF_ShiFouYiZhiWeiZ复选框
是否完全一致F_ShiFouWanQuanYiZhiF_ShiFouWanQuanYiZhi复选框
去除重复值F_QvZhongFuF_QvZhongFu复选框
取单据体物料基础资料的名称值集合FEntryBaseFieldsCollectionFEntryBaseFieldsCollection文本

    1.2 将以《销售订单》单据体(订单明细)上的备注字段(文本)、物料编码字段(基础资料)为例,通过配置字段值更新事件服务、实体服务规则,写Python表达式,来实现需求案例1至6。

2.需求案例1至需求案例5的实现步骤:

    2.1 如下图,设置单据体(订单明细)上的[备注字段]字段属性,“即时触发更新事件”勾选。

7f2a6219af4c1a0e348b44301ed91349_0100969c1b7c661f4436b5d867fd43550a82.png

    2.2 如下2图,在单据体(订单明细)上创建实体服务规则,前置条件设置为“需要触发单据头值更新事件的字段标识<>nul”,调用字段值更新服务,选中单据头自定义字段[取单据体备注文本字段值集合]。注:截图中多出来的两个字段标识,属于下节3.2涉及的内容,此处可忽略。

c87618676f310fa5dbdbc6969eb46d83_0100e85042e73e15469ea934f21356898d7b.png 

82153ee0efe4be5298534deb75fabb61_010036dab9edf7fb4d22abde41de5ff2554e.png

    2.3 设置单据头(基本信息)的[取单据体备注文本字段值集合]字段属性,取消勾选“即时触发更新事件”,添加"值更新事件",服务类型设为“计算定义公式的值并填写到指定列”,如下2图:

646765653934e8012dfb44530fcfc7ca_01009ea5cee4ead84af09d5d80a0b4881e1a.png

5b2ce888785f8b1c95c556e56a31c553_0100f20cc91319854ee0ac713f2c4cc89ad5.png

      2.3.1 前提条件中的Python表达式:

FEntryNote.Count>0

     2.3.2 具体定义公式Python表达式(注意,此处是本文精髓)

(注意,多行Pyhton表达式,每行首尾不能有空格;复杂表达式中,条件判断用==号不容易报错)


FEntryFieldsCollection=','.join(set(x for x in FEntryNote if x)) if F_QvZhongFu else ','.join(x for x in FEntryNote if x) F_ShiFouCunZaiZ=any(x=='Z' for x in FEntryNote) F_ShiFouYiZhiWeiZ=all(x=='Z' for x in FEntryNote) F_ShiFouWanQuanYiZhi=all(x and x==FEntryNote.TargetObjects[0] for x in FEntryNote)

  说明1:以上多行Python表达式,第1行对应需求案例1和2的实现;第2行对应需求案例3的实现;第3行对应需求案例4的实现;第4行对应需求案例5的实现。


  说明2:在单据头的实体服务规则中,字段标识FEntryNote,是个LazyCollection<Object,Object>懒加载对象,此对象可以简单理解为(String)Object对象的集合,每1行实际是1个String对象,每1行对象仅存放了该行FEntryNote字段的文本值(绝不含其他字段)。

  说明3:LazyCollection对象(例如FEntryNote)具有TargetObjects属性,可通过FEntryNote.TargetObjects[行号从0开始]属性,获取指定行号的(String)Object对象(例如上方代码中的FEntryNote.TargetObjects[0],表示访问单据体第1行FEntryNote字段的文本值);或者,可通过for in表达式遍历FEntryNote,遍历获取每行(String)Object对象(对应上方代码中的x)的文本值。


3.需求案例6的实现步骤:

    3.1 如下图,将单据体[物料编码]字段的属性“即时触发更新事件”勾选。

56e216c61b64a0538c7c1ee4569bf9ff_010019eef813477149399b96035176f8bb21.png


    3.2 此步骤已经在设置上文2.2项时,一并完成了,请详细参阅上文2.2。



    3.3 设置单据头(基本信息)的[取单据体物料基础资料的名称值集合]字段属性,取消勾选“即时触发更新事件”,添加"值更新事件",服务类型设为“计算定义公式的值并填写到指定列”,如下图:

308b0b3417be131f38205ba298ee949e_01006e7ef2658290478192c1c1cf53566f9f.png

     3.3.1 前提条件中的Python表达式:

FMaterialId.Count>0

     3.3.2 具体定义公式Python表达式(注意,此处是本文精髓)

    (注意,复杂表达式中,条件判断用==号不容易报错)


FEntryBaseFieldsCollection=','.join(set(x.Name for x in FMaterialId if x)) if F_QvZhongFu else ','.join(x.Name for x in FMaterialId if x)

  说明1:在单据头的实体服务规则中,FMaterialId是个LazyCollection<Object,DynamicObject>懒加载对象,此对象可以简单理解为DynamicObject对象的集合,每1行是1个DynamicObject对象,每1行对象仅存放了该行FMaterialId字段的数据包(绝不含其他字段)。

  说明2:LazyCollection对象(例如FMaterialId)具有TargetObjects属性,可通过FMaterialId.TargetObjects[行号从0开始]属性,获取指定行号的DynamicObject对象;或者,可通过for in推导式遍历FMaterialId,遍历获取每行DynamicObject对象(对应上方代码中的x,代表每行FMaterialId字段的DynamicObject对象数据包)。

  说明3:最后,需要注意,访问DynamicObject对象的属性值,需要用.【绑定实体属性】名(也叫ORM实体名),例如获取“物料.名称”,需要用到“物料”基础资料中名称字段的【绑定实体属性】名,如下图所示,所以,正确的写法是x.Name,而非x.FName。

ec7c860e3c54bbbe799268bb2518040a_010005ed3d1268c746069b23092c61b55c8e.png




  • 知识点及帮助理解


       1.有小伙伴反馈,直接复制我的代码修改字段名使用,一直报错 ( unexpected token ' ' )。经测试发现,是因为从金蝶云社区复制过去的代码,代码中的空格变得有问题。解决方案:纯手工敲代码及空格,就不会问题;或者,可以把复制的代码中的每1个空格都删除再重新手敲空格,经测试也是可以的,但注意一定要确保每1个空格都重新手敲了。 


       2. Python列表推导式及生成器推导式的用法详解 :

           https://www.cnblogs.com/mingmingming/p/11055282.html


       3.在Python条件判断中,凡是被放置在条件判断位置的对象,如果为【''、0、False、null、[]、None、()、{}】,则直接视为False(假)。所以,在上述代码中,【… if x …】代表【过滤掉空对象(空行)】,【all(x and …】代表【x如果为空对象返回False,x如果不为空对象返回True;并且(and),还需要满足…条件】。


       4.理解Python三目运算符(或称三元表达式)

           https://vip.kingdee.com/link/s/MU12r


       未完待续。

       小伙伴先行尝试实践与理解一下,实在有不明白的地方,可以回贴评论留言,详细说明你遭遇的问题、你的疑惑,我会抽空时间解答(并完善此贴)。

       欢迎高质量提问,你们若不提问,由于涉及的知识点太多了,我一时半会也不知道从哪里讲起、怎么讲,总之,还是需要大家给我提供灵感。



       附件《销售订单Python表达式应用:遍历单据体获取数据进行统计、加工、判断.zip》,是基于7.6.2122.7(2021年3月份版本)的蓝海演示数据中心的销售订单扩展部署包,大家可以下载后部署到测试环境观摩学习,也许更加直观。


       另外,小伙伴们,若还有其他比较经典的Python表达式实现需求,也请图文并茂、清晰明了的描述在本贴下方,只要是能用Python表达式实现的需求,我将会挑选其中确实典型的需求,实现它,并且另开一贴来讲述怎么实现它。


销售订单Python表达式应用:遍历单据体获取数据进行统计、 …(32.25KB)





推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

本文链接:https://hqyman.cn/post/6987.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: