
【场景】单据打印次数 、单据类型打印次数 和 单据打印操作次数
【单据打印次数】
(0)单据打印次数是单据上的一个普通整数字段,直接存储于单据的物理表上


(1)启用单据打印次数控制:单据参数配置

(2)计数逻辑:当单据上存在打印次数时,就会进行更新,无需启用打印次数控制。

【单据类型打印次数】
(0)单据类型打印次数,存储于后台表 T_BAS_BILLPRINTCONTROL

(1)启用单据类型打印次数控制:单据类型表单

(2)计数逻辑:当启用了单据类型打印次数控制时,才会进行更新;
使用单据类型计数能避免出现打印次数字段受污染的逻辑,但是会出现非所见即所得。

【单据打印操作次数】
(0)单据打印操作次数是单据上的一个普通整数,直接存储于单据的物理表上


(1)启用单据打印操作次数校验:单据参数配置

(2)计数逻辑:当单据上存在打印操作次数时,就会进行更新,无需启用打印次数控制。
【常见问题】
(0)由于单据打印次数是单据上的字段,需要确保单据新增的时候字段为0,且仅有平台通过套打时更新此字段;
如字段设置不允许复制、不允许下推、值更新等逻辑
(1)当多业务对象共用物理表时
a)当两个业务对象需要独立计数时,可在不同的业务对象上使用不同的打印次数字段(对象A使用打印次数1字段,对象B使用打印次数2字段,不同业务对象之间的打印次数字段标识和数据库字段名不一致)
b)当两个业务对象需要共同计数时,设置两个对象的打印次数字段的字段标识和字段名一致;且当需要打印次数控制时,最好是使用单据参数控制且保证两端一致。不宜使用单据类型控制,如收料通知单和送货通知单



(2)单据的打印次数字段和单据类型的打印次数控制,在计数逻辑上并不一致
如针对已存在打印次数的单据,启用单据类型打印次数控制,平台不会将原单据打印次数的值更新到单据类型上
(3)单据打印次数、单据类型打印次数、单据打印操作次数
以上三个字段的校验时机和更新时机均不一致;
校验时机:套打操作关联的菜单点击时;
更新时机: 单据打印操作次数——在发送套打页面给前端时更新; 单据打印次数、单据类型打印次数——前端打印机打印成功后更新;
如需强并发控制可参考:[套打.常见问题.打印次数强并发控制方案](https://vip.kingdee.com/article/578980548580997888)
【跟踪单据打印次数变化的数据库触发器】
以采购合同的单据打印次数和单据类型打印次数为例,增加触发器,监控字段变化逻辑;
在正式环境部署前,务必在测试环境验证触发器逻辑,并根据自己的业务对象和字段名调整触发器关联的逻辑
```sql
--<0>生成根据记录临时表
select convert(varchar(50),fid) as fid, convert(varchar(50),'') as updateop, F_UNW_PrintTimes_qtr as oldVal, F_UNW_PrintTimes_qtr as newVal,
GETDATE() as UpdateTime,CONVERT(varchar(max),'') as ExecSql
into tmp_log_printtimeupdate
from T_PUR_CONTRACT where 1=0;
```
```sql
--<1>创建单据的打印次数修改触发器
create TRIGGER trg_bill_printtimeupinsert
on T_PUR_CONTRACT
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
BEGIN
-- 插入修改记录到tmp_log_printtimeupdate表
DECLARE @STATMT AS VARCHAR(max)
DECLARE @strSQL AS VARCHAR(100)
SET @strSQL='DBCC INPUTBUFFER('+CAST(@@SPID AS VARCHAR(50))+')'
CREATE TABLE #STATEMENT_BILLINSERT (C1 VARCHAR(50),C2 VARCHAR(50),C3 VARCHAR(5000))
INSERT INTO #STATEMENT_BILLINSERT EXEC(@strSQL)
SELECT @STATMT = C3 FROM #STATEMENT_BILLINSERT
INSERT INTO tmp_log_printtimeupdate (fid, updateop, oldVal, newVal, UpdateTime,ExecSql) -- 这里替换为你t_bos_log表中的列名
SELECT
i.fid, -- 假设tmp_log_printtimeupdate有一个主键或唯一标识列名为id
'bill_insert',
0 AS OldValue,
i.F_UNW_PrintTimes_qtr AS NewValue,
GETDATE() AS UpdateTime, -- 记录修改时间
@STATMT
FROM
inserted i
END
END
create TRIGGER trg_bill_printtimeupdate
ON T_PUR_CONTRACT
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- 检查是否修改了F_UNW_PrintTimes_qtr字段
IF UPDATE(F_UNW_PrintTimes_qtr)
BEGIN
-- 插入修改记录到tmp_log_printtimeupdate表
DECLARE @STATMT AS VARCHAR(max)
DECLARE @strSQL AS VARCHAR(100)
SET @strSQL='DBCC INPUTBUFFER('+CAST(@@SPID AS VARCHAR(50))+')'
CREATE TABLE #STATEMENT_BillUPDATE (C1 VARCHAR(50),C2 VARCHAR(50),C3 VARCHAR(5000))
INSERT INTO #STATEMENT_BillUPDATE EXEC(@strSQL)
SELECT @STATMT = C3 FROM #STATEMENT_BillUPDATE
INSERT INTO tmp_log_printtimeupdate (fid, updateop, oldVal, newVal, UpdateTime,ExecSql) -- 这里替换为你t_bos_log表中的列名
SELECT
d.fid, -- 假设tmp_log_printtimeupdate有一个主键或唯一标识列名为id
'bill_update',
d.F_UNW_PrintTimes_qtr AS OldValue,
i.F_UNW_PrintTimes_qtr AS NewValue,
GETDATE() AS UpdateTime, -- 记录修改时间
@STATMT
FROM
inserted i
INNER JOIN
deleted d ON i.FID = d.FID; -- 使用主键或唯一标识列进行连接
END
END;
```
```sql
--<2>创建单据类型的打印次数修改触发器
create TRIGGER trg_billtype_printtimeinsert
ON T_BAS_BILLPRINTCONTROL
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT 1 FROM inserted WHERE FFORMID = 'PUR_Contract')
BEGIN
-- 插入修改记录到tmp_log_printtimeupdate表
DECLARE @STATMT AS VARCHAR(max)
DECLARE @strSQL AS VARCHAR(100)
SET @strSQL='DBCC INPUTBUFFER('+CAST(@@SPID AS VARCHAR(50))+')'
CREATE TABLE #STATEMENT_BILLTYPEINSERT (C1 VARCHAR(50),C2 VARCHAR(50),C3 VARCHAR(5000))
INSERT INTO #STATEMENT_BILLTYPEINSERT EXEC(@strSQL)
SELECT @STATMT = C3 FROM #STATEMENT_BILLTYPEINSERT
INSERT INTO tmp_log_printtimeupdate (fid, updateop, oldVal, newVal, UpdateTime,ExecSql) -- 这里替换为你t_bos_log表中的列名
SELECT
i.FBILLID, -- 假设tmp_log_printtimeupdate有一个主键或唯一标识列名为id
'billType_insert',
0 AS OldValue,
i.FPRINTEDCOUNT AS NewValue,
GETDATE() AS UpdateTime, -- 记录修改时间
@STATMT
FROM
inserted i
END
END;
create TRIGGER trg_billtype_printtimeupdate
ON T_BAS_BILLPRINTCONTROL
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- 检查是否修改了F_UNW_PrintTimes_qtr字段
IF UPDATE(FPRINTEDCOUNT) and EXISTS(SELECT 1 FROM inserted WHERE FFORMID = 'PUR_Contract')
BEGIN
-- 插入修改记录到tmp_log_printtimeupdate表
DECLARE @STATMT AS VARCHAR(max)
DECLARE @strSQL AS VARCHAR(100)
SET @strSQL='DBCC INPUTBUFFER('+CAST(@@SPID AS VARCHAR(50))+')'
CREATE TABLE #STATEMENT_BILLTYPEUPDATE (C1 VARCHAR(50),C2 VARCHAR(50),C3 VARCHAR(5000))
INSERT INTO #STATEMENT_BILLTYPEUPDATE EXEC(@strSQL)
SELECT @STATMT = C3 FROM #STATEMENT_BILLTYPEUPDATE
INSERT INTO tmp_log_printtimeupdate (fid, updateop, oldVal, newVal, UpdateTime,ExecSql) -- 这里替换为你t_bos_log表中的列名
SELECT
d.FBILLID, -- 假设tmp_log_printtimeupdate有一个主键或唯一标识列名为id
'billType_update',
d.FPRINTEDCOUNT AS OldValue,
i.FPRINTEDCOUNT AS NewValue,
GETDATE() AS UpdateTime, -- 记录修改时间
@STATMT
FROM
inserted i
INNER JOIN
deleted d ON i.FID = d.FID; -- 使用主键或唯一标识列进行连接
END
END;
```
触发器监控打印次数变化效果
