需求:单据 / 分录点击按钮,按指定仓库 + 物料查询该仓库即时库存,回填分录虚拟库存字段,支持限定单一 / 多个仓库过滤,适配自定义单据、采购 / 出库类单据分录。
二、插件完整源码(单据分录工具栏按钮插件)
1. 引用命名空间
using System;
using System.Collections.Generic;
using Kingdee.BOS;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.App.ServiceHelper;
using Kingdee.K3.SCM.Stock.Business.Contracts;
using Kingdee.K3.SCM.Stock.Business.Contracts.DTO;
namespace Kingdee.K3.Custom.PlugIn.Stock
{
/// <summary>
/// 获取指定仓库即时库存插件
/// 按钮标识:tb_GetSpecStock
/// </summary>
public class GetSpecWarehouseStockPlugIn : AbstractBillPlugIn
{
// 库存服务
private IInstantInventoryService _invService;
public override void AfterBindData(EventArgs e)
{
base.AfterBindData(e);
// 初始化即时库存服务
_invService = ServiceHelper.GetService<IInstantInventoryService>(this.Context);
}
/// <summary>
/// 分录工具栏按钮点击事件
/// </summary>
public override void EntryBarItemClick(BarItemClickEventArgs e)
{
base.EntryBarItemClick(e);
// 判断点击的是【获取指定仓库库存】按钮
if (e.BarItemKey != "tb_GetSpecStock")
return;
try
{
DynamicObject entryRow;
int rowIndex;
// 获取当前选中分录行
bool getRow = this.Model.TryGetEntryCurrentRow("FEntity", out entryRow, out rowIndex);
if (!getRow || entryRow == null)
{
this.View.ShowMessage("请先选中一条物料分录行!");
return;
}
// 1. 获取分录字段值(根据你的单据字段名自行替换)
long orgId = Convert.ToInt64(this.Model.DataEntity["FOrgId"]); // 单据头-业务组织ID
long materialId = Convert.ToInt64(entryRow["FMaterialId_Id"]); // 物料ID
long stockId = Convert.ToInt64(entryRow["FStockId_Id"]); // 指定仓库ID(核心过滤条件)
// 2. 构造库存查询参数:限定当前仓库+当前物料
InstantInventoryQueryParam queryParam = new InstantInventoryQueryParam();
queryParam.OrgId = orgId;
queryParam.MaterialIds = new List<long>() { materialId };
queryParam.StockIds = new List<long>() { stockId }; // 指定仓库过滤
queryParam.IsQueryAvailableQty = true; // 同时查询可用库存(扣除锁库)
// 3. 调用库存服务查询即时库存
List<InstantInventoryDTO> stockResult = _invService.QueryInstantInventory(queryParam);
decimal realQty = 0;
decimal availQty = 0;
if (stockResult != null && stockResult.Count > 0)
{
foreach (var dto in stockResult)
{
realQty += dto.BaseQty; // 基本单位库存
availQty += dto.AvailableBaseQty; // 基本单位可用库存
}
}
// 4. 回填到分录虚拟字段(FRealStock、FAvailStock为自定义数量虚拟字段)
entryRow["FRealStock"] = realQty;
entryRow["FAvailStock"] = availQty;
this.View.UpdateView("FEntity", rowIndex); // 刷新界面分录
this.View.ShowMessage($"查询完成!当前仓库库存:{realQty},可用库存:{availQty}");
}
catch (Exception ex)
{
this.View.ShowErrMessage("查询库存失败:" + ex.Message);
}
}
}
}
三、配套 BOS IDE 配置步骤(文档内标准配置流程)
步骤 1:单据扩展与新增分录虚拟字段
- BOS 设计器打开目标单据 → 右键【扩展单据】→ 签出;
- 左侧工具箱【业务】→【数量】,拖入分录 FEntity;
- 字段命名:
FRealStock(标题:当前库存)、FAvailStock(标题:可用库存); - 字段属性勾选虚拟字段(不存数据库,动态查询回填)。
![图片[1]-金蝶云星空「获取指定仓库即时库存」完整插件-Dgcity](https://dgcity.com/wp-content/uploads/2026/08/20260815174534944-image.png)
步骤 2:分录工具栏新增查询按钮
- 批量编辑字段属性 → 选中分录【FEntity】;
- 右侧【菜单合集行】→ 工具栏右上角
...→ 右键新增按钮; - 按钮标识:
tb_GetSpecStock,标题:获取指定仓库即时库存; - 事件无需配置内置服务,绑定上面自定义插件。
![图片[2]-金蝶云星空「获取指定仓库即时库存」完整插件-Dgcity](https://dgcity.com/wp-content/uploads/2026/08/20260815174556774-image-1024x431.png)
步骤 3:插件注册到单据
- 单据属性 → 插件集合 → 新增;
- 插件类型:单据插件;
- 程序集 + 类名:
Kingdee.K3.Custom.PlugIn.Stock.GetSpecWarehouseStockPlugIn; - 保存、签入单据,清除缓存。
,自己编译 DLL 完整步骤
1、新建类库项目
- 打开 Visual Studio,新建【类库 (.NET Framework)】,框架版本和金蝶云星空保持一致(一般是 .NET Framework 4.7.2)
- 把我上面给你的完整 C# 代码复制进去,替换 Class1.cs 全部内容。
2、添加金蝶引用(关键)
从你的金蝶服务器 Kingdee\BOS\bin 目录复制下面 dll 加到项目引用:
Kingdee.BOS.dll
Kingdee.BOS.Core.dll
Kingdee.BOS.App.dll
Kingdee.K3.SCM.Stock.Business.Contracts.dll
⚠️必须拿你服务器本机的 dll,网上随便找的 dll 版本不对,运行直接报错。
3、项目属性设置
- 项目属性 → 生成 → 平台目标:x64
- 关闭 “首选 32 位”
- 编译,输出得到
Kingdee.K3.Custom.PlugIn.dll
4、部署到金蝶
- 将编译好 dll 复制到站点 bin 目录
Kingdee\WebSite\bin - iis 应用池回收
- BOS IDE 单据注册插件,填写完整类名:
Kingdee.K3.Custom.PlugIn.QuerySpecWarehouseStockBillPlugIn - 清除 BOS 缓存。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END














暂无评论内容