PB實現庫房批次收發料,先進先出管理功能
阿新 • • 發佈:2019-01-10
前幾天發了部落格,庫房先進先出,實現原理很簡單,寫了個儲存過程判斷批次。
文章地址: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.讓庫房經理看到
讓庫房的人看到的是不算臺賬的,因為並不是單子庫房的人一做單子就減庫存,是庫房經理稽核完了才算是真正減了庫存
。實現方式也是按照先進先出的原則。
和庫房做單的人不同,那個是不能更新庫房臺賬資料,前臺只能用遊標取數,放到他的收料明細裡,而不去寫入庫房臺賬
部門經理稽核這個實現起來,他稽核完成是要存進庫房臺賬的,用儲存過程會比較方便,程式碼如下:
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),
[email protected]_Qty decimal(30,2),
[email protected]_Qty decimal(30,2),
@Issue_Qty decimal(30,2),
[email protected]_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 [email protected] and [email protected]_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 [email protected]
and [email protected]_sn
and [email protected]_code;
set @Balance_Qty_Temp= @[email protected][email protected]_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 [email protected]
and [email protected]_sn
and [email protected]_code
and INV_Balance_Qty !=0
ORDER BY BATCH_NO ASC;
[email protected]_Iuuse_Qty
------發料單量>此批次收-發+返 本批次夠直接update
if @Issue_Qty<[email protected][email protected][email protected]_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET [email protected]_Qty,[email protected]_Qty
WHERE [email protected]
and [email protected]_sn
and [email protected]_code
and [email protected]_no1;
end
---本批次不夠update成最大,去找下一批次
if @Issue_Qty>@[email protected][email protected]_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET [email protected]_Qty1,INV_Balance_Qty=0
WHERE [email protected]
and [email protected]_sn
and [email protected]_code
and [email protected]_no1;
----獲取到累計發貨量
set @count_Iuuse_Qty [email protected]_Qty1- @Issue_Qty1
while (@[email protected]_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 [email protected]
and [email protected]_sn
and [email protected]_code
and [email protected]_no1+1;
if @[email protected]_Iuuse_Qty<@[email protected][email protected]_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET [email protected][email protected]_Iuuse_Qty,[email protected][email protected][email protected]_Iuuse_Qty
WHERE [email protected]
and [email protected]_sn
and [email protected]_code
and [email protected]_no1;
end
----把獲取量更最大值跳出迴圈
set @[email protected]_Qty;
---本批次不夠update成最大,去找下一批次
if @[email protected]_Iuuse_Qty>@[email protected][email protected]_Qty1
begin
UPDATE dbo.INV_WarehouseAccount
SET [email protected]_Qty1,INV_Balance_Qty=0
WHERE [email protected]
and [email protected]_sn
and [email protected]_code
and [email protected]_no1;
----獲取到累計發貨量
set @count_Iuuse_Qty [email protected]_Qty1- @Issue_Qty1
end
if (@[email protected]_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也比不過,實現這個功能沒有文獻可以參考,公司有程式碼。。。但是很難搞到,如果有更好的實現方法可以分享給我。