金蝶二开常用方法
一、表单插件
一、表单插件开发基础方法
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);
}
}
}
}