版权声明:本文为作者原创,转载请务必注明出处! https://blog.csdn.net/qq_37545120/article/details/83987566
前几天发了博客,库房先进先出,实现原理很简单,写了个存储过程判断批次。
文章地址:https://blog.csdn.net/qq_37545120/article/details/83416526
现在我把先进先出的原理和大家分享一下,其实也是超简单,可能因为我是个小白,几百行代码写了三天哈哈哈。
首先库房的人跟管事儿的经理肯定都要审核单据。所以得分两种情况。
1.让库房做单子的人看到 2.让库房经理看到。
让库房做单子的人看到,首先他可能做完这个单子审核给他的部门经理,如果不分情况,这个发料单回退的话库房台账还得算库存。所以我分情况来写的
1.让库房做单子的人看到
让库房走发料单的人看,写了一个function:wf_selectmatfrommir
一开始打算写个结构体。后来想想用循环好像比较方便,代码如下,大家可以参考
long ll_row,ll_rows,ll_item
long ll_line
decimal ldec_unit_price,ldec_amount
string ls_po_sn, ls_material_code, ls_bin_sn
datawindow ldw_dw
//edit by zxx :2018-11-8 17:43:57
long ll_item2,ll_line2
string ls_material_code2,ls_po_sn2
decimal req_quantity,rec_price,req_balance_qty,ldec_totalissueqty
string ls_po_sn3,ls_item_code3,ls_batch_no3,ls_bin_sn3
long ll_findmateriallist,ll_mainlistnewrow
ll_rows = tab_1.tabpage_1.dw_requireitem.rowcount()
ldw_dw = tab_1.tabpage_1.dw_requireitem
//将选中需要导入的物资放到结构体中
us_materialforreceive lar_material[]
string ls_mirsn[] //MIR SN
string ls_mircode[] //MIR Code
//string ls_matcode
//处理选择的物资
//ll_item = 1
ldec_totalissueqty = 0 //该物资累计发料量
for ll_row = 1 to ll_rows
if ldw_dw.object.selectflag[ll_row] = 'Y' then
ls_material_code2 = ldw_dw.object.material_code[ll_row] //物资编码
ls_po_sn2 = ldw_dw.object.po_sn[ll_row]
req_quantity = ldw_dw.object.quantity[ll_row]
DECLARE INV_WarehouseAccount_Cur CURSOR FOR
SELECT po_sn,item_code,batch_no,bin_sn,price,inv_balance_qty
FROM INV_WarehouseAccount
WHERE db_center = :gs_dbname
AND po_sn = :ls_po_sn2
AND Item_Code = :ls_material_code2
and inv_balance_qty>0;
OPEN INV_WarehouseAccount_Cur;
//循环取到需求量
FETCH INV_WarehouseAccount_Cur INTO :ls_po_sn3,:ls_item_code3,:ls_batch_no3,:ls_bin_sn3,:rec_price,:req_balance_qty;
req_balance_qty = req_balance_qty - ldec_totalissueqty
do while sqlca.sqlcode=0
if req_quantity<=req_balance_qty then
// //查找界面中是否有该物资记录,如果有则覆盖
ll_findmateriallist = adw_issuedet.find(" material_sn = " +string(ldw_dw.object.material_sn[ll_row]),1,ll_rows)
// if ll_findmateriallist > 0 then
// ll_mainlistnewrow = ll_findmateriallist
// else
//ll_mainlistnewrow = adw_issuedet.insertrow(0)
// end if
ll_mainlistnewrow = adw_issuedet.insertrow(0)
adw_issuedet.object.line[ll_mainlistnewrow]=ll_line2
adw_issuedet.object.PO_SN[ll_mainlistnewrow]=ls_po_sn3
adw_issuedet.object.Material_SN[ll_mainlistnewrow]=ldw_dw.object.material_sn[ll_row]
adw_issuedet.object.Material_Code[ll_mainlistnewrow]=ls_item_code3
adw_issuedet.object.batch_no[ll_mainlistnewrow]=ls_batch_no3
adw_issuedet.object.Material_Name[ll_mainlistnewrow]=ldw_dw.object.material_name[ll_row]
adw_issuedet.object.Material_Desc[ll_mainlistnewrow]=ldw_dw.object.material_desc[ll_row]
adw_issuedet.object.Level_SN[ll_mainlistnewrow]='A'
adw_issuedet.object.UOM[ll_mainlistnewrow]=ldw_dw.object.uom[ll_row]
adw_issuedet.object.unit_price[ll_mainlistnewrow] = rec_price
adw_issuedet.object.Bin_SN[ll_mainlistnewrow] = ls_bin_sn3
adw_issuedet.object.quantity[ll_mainlistnewrow] = req_quantity
adw_issuedet.object.requirement_sn[ll_mainlistnewrow] = ldw_dw.object.requirement_sn[ll_row]
adw_issuedet.object.mir_code [ll_mainlistnewrow] = ldw_dw.object.requirement_code[ll_row]
ldec_totalissueqty += req_quantity
EXIT
end if
if req_quantity>req_balance_qty then
// //查找界面中是否有该物资记录,如果有则覆盖
ll_findmateriallist = adw_issuedet.find(" material_sn = " +string(ldw_dw.object.material_sn[ll_row]),1,ll_rows)
// if ll_findmateriallist > 0 then
// ll_mainlistnewrow = ll_findmateriallist
// else
ll_mainlistnewrow = adw_issuedet.insertrow(0)
// end if
adw_issuedet.object.line[ll_mainlistnewrow]=ll_line2
adw_issuedet.object.PO_SN[ll_mainlistnewrow]=ls_po_sn3
adw_issuedet.object.Material_SN[ll_mainlistnewrow]=ldw_dw.object.material_sn[ll_row]
adw_issuedet.object.Material_Code[ll_mainlistnewrow]=ls_item_code3
adw_issuedet.object.batch_no[ll_mainlistnewrow]=ls_batch_no3
adw_issuedet.object.Material_Name[ll_mainlistnewrow]=ldw_dw.object.material_name[ll_row]
adw_issuedet.object.Material_Desc[ll_mainlistnewrow]=ldw_dw.object.material_desc[ll_row]
adw_issuedet.object.Level_SN[ll_mainlistnewrow]='A'
adw_issuedet.object.UOM[ll_mainlistnewrow]=ldw_dw.object.uom[ll_row]
adw_issuedet.object.unit_price[ll_mainlistnewrow] = rec_price
adw_issuedet.object.Bin_SN[ll_mainlistnewrow] = ls_bin_sn3
adw_issuedet.object.quantity[ll_mainlistnewrow] =req_balance_qty
adw_issuedet.object.requirement_sn[ll_mainlistnewrow] = ldw_dw.object.requirement_sn[ll_row]
adw_issuedet.object.mir_code [ll_mainlistnewrow] = ldw_dw.object.requirement_code[ll_row]
ldec_totalissueqty += req_balance_qty
req_quantity -= req_balance_qty
end if
FETCH INV_WarehouseAccount_Cur INTO :ls_po_sn3,:ls_item_code3,:ls_batch_no3,:ls_bin_sn3,:rec_price,:req_balance_qty;
//req_balance_qty -= adw_issuedet.object.quantity[ll_mainlistnewrow]
loop
ldec_totalissueqty = 0 // 该物资累计发料量清零
CLOSE INV_WarehouseAccount_Cur;
end if
next
adw_issuedet.accepttext( )
adw_issuedet.groupcalc( )
adw_issuedet.sort( )
//更新行号
ll_rows = adw_issuedet.rowcount( )
for ll_line=1 to ll_rows
adw_issuedet.object.line[ll_line] = ll_line
end for
adw_issuedet.setredraw( true)
2.让库房经理看到
让库房的人看到的是不算台账的,因为并不是单子库房的人一做单子就减库存,是库房经理审核完了才算是真正减了库存
。实现方式也是按照先进先出的原则。
扫描二维码关注公众号,回复:
4854496 查看本文章
和库房做单的人不同,那个是不能更新库房台账数据,前台只能用游标取数,放到他的收料明细里,而不去写入库房台账
部门经理审核这个实现起来,他审核完成是要存进库房台账的,用存储过程会比较方便,代码如下:
USE [EBSDBClient]
GO
/****** Object: StoredProcedure [dbo].[SP_INV_IssueWarehouseAccount] Script Date: 11/12/2018 10:20:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_INV_IssueWarehouseAccount]
@dbname nvarchar(100),
@Issue_SN nvarchar(100),
@ischs char(1),
@error nvarchar(max) output
AS
declare
@po_sn nvarchar(100),
@item_code nvarchar(100),
--@Ini_Qty decimal(30,2),
--@Receive_Qty decimal(30,2),
@Issue_Qty decimal(30,2),
--@Check_Qty decimal(30,2),
---variable_Temp
@Receive_Qty_Temp decimal(30,2),
@Issue_Qty_Temp decimal(30,2),
@Return_Qty_Temp decimal(30,2),
@Balance_Qty_Temp decimal(30,2),
-----------累计发货量
@count_Iuuse_Qty decimal(30,2),
@batch_no1 nvarchar(2),
@Receive_Qty1 decimal(30,2),
@Return_Qty1 decimal(30,2),
@Issue_Qty1 decimal(30,2),
@Inv_Balance_Qty1 decimal(30,2);
BEGIN TRANSACTION
--定义开启游标
DECLARE INV_WarehouseAccount_Cur CURSOR FAST_FORWARD FOR
select det.po_sn,det.Material_Code,det.Quantity from inv_issueDet det where det.db_center=@dbname and det.Issue_sn=@Issue_SN;
OPEN INV_WarehouseAccount_Cur;
--循环取到需求量
FETCH NEXT FROM INV_WarehouseAccount_Cur INTO @po_sn,@item_code,@Issue_Qty;
WHILE @@FETCH_STATUS=0
BEGIN
---取台账物资量,判断公式:balanceQty=iniQty+receiveQty-IssueQty+returnQty iniQty默认为0
select @Receive_Qty_Temp =SUM(ACCT.Receive_Qty),@Issue_Qty_Temp=SUM(ACCT.Issue_Qty),@Return_Qty_Temp=SUM(ACCT.Return_Qty)
from dbo.INV_WarehouseAccount ACCT
where acct.DB_Center=@dbname
and ACCT.PO_SN=@po_sn
and ACCT.Item_Code=@item_code;
set @Balance_Qty_Temp= @Receive_Qty_Temp-@Issue_Qty_Temp+@Return_Qty_Temp
---库存不足,不允许审核通过,审核通过则继续执行
IF @Issue_Qty>@Balance_Qty_Temp
begin
print 'PO voucher Remaining Quantity not sufficient , Please check and confirm!!!!';
if @ischs='Y'
set @error='PO单剩余量不足,请核实确认!';
if @ischs='N'
set @error='PO voucher Remaining Quantity not sufficient , Please check and confirm!';
end
ELSE
--满足发料
BEGIN
SET ROWCOUNT 1
select @batch_no1=batch_no,@Receive_Qty1=Receive_Qty,@Issue_Qty1=Issue_Qty,@Return_Qty1=Return_Qty,@Inv_Balance_Qty1=INV_Balance_Qty
from dbo.INV_WarehouseAccount ACCT
where acct.DB_Center=@dbname
and ACCT.PO_SN=@po_sn
and ACCT.Item_Code=@item_code
and INV_Balance_Qty !=0
ORDER BY BATCH_NO ASC;
--@count_Iuuse_Qty
------发料单量>此批次收-发+返 本批次够直接update
if @Issue_Qty<=@Receive_Qty1-@Issue_Qty1+@Return_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET Issue_Qty=Issue_Qty+@Issue_Qty,INV_Balance_Qty=INV_Balance_Qty-@Issue_Qty
WHERE DB_Center=@dbname
and PO_SN=@po_sn
and Item_Code=@item_code
and Batch_No=@batch_no1;
end
---本批次不够update成最大,去找下一批次
if @Issue_Qty>@Receive_Qty1-@Issue_Qty1+@Return_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET Issue_Qty=@Receive_Qty1,INV_Balance_Qty=0
WHERE DB_Center=@dbname
and PO_SN=@po_sn
and Item_Code=@item_code
and Batch_No=@batch_no1;
----获取到累计发货量
set @count_Iuuse_Qty =@Receive_Qty1- @Issue_Qty1
while (@Issue_Qty-@count_Iuuse_Qty!=0)
begin
select @batch_no1=batch_no,@Receive_Qty1=Receive_Qty,@Issue_Qty1=Issue_Qty,@Return_Qty1=Return_Qty,@Inv_Balance_Qty1=INV_Balance_Qty
from dbo.INV_WarehouseAccount
where DB_Center=@dbname
and PO_SN=@po_sn
and Item_Code=@item_code
and Batch_No=@batch_no1+1;
if @Issue_Qty-@count_Iuuse_Qty<@Receive_Qty1-@Issue_Qty1+@Return_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET Issue_Qty=@Issue_Qty-@count_Iuuse_Qty,INV_Balance_Qty=@Inv_Balance_Qty1-@Issue_Qty+@count_Iuuse_Qty
WHERE DB_Center=@dbname
and PO_SN=@po_sn
and Item_Code=@item_code
and Batch_No=@batch_no1;
end
----把获取量更最大值跳出循环
set @count_Iuuse_Qty=@Issue_Qty;
---本批次不够update成最大,去找下一批次
if @Issue_Qty-@count_Iuuse_Qty>@Receive_Qty1-@Issue_Qty1+@Return_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET Issue_Qty=@Receive_Qty1,INV_Balance_Qty=0
WHERE DB_Center=@dbname
and PO_SN=@po_sn
and Item_Code=@item_code
and Batch_No=@batch_no1;
----获取到累计发货量
set @count_Iuuse_Qty =@Receive_Qty1- @Issue_Qty1
end
if (@Issue_Qty-@count_Iuuse_Qty!=0)
begin
break;
end;
end
end
--SET ROWCOUNT 0
END
FETCH NEXT FROM INV_WarehouseAccount_Cur INTO @po_sn,@item_code,@Issue_Qty;
END
CLOSE INV_WarehouseAccount_Cur;
DEALLOCATE INV_WarehouseAccount_Cur;
COMMIT TRANSACTION
BEGIN TRANSACTION
if @@ERROR=0
begin
set @error=''
commit
end
else
begin
if @ischs='Y'
set @error='保存失败,请联系系统管理员'
if @ischs='N'
set @error='Fail To Save, Please Contact Administrator!'
rollback
end
PB前台调用
Proc_Issue_Code =ldw_list.object.issue_code[ll_i]
DECLARE IssueWarehouseAccount PROCEDURE FOR SP_INV_IssueWarehouseAccount
@dbname=:gs_dbname,
@Issue_SN=:Proc_Issue_Code,
@ischs=:ls_ischs,
@error=:ls_error2 output;
EXECUTE IssueWarehouseAccount ;
FETCH IssueWarehouseAccount INTO :ls_error2;
CLOSE IssueWarehouseAccount ;
if gnvo_gf.of_isnull(ls_error2) then
if gb_chs then
ls_log="插入物资台账成功! "
else
ls_log="Insert Warehouse Account successfully !"
commit using sqlca;
end if
gf_log(ls_log)
commit using sqlca;
else
gf_errorbox(ls_error2)
end if
//end edit
小白一枚,以上仅供参考。PB这个语言虽说已经过时了,但是要是从开发效率的情况来说,没有任何语言要快的过PB,.NET也比不过,实现这个功能没有文献可以参考,公司有代码。。。但是很难搞到,如果有更好的实现方法可以分享给我。