金蝶K3工业单据中间层插件开发教程
金蝶K3工业单据中间层插件开发教程
金蝶K3工业单据中间层插件开发教程
前言:
做为一个公司的K3系统运维人员一定要学习系统的BOS单据(自定义单据)和工业单据的二次开发,都是在日常开发中遇到问题再到网上去找一些资料再改进自己所写的功能,但在网上找BOS单据和工业单据的单据开发的资料很多,但工业单据中间层的资料确很少(注:可能是我没有竭尽所能的去找吧),现在我将自己在K3工业单据中间层开发实践中不段摸索出来的经验写成教程(此处暂时称为教程吧)分享给大家,以便有助于大家的学习。
一 开发工具
金蝶K3的插件开发所使用的开发工具包括以下四种:
编程工具VB6.0
VB6.0全称为VisualBasic6.0,是微软公司于1998年推出的可视化编程工具MSDN之一。金蝶K3系统的插件开发基本上都是用此工具开发的,当然网上也有用visual studio进行开发并实现的例子,但些教程中所讲解和使用的是VB6.0。
金蝶插件开发向导
金蝶插件开发向导是金蝶公司开发的一个开发辅助包其中包括BOS单据和中间层、工业单据和中间层的所有?。在安装有金蝶K3系统的计算机上安装VB6.0后,在VB6.0的工作窗口中的菜单栏和工具栏中都可找到如下图红框标注位置所示,
如果在工作窗口菜单栏或工具栏中未找到开发向导我们可以新建一个后缀为bat的批处理文件并在文件里面添加如下语句保存并执行该批处理文件即可。
regsvr32 “K3系统安装目录\Addin\K3BOSPLUGINSADDIN.dll”
regsvr32 “K3系统安装目录\Addin\K3GLParaConsolePlugin.dll”
Sql Server数据库系统
Sql Server是微软公司推出的一种关系型数据库系统。SQL Server是一个可扩展的、高性能的、为分布式客户机/服务器计算所设计的数据库管理系统,实现了与WindowsNT的有机结合,提供了基于事务的企业级信息管理系统方案。金蝶K3系统中数据存储及交换就依托本系统实现。因此本教程讲解和使用的为Sql Server 2008版。
组件注册工具-组件服务(windows系统自带)
组件服务具体位置是在系统”控制面板“-”管理工具“对话框下,如下图红框标记处。
二 中间层审核插件开发实例
2.1 该教程以产品入库单审核后通过产品入库单中的计划号去反写向销售订单分录中相同计划号对应自定义字段入库数量、入库类型、入库审核日期中返写入库实收数量、入库类型、入库审核时间等信息。
产品入库单相关字段包括 :
FCheckDAte 产品入库单审核日期可由数据库命令Convert(varchar(100),GETDATE(),21) 生成
FEntrySelfA0238 产品入库单分录计划号
FAuxQty 产品入库单分录对应计划号实收数量
FName 入库类型名称可自己根据单据自己输入也可以根据单据事务类型判断输入
FTransType 单据事务类型可自己根据数据库中的类型输入也可以根据查询带出相关字段
FCheckBZ 审核标志这里 1是审核 2 是反审核
以上字段具体使用方法见" 2.3.8 完整代码展示" 中的SqlStr变量定义。
销售订单相关字段包括:
反写字段:FEntrySelfS0165 入库数量、FEntrySelfS0174 入库审核日期、FEntrySelfS0175 入库单据类型
反写判断所需字段:FEntrySelfS0160 销售订单分录计划号
以上字段具体使用方法风"2.3.10 存储过程Self_StockCheckReSeorder创建"中的代码示例。
2.2 插件开发需要引用的系统动态链接库文件包含:Visual Basic For Applications、Visual Basic runtime objects and procedures、Visual Basic objects and procedures、OLE Automation、Kingdee Foundation Objects 1.0以及Microsfot ActiveX Data Objects 2.8 Library其中前五项动态链接库可以根据VB6.0加载的“金蝶开发向导”自动生成外,其余的通过VB6.0的“工程”菜单下的“引用”命令进行引用。
2.3 开发实例
2.3.1 运行VB6.0并点击菜单栏中的“文件”菜单下的“新建工程”命令并在弹出的“新建工程”对话框中选择“ActiveX DLL”后点“确定”按钮完成工程的新建操作。如下图所示
2.3.2 修改工程名称为“K3SeorderMid"并在工程下添加一个名为”Seorder_MidEvent“的类模块,如下图所示
2.3.3 点击菜单栏上的"金蝶K/3-Bos"菜单并点击其下面的”插件开发向导命令“,如下图所示
2.3.4 在弹出的插件开发向导中选择”金蝶K/3工业单据中间层插件“单选按钮并点击”确定“按钮,如下图所示
2.3.5 在弹出的”选择中间层插件类型“对话框中勾选”审核退出前事件“并在”类模块“下拉列表中选择我们起初新建的命为”Seorder_MidEvent“类模块并点击”下一步“,如下图所示
2.3.6 在弹出的向导完成对话框中点击”完成“按钮退出开发向导,如下图所示
‘定义插件对象接口. 必须具有的声明, 以此来获得事件
‘注意: 此方法必须存在, 请勿修改
Select Case EventID
Case 200003 ‘审核退出前事件
‘——————————————————–
'dctParams 值域 | 含义 '-------------------------------------------------------- 'sDsn | 连接字符串 'InterID | 单据的内码 'TranType | 单据的事务类型 'OperateDelete | 默认值为0 'ROB | 是否是红单 'OperateCode | 操作码: 1------审核 ' | 2------反审核 ' | 4------保存 ' | 8------删除 ' | 16-----反作废 ' | 32-----作废 '--------------------------------------------------------
Case Else
End Select
End Function
dctParams 值域sDsn、InterID以及TranType介绍
sDsn中存放了K3数据库的连接字符串和K3当前登录用户的相关连接字符。我们要通过字符串截取函数将数据库连接字符串截取出来用于数据库的连接并通过建立的连接对数据库进行相关操作。
InterID为单据内码对应单据在数据库表中的FInterID字段。
TranType单据事务类型,该值可通过对数据库ICTransactionType表中的FID值。
dctParams值域的调用方法分为下面两种形式(以sDsn为列)
dctParams(“sDsn”) dctParams.Value(“sDsn”)
2.3.8 完整代码展示
‘变量定义————————————
Dim sDsn As String ‘用于存放数据库存连接字符串
Dim InterID As Long ‘用于存放单据内码
Dim TranType As Long ‘用于存放单据事务类码
Dim OpDelete As Long ‘用于存放操作码
Dim ROB As Long ‘用于存放红、蓝单据标志
Dim OpCode As Long ‘用于存放操作码
Dim Sqlstr As String ‘用于存放SQL相关查询语句
‘————————————————-
‘系统对象定义————————————-
Dim DBCon As New ADODB.Connection ‘定义数据库连接对象
Dim DBset As New ADODB.Recordset ‘定义数据集对象
‘————————————————-
Public Function HookInvoke(ByVal EventID As Long, dctParams As KFO.Dictionary) As Long
'定义插件对象接口. 必须具有的声明, 以此来获得事件
'注意: 此方法必须存在, 请勿修改
'截取数据库连接字符串
sDsn = Left(dctParams.GetValue("sDsn", 0), InStr(dctParams.GetValue("sDsn", 0), "}") - 1)
sDsn = Mid(sDsn, InStr(sDsn, "{") + 1, Len(sDsn))
HookInvoke = True
'设置数据库存游标为本地游标
DBCon.CursorLocation = adUseClient
'打开连接
If DBCon.State <> adStateOpen Then ’判断数据库连接状态是否为连接状态
DBCon.Open sDsn ‘如未连接则连接数据库
DBCon.CommandTimeout = 0
End If
InterID = dctParams.Value("InterID") ’将单据内码赋值给InterID变量
'定义连接字符串结束
Select Case EventID
Case 200003 '审核退出前事件
'--------------------------------------------------------
'dctParams 值域 | 含义
'--------------------------------------------------------
'sDsn | 连接字符串
'InterID | 单据的内码
'TranType | 单据的事务类型
'OperateDelete | 默认值为0
'ROB | 是否是红单
'OperateCode | 操作码: 1------审核
' | 2------反审核
' | 4------保存
' | 8------删除
' | 16-----反作废
' | 32-----作废
'--------------------------------------------------------
Select Case dctParams("TranType") '判断单据事务类型
‘—————————产品入库单———————————————-
Case “2” ‘单据事务类型为产品入库单
Select Case dctParams.Value(“OperateCode”) ‘判断操作码
Case 1 '操作码为审核
‘————————-产品入库单审核——————————————–
On Error GoTo HookCPSErro
Sqlstr = "select Convert(varchar(100),GETDATE(),21) as FCheckDate,a.FEntrySelfA0238 as FPlanCode,a.FAuxQty as FInQty,b.FName as FInType,2 as FTransType,1 as FCheckBZ from icstockbillentry a left outer join t_Stock b on a.FDCStockID=b.FItemID where a.FInterID=" & dctParams.Value("InterID") ‘查询字符串
Set DBset = DBCon.Execute(Sqlstr) ’执行查询字符串并将结果返回至DBset数据集
If DBset.BOF = False And DBset.EOF = False Then ‘判断数据集中是否存在数据,存在则执行下面语句
DBset.MoveFirst ’将数据集指针移动到第一个记录位置
While Not DBset.EOF ‘如指针超越最后一个记录位置则执行While循环体里的代码
'下面调用的是数据库中名为Self_StockCheckReSeorder的存储过程,详见2.3.10
Call DBCon.Execute("Exec Self_StockCheckReSeorder " & DBset.Fields("FCheckDate") & "," & DBset.Fields("FPlanCode") & "," & DBset.Fields("FInQty") & "," & DBset.Fields("FInType") & "," & DBset.Fields("FTransType") & "," & DBset.Fields("FCheckBZ"))
DBset.MoveNext ’将数据集指针下移一个位置
Wend ‘结束当前循环
End If
Exit Function ’退出当前HookInvoke方法
HookCPSErro:
Err.Raise -1, , “中间层产品入库单审核调用失败,原因可能是:” & Err.Description & “:”, “金蝶提示” ‘当出现错误时的提示信息
If DBCon.State <> adStateClosed Then ‘判断数据是不是为连接状态
Set DBCon = Nothing ’如果当前状态为连接状态那么就关闭数据库连接
End If
HookInvoke = -1 ‘停止当前对单据的审核操作
Resume Next ’退出当前 HookInvoke 方法
‘————————-产品入库单审核结束——————————————–
‘————————-产品入库单反审核———————————————-
Case 2 ‘操作码为反审核
On Error GoTo HookCPRSErro
Sqlstr = "select Convert(varchar(100),GETDATE(),21) as FCheckDate,a.FEntrySelfA0238 as FPlanCode,a.FAuxQty as FInQty,b.FName as FInType,2 as FTransType,2 as FCheckBZ from icstockbillentry a left outer join t_Stock b on a.FDCStockID=b.FItemID where a.FInterID=" & dctParams.Value("InterID")
Set DBset = DBCon.Execute(Sqlstr) ’执行查询字符串并将结果返回至DBset数据集
If DBset.BOF = False And DBset.EOF = False Then ‘判断数据集中是否存在数据,存在则执行下面语句
DBset.MoveFirst ’将数据集指针移动到第一个记录位置
While Not DBset.EOF ‘如指针超越最后一个记录位置则执行While循环体里的代码
'下面调用的是数据库中名为Self_StockCheckReSeorder的存储过程,详见2.3.10
Call DBCon.Execute("Exec Self_StockCheckReSeorder " & DBset.Fields("FCheckDate") & "," & DBset.Fields("FPlanCode") & "," & DBset.Fields("FInQty") & "," & DBset.Fields("FInType") & "," & DBset.Fields("FTransType") & "," & DBset.Fields("FCheckBZ"))
DBset.MoveNext ’将数据集指针下移一个位置
Wend ‘结束当前循环
End If
Exit Function ‘执行结束退出Function
HookCPRSErro:
Err.Raise -1, , “中间层产品入库单反审核调用失败,原因可能是:” & Err.Description & “:”, “金蝶提示” ’
If DBCon.State <> adStateClosed Then
Set DBCon = Nothing
End If
HookInvoke = -1
Resume Next
‘————————-产品入库单反审核结束——————————————–
Case Else ‘–判断操作码
End Select ‘–判断操作码结束
Case Else ‘–TransType
End Select ‘–TransType 结束
Case Else ‘–EVENID
End Select ‘–EVENID 结束
End Function
2.3.9 完成代码编辑后点击 VB6.0 菜单上的"文件"菜单下面生成的”生成 K3SeorderMid.dll“命令生成名为”K3SeorderMid“的 dll 文件,如图所示
2.3.10 存储过程 Self_StockCheckReSeorder 创建
Create PROCEDURE [dbo].[Self_StockCheckReSeorder]
– Add the parameters for the stored procedure here
@FCheckDate as varchar(100), –入库审核日期
@FPlanCode as varchar(255),–入库单计划号
@FQty as decimal(18,2),–入库实收数量
@FInType as varchar(255),–入库类型
@FTranType as int,–单据事务类型
@FCheckType as int–单据操作类型 1 为审核 2 为反审核
AS
BEGIN
– SET NOCOUNT ON added to prevent extra result sets from
– interfering with SELECT statements.
if @FTranType=2 –审核单据为产品入库
begin
if @FInType=‘成品库’ and @FCheckType=1 –当入库库房为成品库时且单据为审核时
begin
update se set se.FEntrySelfS0165=Case se.FEntrySelfS0165 When 0 Then @FQty else se.FEntrySelfS0165+@Fqty end ,se.FEntrySelfS0174=@FCheckDate,se.FEntrySelfS0175=‘产品入库’
from seorderentry se
INNER JOIN seorder so on se.finterid=so.finterid
where se.FEntrySelfS0160=@FPlanCode and so.FCancellation=0
end
if @FInType=‘成品返修库’ and @FCheckType=1 –当入库库房为成品返修库时且单据为审核时
begin
update se set se.FEntrySelfS0165=Case se.FEntrySelfS0165 When 0 Then @FQty else se.FEntrySelfS0165+@Fqty end ,se.FEntrySelfS0174=@FCheckDate,se.FEntrySelfS0175=‘返修入库’
from seorderentry se
INNER JOIN seorder so on se.finterid=so.finterid
where se.FEntrySelfS0160=@FPlanCode and so.FCancellation=0
end
if (@FInType=‘成品库’ or @FInType=‘成品返修库’) and @FCheckType=2 –当入库库房为成品库或成品返修改库时且单据为反审核时
begin
update se set se.FEntrySelfS0165=(case WHEN se.FEntrySelfS0165>0 then se.FEntrySelfS0165 - @FQty else 0 end),se.FEntrySelfS0174=NULL,se.FEntrySelfS0175=NULL
from seorderentry se
INNER JOIN seorder so on se.finterid=so.finterid
where se.FEntrySelfS0160=@FPlanCode and so.FCancellation=0
end
end
END
三 中间层插件注册
3.1 中间层插件在 K3 数据库中的注册
3.1.1 K3 数据库插件注册表 t_ThirdPartyComponent
t_ThirdPartyComponent 是用于存放用户所开发的中间层插件信息,便于 K3 系统在特定操作时根据表中信息按指定顺序进行插件调用的数据表。其字段和解释如下:
FTypeID: 插件类型字段:0 表示客户端中间层插件;2 表示工业单据中间层插件;
FTypeDetailID: 插件操作类型字段:客户端中间层插件为单据类型编号(如:销售订单为 81);工业单据插件为具体事件 ID 编号(如:审核退出前事件对应 ID:200003;详见工业单据中间层开发向导)
FIndex: 插件索引字段:用于设置插件执行顺序可以为正数或负数(如:-1 或 1)
FComponentName: 插件名称:用于存放客户端中间层插件;
FComponentSrv: 插件名称:用于存放工业单据中间层插件;
FDescription: 插件描述字段:描述插件作用(这个可以自己随便写);
3.1.2 t_ThirdPartyComponent 表工业单据中间层注册实例
Insert t_ThirdPartyComponent
(FTypeID,FTypeDetailID,FIndex,FComponentSrv,FDescription)
Values(2,200003,-101,’K3SeorderMid.Seorder_MidEvent’,’自定义审核插件’)
3.2 中间层插件在中间层系统中的注册
3.2.1 在中间层服务器上逐步点开控制面板-管理工具-组件服务打开如下图所示控制窗口。
3.2.2 逐步点击展开组件服务-计算机-我的电脑-COM+应用程序-ebok3 树型目录如下图所示。
3.2.3 在 ebok3 目录下点击右键点击新建-组件命令进行组件注册如下图所示。
3.2.4 在弹出的“COM+组件安装向导”对话框中点击下一步如图所示。
3.2.5 在弹出的“导入或安装组件”对话框中点击“安装组件”命令并点击“下一步”按钮 如下图所示:
3.2.6 在弹出来的“安装新组件”对话框中点击“添加”按钮在弹出的文件选择对话框中选择所开发的插件此处以 K3SeorderMid.dll 为例,选中插件文件后并点击“确定”按钮将插件添加到对话框中并点击“下一步”如图所示。其注册后的组件名称为 K3SeorderMid.Seorder_MidEvent。
3.2.7 在弹出的完成对话框中点击完成按钮已完成组件注册。
3.2.8 在组件服务工作窗口中选中刚才注册的 K3SeorderMid.Seorder_MidEvent 并点击鼠标右键,在弹出的右键菜单中点击“属性”如下图所示
3.2.9 在弹出的组件属性对话框中选择事件选项卡如下图所示
3.2.10 在组件属性对话框事务选项卡下的事务支持组框中点击“支持”对应的单选按钮如图所示
3.2.11 选择“支持”单选按钮后事务选项卡下的“事务隔离级别”选项将由灰色不可编辑变为可编辑,此时我们要将“事务隔离级别”选项下拉列表中的值选为“任意”,最后点击“应用”保存设置并点击“确定”退出。
(注:3.2.10 和 3.2.11 是最主要的,如果组件注册完成后不进行这两步设置在调用过程中会暂时造成数据库死锁 K3 系统提示“语句查询超时”错误。)
结束语:
通过上述实例的讲解至此本教程到此结束教程中的代码能过实测能用的,希望该教程对所有正在学习 K3 二次开发的朋友有所帮助,也希望大家能举一反三开发出更多更好的工业单据中间层插件。