• 用友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(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)代码,写在查询button点击事件

    截图效果:

    首先选择好模糊匹配定位(比方输入“双”字,假设选择左模糊。则查出“双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;  //下一个  button 启用
                }
                else
                {
                    btnNext.Enabled = false;  //下一个  button 不启用
                }
                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; //为出库
                   }
                }
            }



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

  • 相关阅读:
    zabbix验证微信
    free
    有名管道和无名管道
    shell实现并发控制
    TCP/IP协议簇 端口 三次握手 四次挥手 11种状态集
    自动化运维
    JSON对象(自定义对象)
    对象中属性的遍历、删除与成员方法
    对象间的赋值操作
    自定义类
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7049769.html
Copyright © 2020-2023  润新知