【第14期】金蝶云·星空-协同开发 | 产品应用典型/热门问答精选 2023年11月发布原创
金蝶云社区-OUT_MAN
OUT_MAN
141人赞赏了该文章 968次浏览 未经作者许可,禁止转载编辑于2024年01月27日 10:27:00
封面

各位社区的小伙伴们,大家好,我是  版主 OUT_MAN


在金蝶云·星空-协同开发产品应用中,你需要了解的典型/热门问答都在这里!  

本帖每月持续更新,欢迎小伙伴们点赞,收藏本帖,CTRL+F关键词搜索,以便随时查看、扩充知识哟


【第14期】

  更新日期:2023-11



1、 下推后调用BusinessDataServiceHelper.Save 和展示单据为何结果不同?

问题描述:
我在下推后对明细单基础资料和数值进行赋值,展示单据能看到值,但直接保存再去单据中查看是空的,并且数值有值,基础资料没值,是为啥?大佬指教,数值文本都行,直接展示基础资料也有值,就是直接保存基础资料为空???

image.png

解决方案:

基础资料赋值 要分别对ID和对象赋值

改成:

 //基础资料赋值
    var COSTID = (BaseDataField)targetBInfo.GetField("FCOSTID");
    var dys = BusinessDataServiceHelper.LoadFromCache(this.Context, new object[] { dt.Rows[i]["FCOSTID"].ToString() }, COSTID.RefFormDynamicObjectType);
    //增加
       ((DynamicObject)((DynamicObjectCollection)((DynamicObject)targetObjs[0])["REFUNDBILLENTRY"])[i])["FCOSTID_Id"] = dt.Rows[i]["FCOSTID"];
       
    ((DynamicObject)((DynamicObjectCollection)((DynamicObject)targetObjs[0])["REFUNDBILLENTRY"])[i])["FCOSTID"] = dys[0];

问题来源:https://vip.kingdee.com/link/s/lAGqK


2、 通过二开插件自动下推,获取到下推后的数据包,如何对下推后生成的单据字段赋值?

问题描述:
我知当前单据赋值用this.Model.SetValue就行,但对下推后的数据包,请指教,

private void Push(string pushCate,string pushId,string targetId,string formId) {

    OperateOption pushOption = OperateOption.Create();//操作选项
    var pushArgs = this.CreatePushArgs(pushOption,pushCate,pushId,targetId,formId); //构建下推参数
    var convertResult = ConvertServiceHelper.Push(this.Context, pushArgs, pushOption);//调用下推接口



    var targetObjs = (from p in convertResult.TargetDataEntities select p.DataEntity).ToArray();//得到目标单据数据包
    var targetBInfo = this.GetBusinessInfo(pushArgs.ConvertRule.TargetFormId, pushArgs.ConvertRule.TargetFormMetadata);



    var saveResult =  BusinessDataServiceHelper.Save(this.Model.Context, targetBInfo, targetObjs);
    

    if (!saveResult.IsSuccess)
    {
        var errorInfo = string.Join(";", saveResult.ValidationErrors.Select(x => x.Message));
        this.View.ShowErrMessage(errorInfo);
        return;
    }
    else
    {
        this.View.ShowMessage("保存成功");
    }


    }

解决方案:

image.png

// 获取生成的目标单据数据包

            DynamicObject[] objs = (from p in operationResult.TargetDataEntities

                                    select p.DataEntity).ToArray();

         

            int i = 0;

            // var list = datas.ToList<Object>()

 //单据头

            ((DynamicObject)objs[0])["F_Remark"] = str;

            ((DynamicObject)objs[0])["F_InspectionStatus"] = status;

            foreach (var data in datas)

            {

//单据体

                    ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])["PRD_MORPTENTRY"])[i])["FinishQty"] = Convert.ToDecimal(data["FQTY"].ToString());

                    ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])["PRD_MORPTENTRY"])[i])["BaseFinishQty"] = Convert.ToDecimal(data["FQTY"].ToString());

                 i++;

            }

问题来源:https://vip.kingdee.com/link/s/lAY8I        


3、 公有云补丁在更新,因特殊原因等不了更新。如何能联系总部撤销补丁更新。

问题描述:
公有云补丁在更新,因特殊原因等不了更新。如何能联系总部撤销补丁更新

解决方案:

补丁安装后无法回退,只能用在安装补丁前做好的备份恢复。安装前的准备工作:

  • 备份数据库打补丁前需要先对数据库进行备份,包括:管理中心库和业务中心库。管理中心库的备份需要在数据库上进行,业务库的备份可以登录Cloud管理站点进行备份。

  • 检查业务数据中心检查业务数据中心是否都可连接,如果是多个应用服务器,请检查所有的应用服务器,确定都可正常使用。如果有多余的业务库,请登录管理中心反注册;如果有多余的站点,请调整管理中心相关配置文件,去掉这个多应用服务器。多应用服务器涉及到的配置,请查阅:如何配置应用服务器集QUN

  • 关闭360软件建议先关闭360等杀毒软件,或者设置白名单,允许Cloud相关的操作,不要对其进行拦截。

  • 确定服务未断请查看Internet信息服务(IIS)管理器,确保应用程序池中的K/3Cloud各服务未断。

问题来源:https://vip.kingdee.com/link/s/lAf2q        


4、 Python在单据保存时把更改的辅助资料值,更新供应商的辅助资料值

问题描述:
一直提示:实体类型BillHead中不存在名为FBillHead的属性

原码如下

import clr
clr.AddReference("System")
clr.AddReference("System.Core")
clr.AddReference("Kingdee.BOS")
clr.AddReference("Kingdee.BOS.App")
clr.AddReference("Kingdee.BOS.Core")
clr.AddReference("Kingdee.BOS.DataEntity")
clr.AddReference("Newtonsoft.Json")
clr.AddReference("Kingdee.BOS.ServiceHelper")
from Kingdee.BOS.Util import *
from Kingdee.BOS.Core.DynamicForm import *
from Kingdee.BOS.Core.DynamicForm.PlugIn import *
from Kingdee.BOS.Core.DynamicForm.PlugIn.Args import *
from Kingdee.BOS.Core.Metadata.FormElement import *
from Kingdee.BOS.App.Data import *
from System import *
from System.Linq import *
from System.Text import *
from Newtonsoft.Json import *
from Newtonsoft.Json.Linq import *
from Kingdee.BOS.ServiceHelper import *

def AfterExecuteOperationTransaction(e):
  obj = e.DataEntitys;
  _FEntity=obj[0]["FBillHead"]  #获取单据明细表
  #raise NameError(JsonConvert.SerializeObject(obj)); #用于查看数据结构 方便取值使用
  for item in _FEntity :
    FSIGNCOMP= item["FSIGNCOMP"];#合同签订主体
    FSUPPLIERID=item["F_WAPC_BASE12"];#供应商ID
   
    if FSIGNCOMP is not None
      #更新基础资料 
      _UpdateSql="/*dialect*/ UPDATE T_BD_SUPPLIER set  F_WAPC_ASSISTANT = {0} where FSUPPLIERID = {1}".format(FSIGNCOMP,FSUPPLIERID);
      DBUtils.Execute(this.Context,_UpdateSql);
      ClearCache(FSUPPLIERID);#清除缓存资料

def ClearCache(ID):
  #缓存清理
  FORMID="BD_SUPPLIER";#基础资料的表单ID
  completaMetadata = MetaDataServiceHelper.Load(this.Context,FORMID);
  pkList = [-1];
  pkList[0] = ID;
  BusinessDataServiceHelper.ClearCache(this.Context, completaMetadata.BusinessInfo.GetDynamicObjectType(), pkList);
  CacheUtil.ClearCache(this.Context.DBId + FORMID, "BOS_QuickBaseDataCache");

解决方案:

获取数据包的方法不对啊!AfterExecuteOperationTransaction读取单据数据包代码参考:

for exBillData in e.SelectedRows:#循环每一张单据
    billObj=exBillData.DataEntity;#单据的数据包,最外层,单据头字段可直接从这里面获取
    en=billObj["单据体ORM实体属性标识"];#获取单据体数据的集合
    for r in en:#循环单据体的每一行
        XXX=r["单据体字段实体属性标识"];#获取单据体的字段

数据包层层解析参考这个:【Python插件入门】第3篇:插件中如何进行数据操作

image.png

问题来源:https://vip.kingdee.com/link/s/lAfUk        


5、 操作服务插件,如果操作是在列表勾选单据体后发起的,校验器的Validate方法里如何获取勾选的单据体?

问题描述:
操作服务插件,在OnAddValidators添加校验器后,指定校验的是单据体,如validator.EntityKey = "FPOOrderEntry",假如单据列表界面,有2个单据,单据A(2条明细:序号1,2),单据B(3条明细:序号3,4,5),如果勾选单据A的序号1的明细,加上单据B序号3的明细,发起操作,经调试发现校验器        
public override void Validate(ExtendedDataEntity[] dataEntities, ValidateContext validateContext, Context ctx)
方法里dataEntities是已勾选的单据A和单据B的所有明细集合(即1,2,3,4,5),并不是已勾选的明细集合(1,3)。请问如果我只想获取已勾选的明细,该如何操作?在

解决方案:

using Kingdee.BOS.Core.DynamicForm 


public override void BeforeExecuteOperationTransaction(BeforeExecuteOperationTransaction e)

        {

            base.BeforeExecuteOperationTransaction(e);

            var selectedRows = this.Option.GetBillOperationSelectedRows();

}

问题来源:https://vip.kingdee.com/link/s/lAfN3        


6、 操作服务插件,能否区分是在列表发起的,还是表单发起的?

问题描述:
操作服务插件,BeforeExecuteOperationTransaction函数里,有什么办法能区分,当前操作是在单据列表通过勾选单据体发起的(对应BOS列表菜单)? 还是打开具体某个单据后,在表单里发起的?(对应BOS菜单集合)

解决方案:

操作插件里面应该是没有办法直接获取的,

思路1  通过获取父窗体试试

思路2  可以尝试用下面的方法

单据插件中用:

    e.Option.SetVariableValue("isList", "yes");

服务插件用:

    if (this.Option.ContainsVariable("isList"))

                {

                    islist= this.Option.GetVariables()["isList"].ToString();

                }

问题来源:https://vip.kingdee.com/link/s/lAfiS        


7、 Python列表插件,获取不到客户的客户名称,要如何写?经测试获取不到FCustId

问题描述:
Python列表插件,获取不到客户的客户名称,要如何写?经测试获取不到FCustId

#引入clr运行库
import clr
#添加对cloud插件开发的常用组件的引用
clr.AddReference('System')
clr.AddReference('System.Data')
clr.AddReference('Kingdee.BOS')
clr.AddReference('Kingdee.BOS.Core')
clr.AddReference('Kingdee.BOS.App')
clr.AddReference('Kingdee.BOS.ServiceHelper')
#导入cloud基础库中的常用实体对象(分命名空间导入,不会递归导入)
from Kingdee.BOS import *
from Kingdee.BOS.Core import *
from Kingdee.BOS.Core.Bill import *
from Kingdee.BOS.Core.DynamicForm.PlugIn import *
from Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel import *
from System import *
from System.Data import *
from Kingdee.BOS.App.Data import *
from System.Collections.Generic import List
from Kingdee.BOS.ServiceHelper import *

def OnFormatRowConditions(args):
    if(args.DataRow.DynamicObject.DynamicObjectType.Properties.ContainsKey("FDELIVERYDATE")
    and args.DataRow.DynamicObject.DynamicObjectType.Properties.ContainsKey("F_RZ_DATE")
    and args.DataRow.ColumnContains("FCustId")):
        #这里是普通字段作为判断,需要判断列表是否显示了该字段,否则没显示该字段时会报错
        #而且只有显示了这个字段才能判断设置颜色
        FDELIVERYDATE=str(args.DataRow["FDELIVERYDATE"]);#要货日期
        F_Rz_Date=str(args.DataRow["F_RZ_DATE"]);#出库日期
        matObj=args.DataRow.DynamicObject["FCustId"];#客户ID 凤铝ID:221093
        FCustName = ("{0}").format(matObj["FName"])
        #凤铝全称:佛山市三水凤铝铝业有限公司
        t1=DateTime.Parse(FDELIVERYDATE);
        current =DateTime.Now.Date.ToString();
        t2=DateTime.Parse(str(current));
        ts=t1-t2;
        sub=ts.Days;
        ck=len(str(F_Rz_Date));
        this.View.ShowMessage(FCustName);
        this.View.ShowMessage("销售订单");
        if(sub<= 0 and ck==4 and FCustName!="佛山市三水凤铝铝业有限公司"):
            fc=FormatCondition();
            #fc.ForeColor="#FFFF9B98";#前景色
            fc.BackColor="#FE2C2C";#背景色 红色
            #fc.BackColor="#FEB82C";#背景色 黄色
            args.FormatConditions.Add(fc);
        if(sub<= 0 and ck==4 and FCustName=="佛山市三水凤铝铝业有限公司"):
            fc=FormatCondition();
            #fc.ForeColor="#FFFF9B98";#前景色
            fc.BackColor="#ADD8E6";#背景色 浅蓝色
            #fc.BackColor="#FEB82C";#背景色 黄色
            args.FormatConditions.Add(fc);

解决方案:

不是这样写的。客户是基础资料字段,要取基础资料属性的话是要这样写:

if (args.DataRow.ColumnContains("FCustId_Ref"))
    custObj=args.DataRow.DynamicObject["FCustId_Ref"];#客户引用数据包
    custName=("{0}").format(custObj["Name"]);#取客户名称

我这文章里面不是强调了吗?没看懂??【Python插件入门】第5篇:单据列表插件

image.png

问题来源:https://vip.kingdee.com/link/s/lAfnz        


8、 启用工作流的单据,如何限制反审核与审核人必须是同一人

问题描述:
启用工作流的单据,如何限制反审核与审核人必须是同一人

解决方案:

可以试一下用管理员用户登录,选对应的角色,在业务对象功能授权的业务对象里,设置反审核的数据范围:

审核人为当前用户

看能否实现。

image.png

问题来源:https://vip.kingdee.com/link/s/lAfnE        



我创建了<<协同开发,轻松入门>>的学习清单,推荐给你,和我一起学习交流吧!

<<协同开发,轻松入门>>


查看往期精选:

【汇总】金蝶云·星空-协同开发 | 产品应用典型/热门问答精选






赞 141