学习金蝶星空云平台插件二次开发记录博客

49 阅读10分钟

金蝶二开常用方法

一、表单插件

一、表单插件开发基础方法

1、获取单据标题 this.View.GetFormTitle()

// 获取单据标题
string FormTitle = this.ViewGetFormTitle();
// 将单据标题显示到备注框上
this.View.Model.SetValue("FNote", FormTitle);

2、获取当前单据的Fid内码(也就是当前表单对应的数据库表)this.View.Model.DataObject和this.View.Model.GetPKValue

第一种方法:

// 获取单据内码Fid
string FormTitle = this.View.Model.DataObject["Id"].ToString();
// 显示到备注框上
this.View.Model.SetValue("FNote", FormTitle);
// 通过GetPKValue方法获取Fid内码
string FornTitle = this.View.Model.GetPKValue().ToString();
// 显示到备注上,赋值给备注框
this.View.Model.SetValue("FNote",FormTitle);

第二种方法:

// 获取单据内码Fid
string FormTitle = this.View.Model.GetPKValue().ToString();
// 显示到备注框上
this.View.Model.SetValue("FNote", FormTitle);

3、设置焦点

应用的业务场景有以下这些:

1、设置焦点,例如设置了必录项,没填,自动跳转到必录项上面,判断哪些值没有录入;

2、条码扫描,固定在一个焦点;

// 获取焦点到备注上(打开销售订单,点按钮,鼠标光标跳到备注上面)
this.View.GetControl("FNote").SetFocus();

4、锁定、隐藏,字段

// 锁定备注字段
this.View.GetControl("FNote").Enable = false;
// 扩展,行锁定字段(锁定单据里面的某一行)
this.View.GetControl("FEntryNote",0).Enable = false;
// 隐藏备注字段
this.View.GetControl("FNote").Visible = false;

5、锁定、隐藏,按钮

// 锁定保存按钮
this.View.GetMainBarItem("tbSplitSave").Enabled = false;
// 隐藏保存按钮
this.View.GetMainBarItem("tbSplitSave").Visible = false;

6、刷新前台页面

// 前台刷新,异步,不与服务器交互
this.View.UpdateView("FNote");
// 整个页面都刷新,与服务器交互,获取数据库数据
this.View.Refresh();

7、调用表单事件

// 调用保存事件 除了save还会有其他的事件
this.View.InvokeFormOperation("Save");

二、常用的单据体属性

1、单据体的点击事件重写

public override void EntryBarItemClick(BOS.Core.DynamicForm.PlugIn.Args.BarItemClickEventArgs e)
{
    // 这里判断一下是否为新加的按钮,是的话就执行以下操作
    if(e.BarItemKey.Equals("YDIE_tbTest"))
    {
        
    }
    base.EntryBarItemClick(e);
}

2、常用的单据体、表单插件属性

// 删除单据体信息
this.View.Model.DeleteEntryData("FSaleOrderEntry");
// 刷新,单据体界面
this.View.UpdateView("FSaleOrderEntry");

3、逐行删除单据体信息

// 逐行删除单据提分录,0代表着第一行
this.View.Model.DeleteEntryRow("FSaleOrderEntry",0);

4、创建和复制单据提新行

新增行的业务场景:从后台创建行,写入数据

// 新建一行,行内数据为FSaleOrderEntry
this.View.Model.CreateNewEntryRow("FSaleOrderEntry");

复制行的业务场景:从后台复制行,复制数据

// 参数说明,0代表第一行,1代表复制的行数(这里是复制第二行),false代表不携带源单关系
// 源单关系解释:源订单和关联订单之间的关系。在电商或供应链管理中,源单通常指原始的购买订单,而关联订单可能包括退款、分单、合并单等操作产生的订单。这里不携带源单关系也就是说没有源单
this.View.Model.CopyEntryRow("FSaleOrderEntry",0,1,false)

5、获取单据体FENTRYID内码

// 获取单据体的第一行到第三行的内码
this.View.Model.GetEntryPKValue("FSaleOrderEntry",0);
this.View.Model.GetEntryPKValue("FSaleOrderEntry",0);
this.View.Model.GetEntryPKValue("FSaleOrderEntry",0);

// 用SetValue()赋值给新增的字段F_YDIE_EntryID
this.View.Model.SetValue("F_YDIE_EntryID",this.View.Model.GetEntryPKValue("FSaleOrderEntry", 0),0);
this.View.Model.SetValue("F_YDIE_EntryID",this.View.Model.GetEntryPKValue("FSaleOrderEntry", 1),1);               
this.View.Model.SetValue("F_YDIE_EntryID",this.View.Model.GetEntryPKValue("FSaleOrderEntry", 2),2);

6、获取单据体行数

// 获取单据提行数方法
var count1 = this.View.Model.GetEntryRowCount("FSaleOrderEntry");
// 将行数set到FNote里面
this.View.Model.SetValue("FNote",count1);

7、Context属性

Context属性,上下文,记录一些公用的信息,比如当前登陆用户、组织、连接的数据库、区域等等信息

public override void BarItemClick(BarItemClickEventArgs e)
{
    base.BarItemClick(e);
    
    if(e.BarItemKey == "YDIE_tbTest")
    {
      this.View.Model.SetValue("F_YDIE_Text", Convert.ToString(this.Context.CurrentOrganizationInfo.ID));
      this.View.Model.SetValue("F_YDIE_Text1", Convert.ToString(this.Context.CurrentOrganizationInfo.Name));
      this.View.Model.SetValue("F_YDIE_Text2", Convert.ToString(this.Context.CurrentUserTimeZone));
      this.View.Model.SetValue("F_YDIE_Text3", Convert.ToString(this.Context.DatabaseType));
      this.View.Model.SetValue("F_YDIE_Text4", Convert.ToString(this.Context.IsMultiOrg));
      this.View.Model.SetValue("F_YDIE_Text11", Convert.ToString(this.Context.UserId));
      this.View.Model.SetValue("F_YDIE_Text31", Convert.ToString(this.Context.UserName));
      this.View.Model.SetValue("F_YDIE_Text41", Convert.ToString(this.Context.DBId));
      this.View.Model.SetValue("F_YDIE_Text21", Convert.ToString(this.Context.UserEmail));
      this.View.Model.SetValue("F_YDIE_Text5", Convert.ToString(this.Context.UserPhone));
        
        
       // 刷新
        this.View.UpdateView();
    }
}

8、ListShow属性(选单)

调用ListShow属性,点击按钮的时候回弹框,弹出指定的单据的列表,进行选单

public override void BarItemClick(BOS.Core.DynamicForm.PlugIn.Args.BarItemClickEventArgs e)
{
    base.BarItemClick(e);
    if(e.BarItemKey == "YDIE_tbTest")
    {
        // 定义一个字段
        ListShowParameter listShowParameter = new ListShowParameter();
        // FromId是你需要调用的单据列表的标识
        listShowParameter.FormId = "SAL_SaleOrder";
        
        // 设置只显示基本信息
        listShowParameter.ListType = Convert.ToInt32(BOSEnums.Enu_ListType.BaseList);
        
        // 设置全部显示(默认全部显示)
        listShowParameter.ListType = Convert.ToInt32(BOSEnums.Enu_ListType.List);
        
        // 是否显示复选框。默认是true
        listShowParameter.MultiSelect = false;
        
        // 接受返回值,默认可以这么写
        //this.View.ShowForm(args);
        // 传result返回
       this.View.ShowForm(listShowParameter,delegate(FormResult result){
           //读取返回值
       });
    }
}

9、打开外部页面

public override void BarItemClick(BOS.Core.DynamicForm.PlugIn.Args.BarItemClickEventArgs e)
{
    base.BarItemClick(e);
	if(e.BarItemKey ==("YDIE_tbTest"))
    {
        JSONObject webobj = new JSONObject();
        webobj["source"] = @"http://www.baidu.com";
        webobj["height"] = 600;
        webobj["width"] = 910;
        
        //是否为新窗口打开
        webobj["isweb"] = true;
        
        webobj["title"] = "百度";
     this.View.AddAction("ShowKDWebbrowseForm",webobj);
        this.View.SendAynDynamicFormAction(this.View);

    }
}

三、提示信息框

1、常用的弹窗函数

this.View.ShowMessage("你好");

2、错误信息框

this.View.ShowErrMessage("严重错误");

3、询问提示框(YES|NO)

// 使用这个提示框需要先添加引用
using Kingdee.BOS.Core.DynamicForm;

this.View.ShowMessage("错误提示,是否继续?",MessageBoxOptions.YesNO,
                     new Action<MessageBoxResult>(() => {
                         if(result == MessageBoxResult.Yes){
                             // 如果选择是,则将“是”赋值给FNote
                             this.View.Model.SetValue("FNote","是");
                         }else if(result == MessageBoxResult.No){
                             this.View.Model.SetValue("FNote","否");
                         }else if(result == MessageBoxResult.Cancel){
                             this.View.Model.SetValue("FNote","取消");
                         }
                     }));
//刷新一下备注
this.View.UpdateView("FNote");

4、警告式提示框

// 警告式提示框
this.View.ShowWarinningMessage("不能对其操作,请确认",action(result) =>{
    //关闭页面
    this.View.Close();
})

5、处理结果信息提示框

// 先引用
using Kingdee.BOS.Core.DynamicForm;

// 成功状态下的提示
IOperationResult opResult = new OperationResult();
opResult.OperateResult.Add(new OperateResult(){
	Name = "信息提示",
	Message = "成功",
	SuccessStatus = true
});
this.View.ShowOperateResult(opResult.OperateResult);


// 失败状态下的提示
opResult.OperateResult.Add(new OperateResult(){
	Name = "信息提示",
	Message = "失败",
	SuccessStatus = false
});
this.View.ShowOperateResult(opResult.OperateResult);

处理结果

更改上述代码,实现以下效果,在序号为单数的时候成功,在序号为双数的时候失败

// 先引用
using Kingdee.BOS.Core.DynamicForm;

IOperationResult opResult = new OperationResult();

for(int i = 0; i < 20; i++){
    if(Convert.ToBoolean(i%2)){
        opResult.OperateResult.Add(new OperateResult(){
            Name = "信息提示",
            Message = i.ToString()+"----奇数成功",
            SuccessStatus = true
    	});
    }else{
            opResult.OperateResult.Add(new OperateResult(){
            Name = "信息提示",
            Message = i.ToString()+"----偶数失败",
            SuccessStatus = false
    	});
    }
}

四、金蝶的事件

1、BarItemClick按钮点击事件

判断备注框里的内容是否为空,如果是空的就弹窗提示,如果不是就不弹窗

public override void BarItemClick(BOS.Core.DynamicForm.PlugIn.Args.BarItemClickEventArgs e)
{
    base.BarItemClick(e);
    
    if(e.BarItemKey == "tbDraw"){
        if(Convert.ToString(this.View.Model.GetValue("FNote")) == ""){
            e.Cancel = true;
            this.View.ShowMessage("请填写备注信息");
        }
    }
}

2、AfterSave触发后保存事件

业务场景:销售订单下推销售出库单,在销售出库单填写项目名称,点保存,反写到销售订单上面

​ 通过数据库,找到销售出库单关联销售订单,行内码,更新销售订单,项目名称;

public override void AfterSave(BOS.Core.Bill.PlugIn.Args.AfterSaveEventArgs e)
{
    base.AfterSave(e);
    
    if(e.OperationResult.Success){
        string sql = @"/*dialect*/update t1 set F_YDIE_ProjectName = 			t2.F_YDIE_ProjectName from T_SAL_ORDERENTRY t1,(select FSOEntryId,F_YDIE_ProjectName from T_SAL_OUTSTOCKENTRY_R x INNER JOIN T_SAL_OUTSTOCKENTRY y on x.FENTRYID = y.ENTRYID where x.FID ="+this.View.Model.DataObject["Id"].ToString()+")t2"+"where t1.FENTRYID = t2.FSOENTERYID"; 
    }
    
    //执行sql
    DBUtils.Execute(this.Context,sql);

}

3、DataChange事件,值改变的时候触发的事件

用if来写

// 引用
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;

// DataChanged事件
public override void DataChanged(DataChangedEventArgs e){
    base.DataChanged(e);
    // Field的用法
    if(e.Field.Key == "FCustId"){
        this.View.Model.SetValue("FNote","客户变化后赋值到备注");
        this.View.Model.SetValue("FNote1","客户变化后赋值到备注1");
        
        // DataChange中的e.NewValue和e.OldValue
        this.View.Model.SetValue()
    }
    
    // 给FCustIdNew,赋新值e.NewValue,更新前的值
    this.View.Model.SetValue("FCustIdNew",e.NewValue);
    
    // 给FCustIdNew,赋旧值e.OldValue,更新后的值
    this.View.Model.SetValue("FCustIdOld",e.OldValue);
    
    
    // DataChange中的e.Row,更新某一行中的数据
    
    // 刷新
    this.View.UpdateView("FNote");
    this.View.UpdateView("FNote1");
    
}

用switch···case来写

public override void DataChanged(DataChangedEventArgs e){
    base.DataChanged(e);
    
    switch(e.Field.Key){
        case "FCustId":
            this.View.Model.SetValue("FNote", "客户变化后赋值到备注");
            this.View.Model.SetValue("FNote1", "客户变化后赋值到备注1");
            this.View.Model.SetValue("FCustIdNew", e.NewValue);
            this.View.Model.SetValue("FCustIdOld", e.OldValue);
            break;
        case "FMaterialId":
            this.View.Model.SetValue("F_YDIE_ProjectName","项目名称"+e.Row.ToString(),e.Row);
            break;
    }
    
    // 刷新
    this.View.UpdateView("FNote");
    this.View.UpdateView("FNote1");
}

4、BeforeF7Select事件,F7

// F7函数

public override void BeforeF7Select(BOS.Core.DynamicForm.PlugIn,Args.BeforeF7SelectEventArgs e){
    // 如果等于客户
    if(e.FieldKey.Equals("FCustId")){
        e.ListFilterParameter.Filter = "FNumber='003'";
    }
}

5、AfterBindData事件

// 添加引用
using Kingdee.BOS.Core.Metadata;


public override void AfterBindData(EventArgs e)
{
    base.AfterBindData(e);

    // AfterBindData方法是用于判断单据状态的
    // 四种状态:ADDNEW,EDIT,VIEW,DISASSEMBLY
    // 分别对应:新增,编辑,查看,卸载
    
    // 判断单据状态进行字段更新 如果是新增状态,就给备注和备注1赋值
    if (this.View.OpenParameter.Status.Equals(OperationStatus.ADDNEW))
    {
		this.View.Model.SetValue("FNote", "备注");
        this.View.Model.SetValue("FNote1", "备注1");


        this.View.UpdateView("FNote");
        this.View.UpdateView("FNote1");
    }
}

根据单据状态,下推生成时,将数据推掉单据体中

//如果是新增状态,下推的,销售出库单,加载完成之后
if (this.View.OpenParameter.Status.Equals(OperationStatus.ADDNEW))
{
    //定义几个字段
    string sql;
    DataSet ds;
    DataTable dt;


    //如果是下推生成的,销售出库单上面有订单单号
    //获取源单,订单单号FSOORDERNO ,第一行,不等于空
    if (Convert.ToString(this.View.Model.GetValue("FSOORDERNO", 0)) != "")
    {
        //到数据库里面,寻找,关联的备注信息
        //获取上面关联的值1001,写入销售出库单里面
        sql = "/*dialect*/select F_YDIE_TEXT,* from YDIE_t_Cust_Entry100017 where FID in (select FID from T_SAL_ORDER where FBILLNO ='" + Convert.ToString(this.View.Model.GetValue("FSOORDERNO", 0)) + "')";

        //读取数据库里面的,执行数据,赋值给ds
        ds = DBUtils.ExecuteDataSet(this.Context, sql);

        //读取第一行数据这里是取出DataSet中的第一个表,也就是第一个DataTable变量
        dt = ds.Tables[0];

        //循环dt表,给单据体赋值,如果行大于0
        if (dt.Rows.Count > 0)
        {   //循环读取每一行数据
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                //给备注F_YDIE_TEXT,赋值

                //dt.Rows[i]行    ["F_YDIE_TEXT"].ToString() 列
                this.View.Model.SetValue("F_YDIE_TEXT", dt.Rows[i]["F_YDIE_TEXT"].ToString(), i);
            }
        }

        //刷新单据体
        this.View.UpdateView("YDIE_t_Cust_Entry100017");

    }
}

6、CustomEvents 条码扫描事件

// 添加引用
using Kingdee.BOS.Core.DynamicForm;

// 重写CustomEvents方法
public override void CustomEvents(CustomEventsArgs e)
{
    base.CustomEvents(e);

    //第一个判断,如果是条码
    if (e.Key.Equals("F_YDIE_TM"))
    {
        //捕获,回车
        if (e.EventName == "EnterKeyPressed")
        {
            //把输入的条码,获取过来,拆分成数组
            //@ 分割符号
            string[] strArray = this.View.Model.GetValue("F_YDIE_TM").ToString().Trim().Split('@');

            //如果分割成4块,说明是正确的,否则提示报错
            if (strArray.Length == 4)
            {
                //创建新行
                this.View.Model.CreateNewEntryRow("FEntity");

                //输入条码,给物料编码,赋值;第一个数组,第一个行
                //获取单据体行数 this.Model.GetEntryRowCount("FEntity");
                this.View.Model.SetItemValueByNumber("FMaterialID", strArray[0], this.Model.GetEntryRowCount("FEntity") - 1);

                //调用值更新,刷新,带出物料的计量单位等等
                this.View.InvokeFieldUpdateService("FMaterialID", this.Model.GetEntryRowCount("FEntity") - 1);

                //方便连续扫描,清空当前字段
                this.View.Model.SetValue("F_YDIE_TM", "");

                //设置焦点,一直在条码上
                this.View.GetControl("F_YDIE_TM").SetFocus();
            }
            else
            {
                //弹出错误提示,清空数据,指向焦点。
                this.View.ShowMessage("条码位数出错,请检查。。。", MessageBoxOptions.OK,
                new Action<MessageBoxResult>((result) =>
                {
                    this.Model.SetValue("F_YDIE_TM", "");
					//设置焦点
                    this.View.GetControl("F_YDIE_TM").SetFocus();
                 }));
            }
        }
    }
}

五、数据库操作

金蝶数据库操作使用的命名空间 using Kingdee.BOS.App.Data; using Kingdee.BOS.Core.DynamicForm; using Kingdee.BOS.Orm.DataEntity; // Kingdee.BOS.DataEntity.dll

1、ExecuteSql 执行sql语句

// 使用BarItemClick方法,触发点击事件来执行sql语句

public override void BarItemClick(BOS.Core.DynamicForm.PlugIn.Args.BarItemClickEventArgs e)
{
    base.BarItemClick(e);


    //当点击YDIE_tbTest按钮,触发
    if (e.BarItemKey == "YDIE_tbTest")
    {
        //执行sql语句返回Int,表示影响了多少行
        int x =  DBUtils.Execute(this.Context, "/*dialect*/update T_SAL_OUTSTOCKENTRY set FNOTE ='测试'");
        
        //弹窗显示
        this.View.ShowMessage(x.ToString());
    }
}

2、DataSet 接收返回数据


public override void BarItemClick(BarItemClickEventArgs e)
{
    base.BarItemClick(e);

    //当点击YDIE_tbTest按钮,触发
    if (e.BarItemKey == "YDIE_tbTest")
    {
        //执行sql语句返回DataSet
        //ExecuteDataSet执行
        //this.Context 上下文关联
        //抓取 物料表T_BD_MATERIAL的 ID和代码
        //DataTable,Tables[0] 操作数据库,读取第一张表,赋值给dt 

        DataTable dt = DBUtils.ExecuteDataSet(this.Context, "/*dialect*/select FMATERIALID,FNumber from T_BD_MATERIAL").Tables[0];

        //循环,读取dt表有多少行
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            //新增行
            this.View.Model.CreateNewEntryRow("FEntity");

            //给基础资料物料,赋值
            this.View.Model.SetValue("FMaterialId", dt.Rows[i]["FMATERIALID"].ToString(), i);

            //调用物料,值更新
            this.View.InvokeFieldUpdateService("FMaterialID", i);

            //给备注,赋值
            this.View.Model.SetValue("FEntrynote", dt.Rows[i]["FNumber"].ToString(), i);
        }

        //刷新
        this.View.UpdateView("FEntity");
    }
}

3、IEnumerable 枚举集合

// 操作基本与上面的DataSet一样,只是将DataSet换成了IEnumerable

IEnumerable<IDataRecord> itemDataTable = DBUtils.ExecuteEnumerable(this.Context, "/*dialect*/select FMATERIALID,FNumber from T_BD_MATERIAL");
                
//循环
int i = 0;
foreach(IDataRecord drItem in itemDataTable)
{
    //新增行
    this.View.Model.CreateNewEntryRow("FEntity");

    //给基础资料物料,赋值
    this.View.Model.SetValue("FMaterialID", drItem["FMATERIALID"].ToString(), i);

    //调用物料,值更新
    this.View.InvokeFieldUpdateService("FMaterialID", i);

    //给备注,赋值
    this.View.Model.SetValue("FEntrynote", drItem["FNumber"].ToString(), i);

    i++;
}

//刷新
this.View.UpdateView("FEntity");

4、DynamicObjectCollection 获取数据库表集合


public override void BarItemClick(BarItemClickEventArgs e)
{
        base.BarItemClick(e);

        if(e.BarItemKey == "YDIE_tbTest")
        {
            // DynamicObjectCollection里面存储多个DynamicObject对象,而每个DynamicObject对象代表一条记录
            DynamicObjectCollection data = DBUtils.ExecuteDynamicObject(this.Context, "/*dialect*/select FMATERIALID,FNUMBER from T_BD_MATERIAL");

            int j = 0;
            foreach (DynamicObject item in data)
            {
                //新增行
                this.View.Model.CreateNewEntryRow("FEntity");

                //给基础资料物料赋值
                this.View.Model.SetValue("FMaterialId", item["FMATERIALID"].ToString(), j);

                // 调用物料,值更新
                this.View.InvokeFieldUpdateService("FMaterialId", j);

                // 备注赋值
                this.View.Model.SetValue("FEntrynote", item["FNumber"].ToString(), j); ;

                j++;
            }

            // 刷新
            this.View.UpdateView("FEntity");
        }
}

二、列表插件

一、列表插件开发常用方法

1、获取单据头、单据体的FID内码

// 引用列表插件
using Kingdee.BOS.Core.List.PlugIn;
using Kingdee.BOS.Core.List;

public class Class1: AbstractListPlugIn
{
    string info;

    public override void BarItemClick(BarItemClickEventArgs e)
    {
        base.BarItemClick(e);


        // 获取选中行的主键值
        if (e.BarItemKey == "YDIE_tbTest")
        {
            // 获取选中行数据,存储到rows中
            ListSelectedRowCollection rows = this.ListView.SelectedRowsInfo;


            #region 获取单据头FID内码
            // 获取单据体的FID内码
            string[] pkValues = rows.GetPrimaryKeyValues();

            info = "";

            // 拼接主键值
            foreach (string key in pkValues)
            {
                info += key + ",";
            }

            // 反显主键值
            this.View.ShowMessage(info);
            #endregion
                
            #region 获取单据体的FID内码
			string[] listKey = rows.GetEntryPrimaryKeyValues();
            foreach (string key in listKey)
            {
                info += key + ",";
            }
            
            this.View.ShowMessage(info);
            #endregion
        }
    }
}

2、ListModel.GetData 获取单据编码

// 获取行选择信息
	ListSelectedRowCollection listcoll=this.ListView.SelectedRowsInfo;
	this.ListModel.GetData(listcoll);



二、列表插件的属性操作

引用

using Kingdee.BOS.Core.Metadata;

using System.Drawing;

1、单据列表颜色

// 重写OnFormatRowConditions方法,用于在呈现报表行数据之前,根据预设的条件动态地设置行的格式
namespace BillExecuteSql
{
    public class Class1: AbstractListPlugIn
    {
        string info;

        public override void OnFormatRowConditions(ListFormatConditionArgs args)
        {
            base.OnFormatRowConditions(args);
            DateTime dt1; // 单据日期
            DateTime dt2 = Convert.ToDateTime(DateTime.Now); // 当前日期
            TimeSpan ts; // 时间间隔
            int sub;

            // 定义FormatCondition(格式条件)对象,用于设置列表中数据区域的格式或者限制一些规则
            FormatCondition fc =new FormatCondition();

            // 打开单据的时候触发
            fc.ApplayRow = true;

            if (args.DataRow["FDOCUMENTSTATUS"].ToString() != "C")
            {
                // 获取单据日期
                dt1 = Convert.ToDateTime(args.DataRow["FDate"].ToString());

                // 计算时间间隔
                ts = dt2 - dt1;

                // 获取时间间隔的值
                sub = ts.Days;
                if (sub > 10 && sub < 20)
                {
                    fc.BackColor = ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(255, 255, 187));
                }
                if (sub > 20)
                {
                    // 橙色
                    fc.BackColor = ColorTranslator.ToHtml(System.Drawing.Color.FromArgb(255, 64, 64));
                }

                args.FormatConditions.Add(fc);
            }

        }
    }
}