1. 程式人生 > >PB實現庫房批次收發料,先進先出管理功能

PB實現庫房批次收發料,先進先出管理功能

前幾天發了部落格,庫房先進先出,實現原理很簡單,寫了個儲存過程判斷批次。

文章地址: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也比不過,實現這個功能沒有文獻可以參考,公司有程式碼。。。但是很難搞到,如果有更好的實現方法可以分享給我。