用友ERP T6技术解析(六) 库龄分析

2.4 库存管理

 

2.4.1 库龄分析

介绍:库存账龄是在某时间节点,某种或某类存货的库存时间的加权平均值,跟库存周转率关系明显,库存周转率越高,库存账龄越低,但是二者又不是反比关系,不能简单把库存账龄看成库存周转率的一个衍生指标来对待 ,

主界面 (如图2.4.1图1)。

目的:一、库存成本的控制。二、存货跌价准备计提。

功能:【全部导出】将当前页的全部仓库对应的全部产品导出到Excel文档。【选择导出】将当前页选择的的产品导出到Excel文档。【查询】多条件筛选查询数据(如图2.4.1 图2)。【定位】查询某产品定位到某行,如果产品在多个仓库,可以选择下条定位(如图2.4.2 图3)。

 

 

 

主界面:

2.4.1(图1)

 

筛选查询框:

2.4.2(图2)

 

 

定位查询框:

2.4.3(图3)

 

从界面上可以看到00我们这里用到的控件有

控件名称

说明

日期控件(DateTimePicker)

控件可以在工具箱直接拖动至窗体,拖至窗体后右击属性可以修改控件的样式和各种属性,还可以编辑事件。

下拉框(ComboBox)

文本(TextBox)

按钮(Button)

表格(DataGridView)

复选框(CheckBox)

 

功能实现:

第一步:数据库

1、表与关系

2.4.4(图4)

 

 

表1:  出入库记录明细表(InAndOutOfInventoryRecordList)

列名

数据类型

主键/外键

说明

InAndOutOfInventoryRecordListID

int - Identity

主键

出入库记录明细ID

Quantity

decimal (18, 3)

 

数量

TheUnitPrice

decimal (18, 3)

 

单价

InAndOutOfInventoryRecordID

int

外键

存货ID

TheInventoryID

int

外键

出入库存记录ID

 

表2:  出入库记录表(InAndOutOfInventoryRecord)

列名

数据类型

主键/外键

说明

InAndOutOfInventoryRecordID

int - Identity

主键

出入库存记录ID

WarehouseID_Dispatch

int

外键

仓库ID_出库

ForTheTypeID

int

外键

出入库类型ID

WarehouseInventory_ID

int

外键

仓库ID_入库

OoperateDate

datetime

 

操作日期

 

 

2、模糊查询匹配

第一步:界面层(UIL)代码,写在查询按钮点击事件

截图效果:

首先选择好模糊匹配定位(比如输入“双”字,如果选择左模糊,则查出“双XX”的产品,如果选择右模糊,则查出“XX双”,如果选择包含可以为左、右模糊加上“XX双XX”,如果是精确查询,则为“双”的产品)

代码:

private voidbtnFixedPosition_Click(object sender, EventArgs e)
        {
            stringstrRowFilter = "";   //查询条件
            stringstrProductName = txtProductName1.Text.Trim();  //定位到筛选后的一行
            if(strProductName == "") { return; }
            if(radLeft.Checked)    //左模糊
            {
                strRowFilter = string.Format("产品名称 like '%{0}'", strProductName.Trim());
            }
            else
            {
                if(radRight.Checked)  //右模糊
                {
                    strRowFilter = string.Format("产品名称 like '{0}%'", strProductName.Trim());
                }
                else
                {
                    if(radContain.Checked)  //包含模糊
                    {
                        strRowFilter = string.Format("产品名称 like '%{0}%'", strProductName.Trim());
                    }
                    else       //精确查询
                    {
                        strRowFilter = string.Format("产品名称 like '{0}'", strProductName.Trim());
                    }
                }
            }
            dvtest = newDataView(dtExisting) { RowFilter =strRowFilter };
            dttest = dvtest.ToTable();
            if(dttest.Rows.Count > 1)  //是否筛选后有一行以上
            {
                btnNext.Enabled = true;  //下一个  按钮 启用
            }
            else
            {
                btnNext.Enabled = false;  //下一个  按钮 不启用
            }
            intTpage = 0;
            FixedPosition(intTpage);
        }
 


 

3、库龄明细查询分析(根据产品ID与对应的存库进行分析)

第一步:数据库的存储过程

if(@Type='btnCountAnalysis_Click_SELECTBeLaidUpQuantity')  --查询入库量计算库龄账龄
   BEGIN
   DECLARE @出入库流水表 TABLE (产品名称 char(30),出入库时间 nchar(10), 出入库数量 decimal,时间 DATETIME)   --创建临时表
       INSERT@出入库流水表
      SELECT LTRIM(RTRIM(TheProductTable.ProductName)) AS 产品名称,
      CONVERT(nchar(10),InAndOutOfInventoryRecord.OoperateDate , 20) AS 出入库时间,
       LTRIM(RTRIM(CAST(-InAndOutOfInventoryRecordList.Quantity AS DECIMAL))) AS 出入库数量,
      InAndOutOfInventoryRecord.OoperateDate AS 时间
      FROM  InAndOutOfInventoryRecordListINNER JOIN
      InAndOutOfInventoryRecord ON InAndOutOfInventoryRecordList.InAndOutOfInventoryRecordID= InAndOutOfInventoryRecord.InAndOutOfInventoryRecordIDINNER JOIN
      TheInventoryTable ON InAndOutOfInventoryRecordList.TheInventoryID = TheInventoryTable.TheInventoryID INNER JOIN
      TheProductTable ON TheInventoryTable.ProductID = TheProductTable.ProductID
      WHERE InAndOutOfInventoryRecord.WarehouseID_Dispatch!= 0 AND
      InAndOutOfInventoryRecordList.TheInventoryID IN
      (SELECT TheInventoryTable.TheInventoryID AS 存货ID
      FROM  TheInventoryTableINNER JOIN
      TheProductTable ON TheInventoryTable.ProductID = TheProductTable.ProductID
      WHERE TheProductTable.ProductID = 3 AND TheInventoryTable.WarehouseID = 1)  --产品ID、仓库ID
      UNION ALL
      SELECT LTRIM(RTRIM(TheProductTable.ProductName)) AS 产品名称,
      CONVERT(nchar(10),InAndOutOfInventoryRecord.OoperateDate , 20) AS 出入库时间,
       LTRIM(RTRIM(CAST(InAndOutOfInventoryRecordList.Quantity AS DECIMAL))) AS 出入库数量,
      InAndOutOfInventoryRecord.OoperateDate AS 时间
      FROM  InAndOutOfInventoryRecordListINNER JOIN
      InAndOutOfInventoryRecord ON InAndOutOfInventoryRecordList.InAndOutOfInventoryRecordID= InAndOutOfInventoryRecord.InAndOutOfInventoryRecordIDINNER JOIN
      TheInventoryTable ON InAndOutOfInventoryRecordList.TheInventoryID = TheInventoryTable.TheInventoryID INNER JOIN
      TheProductTable ON TheInventoryTable.ProductID = TheProductTable.ProductID
      WHERE InAndOutOfInventoryRecord.WarehouseInventory_ID!= 0 AND
      InAndOutOfInventoryRecordList.TheInventoryID IN
      (SELECT TheInventoryTable.TheInventoryID AS 存货ID
      FROM  TheInventoryTableINNER JOIN
      TheProductTable ON TheInventoryTable.ProductID = TheProductTable.ProductID
      WHERE TheProductTable.ProductID = @ProductID AND TheInventoryTable.WarehouseID = @WarehouseID)  --产品ID、仓库ID
      ORDER BYInAndOutOfInventoryRecord.OoperateDate;
     
        SELECT 产品名称,库龄,CASE WHEN 出入库数量 > 数量 THEN 数量 ELSE 出入库数量 END AS数量
      FROM (
            SELECT 产品名称,
            DATEDIFF(DAY,出入库时间,GETDATE()) AS 库龄,   --与今天相比,计算出相差的天数
            出入库数量,
            (
                SELECT ISNULL(SUM(CAST(出入库数量 AS DECIMAL)),0)
                FROM @出入库流水表
                WHERE 产品名称 =(SELECT ProductName FROM TheProductTable WHERE TheProductTable.ProductID = @ProductID)
                AND 出入库时间 <= GETDATE() AND
                (出入库时间 <= 出入库流水表.出入库时间 OR(出入库时间 > 出入库流水表.出入库时间 AND 出入库数量 < 0))
            )AS数量
            FROM  @出入库流水表 AS 出入库流水表
            WHERE 产品名称 =(SELECT ProductName FROM TheProductTable WHERE TheProductTable.ProductID = @ProductID) and 出入库时间 <= GETDATE() and 出入库数量 > 0
         ) as计算表
      WHERE 数量 > 0
      SELECT *FROM @出入库流水表
   END


 

第二步:逻辑层(BLL)代码

        ///<summary>
        ///查询入库量计算库龄账龄
        ///</summary>
        ///<param name="intProductID">产品ID</param>
        ///<param name="intWarehouseID">仓库ID</param>
        ///<returns></returns>
        [OperationContract]
        public DataSetbtnCountAnalysis_Click_SELECTBeLaidUpQuantity(intintProductID, int intWarehouseID)
        {
            SqlParameter[] SQlCMDpas = {
                                             newSqlParameter("@Type",SqlDbType.Char),
                                             new SqlParameter("@ProductID", SqlDbType.Int),//产品ID
                                             new SqlParameter("@WarehouseID", SqlDbType.Int),//仓库ID
                                        };
           SQlCMDpas[0].Value = "btnCountAnalysis_Click_SELECTBeLaidUpQuantity";
           SQlCMDpas[1].Value = intProductID;
           SQlCMDpas[2].Value = intWarehouseID;
            return myDALMethod.QueryDataSet("InventoryManage_frm_StockLookIntoTheDistance",SQlCMDpas);
        }


 

第三步:界面层(UIL)代码,在详细库龄窗体的Load事件中绑定的数据

截图效果(在主界面点击对应的产品对应的仓库的详细库龄):

 

截图效果(详细库龄的主界面):

左边为产品对应的库龄与及对应库龄的数量,右边为对应产品的出入库情况(时间、数量)

 

截图效果(点击相同库龄合并数量):

将相同库龄的数量加起来(为什么出现相同库龄?因为在某天对该产品的进出次数多!)

 

代码:

(一)Load事件:

DataSet dsAgeAnalysis =myfrm_StockLookIntoTheDistance.btnCountAnalysis_Click_SELECTBeLaidUpQuantity(intProductID,intWarehouseID);
           dgvInventoryAgeAnalysis.DataSource = dsAgeAnalysis.Tables[0];  //查询库龄
           dgvDiscrepancyAgeAnalysis.DataSource = dsAgeAnalysis.Tables[1];  //详细出入明细
           ChangeColour();  //出库标识 入库 标识 颜色

 

 

(二) 合计数量

  #region 合计
        ///<summary>
        ///合计
        ///</summary>
        ///<param name="sender"></param>
        ///<param name="e"></param>
        private voidbtnTotal_Click(object sender, EventArgs e)
        {
           listAgeAnalysis.Clear();  //重新点击时,清空库龄集合
            DataTable dtSumAgeAnalysis = new DataTable();   //保存合计的库龄
           dtSumAgeAnalysis = ((DataTable)(dgvInventoryAgeAnalysis.DataSource)).Clone();
            for (int intRows = 0;intRows < dgvInventoryAgeAnalysis.Rows.Count; intRows++)
            {
               if (!listAgeAnalysis.Exists(i => i ==Convert.ToInt32(dgvInventoryAgeAnalysis.Rows[intRows].Cells["库龄"].Value)))
               {
                   listAgeAnalysis.Add(Convert.ToInt32(dgvInventoryAgeAnalysis.Rows[intRows].Cells["库龄"].Value));
                   dtSumAgeAnalysis.Rows.Add();
                   dtSumAgeAnalysis.Rows[dtSumAgeAnalysis.Rows.Count - 1]["产品名称"] =dgvInventoryAgeAnalysis.Rows[intRows].Cells["产品名称"].Value;
                   dtSumAgeAnalysis.Rows[dtSumAgeAnalysis.Rows.Count - 1]["库龄"] =dgvInventoryAgeAnalysis.Rows[intRows].Cells["库龄"].Value;
                   dtSumAgeAnalysis.Rows[dtSumAgeAnalysis.Rows.Count - 1]["数量"] = 0;
               }
               if (listAgeAnalysis.Exists(i => i == Convert.ToInt32(dgvInventoryAgeAnalysis.Rows[intRows].Cells["库龄"].Value)))
               {
                   dtSumAgeAnalysis.Rows[dtSumAgeAnalysis.Rows.Count - 1]["数量"] = Convert.ToInt32(dtSumAgeAnalysis.Rows[dtSumAgeAnalysis.Rows.Count- 1]["数量"])
                        + Convert.ToInt32(dgvInventoryAgeAnalysis.Rows[intRows].Cells["数量"].Value);
               }
            }
           dgvInventoryAgeAnalysis.DataSource = dtSumAgeAnalysis;
        }
       #endregion
 


 

(三)出库标识 入库 标识 颜色

///<summary>
        ///出库标识 入库 标识 颜色
        ///</summary>
        void ChangeColour()
        {
            for (int intRows = 0;intRows < dgvDiscrepancyAgeAnalysis.Rows.Count; intRows++)
            {
               if (Convert.ToInt32(dgvDiscrepancyAgeAnalysis.Rows[intRows].Cells["出入库数量"].Value) > 0)
               {
                    dgvDiscrepancyAgeAnalysis.Rows[intRows].DefaultCellStyle.BackColor= Color.Gold;  //为入库
               }
               else
               {
                   dgvDiscrepancyAgeAnalysis.Rows[intRows].DefaultCellStyle.BackColor = Color.OldLace; //为出库
               }
            }
        }



                                                                                                                                                                                                以上技术仅供参考,禁止用于商业用途,上述内容不代表用友立场!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值