1. 金蝶KIS专业版二次开发入门指南金蝶KIS专业版作为国内中小型企业广泛使用的ERP系统其二次开发能力让企业能够根据自身业务需求进行深度定制。我刚接触KIS二次开发时发现它其实比想象中要简单得多。通过几个月的实战我总结出了一套适合新手的快速入门方法。二次开发主要涉及三大核心场景单据插件开发、序时薄插件开发和主控台外挂开发。其中单据开发是最基础也是最重要的部分。记得我第一次做销售出库单插件时花了整整一周时间才搞明白如何添加自定义字段而现在只需要半小时就能完成同样的工作。开发环境搭建其实很简单需要安装金蝶KIS专业版开发包Visual Studio 2019及以上版本.NET Framework 4.7.2金蝶提供的SDK和开发文档建议新手先从单据开发入手因为单据开发接口相对简单而且可以立即看到效果。我在开发第一个插件时就是从一个简单的字段自动填充功能开始的。2. 单据插件开发实战技巧2.1 基础字段扩展单据插件开发最常见的需求就是扩展单据字段。以销售出库单为例我们经常需要添加客户特定要求的字段。下面是一个典型的字段扩展代码示例// 在单据加载时添加自定义字段 protected override void OnLoad() { base.OnLoad(); // 在单据头添加下拉框 this.View.AddField(FMyComboBox, 我的下拉框, FieldType.ComboBox); this.View.SetFieldComboBoxItems(FMyComboBox, new string[] {选项1, 选项2, 选项3}); // 在单据体添加自定义文本字段 this.View.AddField(FMyTextField, 产品备注, FieldType.Text, 100); }这段代码会在销售出库单上添加一个下拉框和一个文本字段。我在实际项目中发现字段命名最好遵循金蝶的命名规范以F开头这样能避免很多奇怪的问题。2.2 字段自动填充自动填充是提升用户体验的关键。比如在录入物料时自动填充产品名称protected override void OnAfterEntryField(string fieldKey) { if(fieldKey FItemID) // 物料字段 { string itemID this.View.GetFieldValue(FItemID).ToString(); string itemName GetItemNameFromDB(itemID); // 从数据库获取物料名称 this.View.SetFieldValue(FMyTextField, itemName); } }这个功能看似简单但能大幅提升数据录入效率。我在一个客户项目中实现这个功能后他们的订单录入速度提高了40%。2.3 自定义按钮与业务逻辑除了字段扩展我们还可以在单据上添加自定义按钮protected override void OnLoad() { base.OnLoad(); // 添加自定义按钮 this.View.AddToolbarButton(我的按钮, 执行我的业务, MyButtonClick); } private void MyButtonClick(object sender, EventArgs e) { // 获取当前单据数据 string orderNo this.View.GetFieldValue(FBillNo).ToString(); // 执行自定义业务逻辑 bool result ProcessMyBusiness(orderNo); if(result) { this.View.ShowMessage(处理成功); } }记得在一个项目中客户需要在销售单上添加一个快速复制按钮点击后能复制当前单据并自动修改某些字段。这个功能用上述方法实现后客户非常满意。3. 序时薄插件开发进阶3.1 基础功能扩展序时薄插件开发与单据插件类似但更侧重于批量操作。比如在销售出库序时薄上添加过滤功能protected override void OnLoad() { base.OnLoad(); // 添加过滤输入框 this.View.AddFilterControl(FMyFilter, 客户名称过滤, 200); // 添加过滤按钮 this.View.AddToolbarButton(过滤, 执行过滤, OnFilterClick); } private void OnFilterClick(object sender, EventArgs e) { string filterValue this.View.GetFilterValue(FMyFilter); string filterStr $FCustomerName LIKE %{filterValue}%; this.View.SetFilter(filterStr); }这个功能特别适合数据量大的场景。有个客户有上万条历史单据加了过滤功能后查找效率提升了几十倍。3.2 行样式定制序时薄另一个常见需求是根据数据状态改变行样式protected override void OnDrawRow(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.DrawRowEventArgs e) { base.OnDrawRow(e); string status e.Row[FStatus].ToString(); if(status 已审核) { e.Style.BackColor Color.LightGreen; } else if(status 已关闭) { e.Style.BackColor Color.LightGray; } }这种视觉提示能让用户快速识别单据状态。我在一个生产管理系统中实现这个功能后用户反馈操作失误率明显降低。4. 主控台外挂开发实战4.1 自定义菜单集成主控台开发主要是在系统主界面添加自定义功能入口。下面是一个添加报表菜单的示例public class MyReportPlugin : AbstractMainViewPlugIn { public override void AfterCreateMainView(AfterCreateMainViewEventArgs e) { base.AfterCreateMainView(e); // 在销售管理下添加菜单项 this.View.AddMenuItem(销售管理, 我的自定义报表, ShowMyReport); } private void ShowMyReport(object sender, EventArgs e) { MyReportForm reportForm new MyReportForm(); reportForm.ShowDialog(); } }这种集成方式能让二次开发的功能看起来像是系统原生功能用户体验更好。4.2 报表集成技巧将自定义报表集成到系统中有两种方式弹窗式和页签式。弹窗式适合简单的报表private void ShowMyReport(object sender, EventArgs e) { string sql SELECT * FROM MyCustomTable; DataTable data DBHelper.ExecuteDataSet(sql).Tables[0]; ReportViewer viewer new ReportViewer(); viewer.SetDataSource(data); viewer.Show(); }而页签式更适合复杂的交互式报表private void ShowTabReport(object sender, EventArgs e) { string tabKey MyReportTab; if(this.View.ExistTabPage(tabKey)) { this.View.ActivateTabPage(tabKey); return; } MyReportControl reportControl new MyReportControl(); this.View.AddTabPage(tabKey, 我的报表, reportControl); }在一个库存分析项目中我采用了页签式集成用户可以在不同报表间快速切换大大提升了分析效率。5. 开发经验与避坑指南5.1 K3工业单据开发经验借鉴金蝶KIS专业版的单据设计与K3工业单据一脉相承。我在开发过程中发现很多K3工业单据的开发技巧可以直接应用到KIS专业版中事件处理顺序完全一致字段控制方法相同业务逻辑封装方式类似特别是单据插件开发K3的示例代码稍作修改就能在KIS专业版中运行。有次我直接使用了K3的一个批量审核插件代码只改了命名空间就在KIS上完美运行了。5.2 BOS新单据开发注意事项KIS专业版中也有部分BOS新单据这类单据的开发略有不同需要使用BOS设计器扩展方式更灵活支持更复杂的业务逻辑我建议新手先从传统单据开发入手等熟悉了再尝试BOS单据开发。BOS开发虽然强大但学习曲线更陡峭。5.3 常见问题排查在开发过程中我遇到过不少坑这里分享几个典型问题的解决方法插件不加载检查插件是否注册到GAC配置文件是否正确字段值不保存确保字段在数据库中有对应列且有写入权限性能问题避免在循环中频繁访问数据库尽量批量操作记得有次客户反映单据保存特别慢最后发现是在BeforeSave事件中做了全表扫描优化查询后速度提升了上百倍。6. 销售与库存协同优化案例6.1 业务场景分析我曾负责一个销售与库存协同优化项目客户的主要痛点是销售不知道实时库存采购不能及时响应销售需求库存积压严重通过分析我们确定了以下开发重点销售单实时显示库存自动生成采购建议库存预警功能6.2 关键技术实现实时库存显示在销售单插件中实现protected override void OnAfterEntryField(string fieldKey) { if(fieldKey FItemID) { string itemID this.View.GetFieldValue(FItemID).ToString(); int stockQty GetRealTimeStock(itemID); this.View.SetFieldValue(FStockQty, stockQty); } }自动采购建议通过序时薄插件实现private void GeneratePurchaseAdvice() { string sql SELECT t1.FItemID, t1.FItemName, SUM(t1.FQty) AS DemandQty, t2.FStockQty, (SUM(t1.FQty) - t2.FStockQty) AS AdviceQty FROM SalesOrder t1 JOIN Inventory t2 ON t1.FItemID t2.FItemID GROUP BY t1.FItemID, t1.FItemName, t2.FStockQty HAVING SUM(t1.FQty) t2.FStockQty; DataTable advice DBHelper.ExecuteDataSet(sql).Tables[0]; advice.TableName PurchaseAdvice; PurchaseAdviceForm form new PurchaseAdviceForm(); form.SetDataSource(advice); form.Show(); }这个项目上线后客户库存周转率提高了35%订单满足率提升了28%。7. 调试与部署最佳实践7.1 调试技巧金蝶KIS插件的调试比较特殊我总结了几种有效方法日志输出使用金蝶提供的日志接口Kingdee.BOS.Log.Logger.Info(这是我的调试信息);附加进程在Visual Studio中附加到KIS主进程单元测试对核心业务逻辑单独测试我发现日志输出是最可靠的调试方式特别是在客户现场排查问题时。7.2 部署方案插件部署有几个关键点需要将DLL安装到GAC配置文件要放在正确位置权限设置要合理我习惯使用一个批处理文件来自动化部署echo off set GACUTILC:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\gacutil.exe %GACUTIL% -i MyPlugin.dll xcopy config.xml C:\Program Files (x86)\Kingdee\KIS\Professional\Config\ /Y这个简单的脚本可以避免很多手动部署容易出错的问题。8. 性能优化建议在开发过程中性能是需要特别关注的。以下是我总结的几个优化建议减少数据库访问尽量批量获取数据避免在循环中查询合理使用缓存对不常变的数据进行缓存异步处理耗时操作放到后台线程我曾优化过一个单据插件将200次单条查询改为1次批量查询执行时间从15秒降到了0.3秒。另一个有用的技巧是延迟加载protected override void OnLoad() { base.OnLoad(); // 延迟加载非必要数据 this.View.RegisterDelayAction(LoadExtraData, LoadExtraData, 1000); } private void LoadExtraData() { // 加载额外数据 }这样可以让界面先显示出来提升用户体验。
KIS专业版二次开发实战:从单据插件到主控台外挂的进阶指南
1. 金蝶KIS专业版二次开发入门指南金蝶KIS专业版作为国内中小型企业广泛使用的ERP系统其二次开发能力让企业能够根据自身业务需求进行深度定制。我刚接触KIS二次开发时发现它其实比想象中要简单得多。通过几个月的实战我总结出了一套适合新手的快速入门方法。二次开发主要涉及三大核心场景单据插件开发、序时薄插件开发和主控台外挂开发。其中单据开发是最基础也是最重要的部分。记得我第一次做销售出库单插件时花了整整一周时间才搞明白如何添加自定义字段而现在只需要半小时就能完成同样的工作。开发环境搭建其实很简单需要安装金蝶KIS专业版开发包Visual Studio 2019及以上版本.NET Framework 4.7.2金蝶提供的SDK和开发文档建议新手先从单据开发入手因为单据开发接口相对简单而且可以立即看到效果。我在开发第一个插件时就是从一个简单的字段自动填充功能开始的。2. 单据插件开发实战技巧2.1 基础字段扩展单据插件开发最常见的需求就是扩展单据字段。以销售出库单为例我们经常需要添加客户特定要求的字段。下面是一个典型的字段扩展代码示例// 在单据加载时添加自定义字段 protected override void OnLoad() { base.OnLoad(); // 在单据头添加下拉框 this.View.AddField(FMyComboBox, 我的下拉框, FieldType.ComboBox); this.View.SetFieldComboBoxItems(FMyComboBox, new string[] {选项1, 选项2, 选项3}); // 在单据体添加自定义文本字段 this.View.AddField(FMyTextField, 产品备注, FieldType.Text, 100); }这段代码会在销售出库单上添加一个下拉框和一个文本字段。我在实际项目中发现字段命名最好遵循金蝶的命名规范以F开头这样能避免很多奇怪的问题。2.2 字段自动填充自动填充是提升用户体验的关键。比如在录入物料时自动填充产品名称protected override void OnAfterEntryField(string fieldKey) { if(fieldKey FItemID) // 物料字段 { string itemID this.View.GetFieldValue(FItemID).ToString(); string itemName GetItemNameFromDB(itemID); // 从数据库获取物料名称 this.View.SetFieldValue(FMyTextField, itemName); } }这个功能看似简单但能大幅提升数据录入效率。我在一个客户项目中实现这个功能后他们的订单录入速度提高了40%。2.3 自定义按钮与业务逻辑除了字段扩展我们还可以在单据上添加自定义按钮protected override void OnLoad() { base.OnLoad(); // 添加自定义按钮 this.View.AddToolbarButton(我的按钮, 执行我的业务, MyButtonClick); } private void MyButtonClick(object sender, EventArgs e) { // 获取当前单据数据 string orderNo this.View.GetFieldValue(FBillNo).ToString(); // 执行自定义业务逻辑 bool result ProcessMyBusiness(orderNo); if(result) { this.View.ShowMessage(处理成功); } }记得在一个项目中客户需要在销售单上添加一个快速复制按钮点击后能复制当前单据并自动修改某些字段。这个功能用上述方法实现后客户非常满意。3. 序时薄插件开发进阶3.1 基础功能扩展序时薄插件开发与单据插件类似但更侧重于批量操作。比如在销售出库序时薄上添加过滤功能protected override void OnLoad() { base.OnLoad(); // 添加过滤输入框 this.View.AddFilterControl(FMyFilter, 客户名称过滤, 200); // 添加过滤按钮 this.View.AddToolbarButton(过滤, 执行过滤, OnFilterClick); } private void OnFilterClick(object sender, EventArgs e) { string filterValue this.View.GetFilterValue(FMyFilter); string filterStr $FCustomerName LIKE %{filterValue}%; this.View.SetFilter(filterStr); }这个功能特别适合数据量大的场景。有个客户有上万条历史单据加了过滤功能后查找效率提升了几十倍。3.2 行样式定制序时薄另一个常见需求是根据数据状态改变行样式protected override void OnDrawRow(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.DrawRowEventArgs e) { base.OnDrawRow(e); string status e.Row[FStatus].ToString(); if(status 已审核) { e.Style.BackColor Color.LightGreen; } else if(status 已关闭) { e.Style.BackColor Color.LightGray; } }这种视觉提示能让用户快速识别单据状态。我在一个生产管理系统中实现这个功能后用户反馈操作失误率明显降低。4. 主控台外挂开发实战4.1 自定义菜单集成主控台开发主要是在系统主界面添加自定义功能入口。下面是一个添加报表菜单的示例public class MyReportPlugin : AbstractMainViewPlugIn { public override void AfterCreateMainView(AfterCreateMainViewEventArgs e) { base.AfterCreateMainView(e); // 在销售管理下添加菜单项 this.View.AddMenuItem(销售管理, 我的自定义报表, ShowMyReport); } private void ShowMyReport(object sender, EventArgs e) { MyReportForm reportForm new MyReportForm(); reportForm.ShowDialog(); } }这种集成方式能让二次开发的功能看起来像是系统原生功能用户体验更好。4.2 报表集成技巧将自定义报表集成到系统中有两种方式弹窗式和页签式。弹窗式适合简单的报表private void ShowMyReport(object sender, EventArgs e) { string sql SELECT * FROM MyCustomTable; DataTable data DBHelper.ExecuteDataSet(sql).Tables[0]; ReportViewer viewer new ReportViewer(); viewer.SetDataSource(data); viewer.Show(); }而页签式更适合复杂的交互式报表private void ShowTabReport(object sender, EventArgs e) { string tabKey MyReportTab; if(this.View.ExistTabPage(tabKey)) { this.View.ActivateTabPage(tabKey); return; } MyReportControl reportControl new MyReportControl(); this.View.AddTabPage(tabKey, 我的报表, reportControl); }在一个库存分析项目中我采用了页签式集成用户可以在不同报表间快速切换大大提升了分析效率。5. 开发经验与避坑指南5.1 K3工业单据开发经验借鉴金蝶KIS专业版的单据设计与K3工业单据一脉相承。我在开发过程中发现很多K3工业单据的开发技巧可以直接应用到KIS专业版中事件处理顺序完全一致字段控制方法相同业务逻辑封装方式类似特别是单据插件开发K3的示例代码稍作修改就能在KIS专业版中运行。有次我直接使用了K3的一个批量审核插件代码只改了命名空间就在KIS上完美运行了。5.2 BOS新单据开发注意事项KIS专业版中也有部分BOS新单据这类单据的开发略有不同需要使用BOS设计器扩展方式更灵活支持更复杂的业务逻辑我建议新手先从传统单据开发入手等熟悉了再尝试BOS单据开发。BOS开发虽然强大但学习曲线更陡峭。5.3 常见问题排查在开发过程中我遇到过不少坑这里分享几个典型问题的解决方法插件不加载检查插件是否注册到GAC配置文件是否正确字段值不保存确保字段在数据库中有对应列且有写入权限性能问题避免在循环中频繁访问数据库尽量批量操作记得有次客户反映单据保存特别慢最后发现是在BeforeSave事件中做了全表扫描优化查询后速度提升了上百倍。6. 销售与库存协同优化案例6.1 业务场景分析我曾负责一个销售与库存协同优化项目客户的主要痛点是销售不知道实时库存采购不能及时响应销售需求库存积压严重通过分析我们确定了以下开发重点销售单实时显示库存自动生成采购建议库存预警功能6.2 关键技术实现实时库存显示在销售单插件中实现protected override void OnAfterEntryField(string fieldKey) { if(fieldKey FItemID) { string itemID this.View.GetFieldValue(FItemID).ToString(); int stockQty GetRealTimeStock(itemID); this.View.SetFieldValue(FStockQty, stockQty); } }自动采购建议通过序时薄插件实现private void GeneratePurchaseAdvice() { string sql SELECT t1.FItemID, t1.FItemName, SUM(t1.FQty) AS DemandQty, t2.FStockQty, (SUM(t1.FQty) - t2.FStockQty) AS AdviceQty FROM SalesOrder t1 JOIN Inventory t2 ON t1.FItemID t2.FItemID GROUP BY t1.FItemID, t1.FItemName, t2.FStockQty HAVING SUM(t1.FQty) t2.FStockQty; DataTable advice DBHelper.ExecuteDataSet(sql).Tables[0]; advice.TableName PurchaseAdvice; PurchaseAdviceForm form new PurchaseAdviceForm(); form.SetDataSource(advice); form.Show(); }这个项目上线后客户库存周转率提高了35%订单满足率提升了28%。7. 调试与部署最佳实践7.1 调试技巧金蝶KIS插件的调试比较特殊我总结了几种有效方法日志输出使用金蝶提供的日志接口Kingdee.BOS.Log.Logger.Info(这是我的调试信息);附加进程在Visual Studio中附加到KIS主进程单元测试对核心业务逻辑单独测试我发现日志输出是最可靠的调试方式特别是在客户现场排查问题时。7.2 部署方案插件部署有几个关键点需要将DLL安装到GAC配置文件要放在正确位置权限设置要合理我习惯使用一个批处理文件来自动化部署echo off set GACUTILC:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\gacutil.exe %GACUTIL% -i MyPlugin.dll xcopy config.xml C:\Program Files (x86)\Kingdee\KIS\Professional\Config\ /Y这个简单的脚本可以避免很多手动部署容易出错的问题。8. 性能优化建议在开发过程中性能是需要特别关注的。以下是我总结的几个优化建议减少数据库访问尽量批量获取数据避免在循环中查询合理使用缓存对不常变的数据进行缓存异步处理耗时操作放到后台线程我曾优化过一个单据插件将200次单条查询改为1次批量查询执行时间从15秒降到了0.3秒。另一个有用的技巧是延迟加载protected override void OnLoad() { base.OnLoad(); // 延迟加载非必要数据 this.View.RegisterDelayAction(LoadExtraData, LoadExtraData, 1000); } private void LoadExtraData() { // 加载额外数据 }这样可以让界面先显示出来提升用户体验。