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

2.4 库存管理

 

2.4.1 库龄分析

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

主界面 (如图2.4.1图1)。

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

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

主界面:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenNtMTM2NzY3MzQ5NzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

2.4.1(图1)

筛选查询框:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenNtMTM2NzY3MzQ5NzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

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)   --创建暂时表
       [email protected]出入库流水表
      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事件中绑定的数据

截图效果(在主界面点击相应的产品相应的仓库的具体库龄):

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenNtMTM2NzY3MzQ5NzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

 

截图效果(具体库龄的主界面):

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenNtMTM2NzY3MzQ5NzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >

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

 

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

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

 

代码:

(一)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; //为出库
               }
            }
        }

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

时间: 2024-10-28 15:46:12

用友ERP T6技术解析(六) 库龄分析的相关文章

爬虫技术(六)-- 使用HtmlAgilityPack获取页面链接(附c#代码及插件下载)

菜鸟HtmlAgilityPack初体验...弱弱的代码... Html Agility Pack是一个开源项目,为网页提供了标准的DOM API和XPath导航.使用WebBrowser和HttpWebRequest下载的网页可以用Html Agility Pack来解析. HtmlAgilityPack的文档是CHM格式的,有时会无法正常阅读CHM格式的文件.如果是IE不能链接到您请求的网页或者打开后"页面无法显示".请在要打开的CHM文件上右击属性,会在底下属性多了个"

保驾11.11 京东多中心交易系统技术解析

保驾11.11 京东多中心交易系统技术解析 2015-11-12 程序员的那些事 来源:IT168 ,作者:刘策 一年一度的“11.11”电商节购物狂欢季,各大电商平台也纷纷摩拳擦掌准备大干一场.但是网友消费热情的上涨不免对电商平台后端的数据中心提出更高的要求,许多消费者或许还记得几年前由于系统原因造成的卡单.丢单等事情,大大影响了用户体验.为此,近年来各家电商也都提前准备应对策略,积极的寻求瞬间大流量的解决办法. 日前,京东召开11.11技术备战大会,详细介绍了京东如何应对即将到来的“11.1

学习PHP爬虫--《Webbots、Spiders和Screen Scrapers:技术解析与应用实践(原书第2版)》

<Webbots.Spiders和Screen Scrapers:技术解析与应用实践(原书第2版)> 译者序 前言 第一部分 基础概念和技术 第1章 本书主要内容3 1.1 发现互联网的真正潜力3 1.2 对开发者来说3 1.2.1 网络机器人开发者是紧缺人才4 1.2.2 编写网络机器人是有趣的4 1.2.3 网络机器人利用了“建设性黑客”技术4 1.3 对企业管理者来说5 1.3.1 为业务定制互联网5 1.3.2 充分利用公众对网络机器人的经验不足5 1.3.3 事半功倍6 1.4 结论

对比NetSuite与用友ERP系统之间的区别以及优缺点!

目前国内的中小企业广泛采用国产ERP,主要是因为这些软件实施成本相对于更低,也更符合国内需求.然而,这仅仅停留在表面,像用友U8或NC系统由于其隐形成本高,配置复杂,缺乏可扩展性,会为企业带来一定的负担. 在这篇文章里,我们一起来了解一下为什么用友ERP系统会让中国的企业愈敢头痛,同时也一起来关注一个用友ERP无法实现的新型云计算ERP解决方案. 软件架构与硬件部署 传统ERP如用友的U8系列,NC系列都是基于C/S或者C/S结构与B/S混合使的软件,需要部署于服务器端.或者同时需要安装客户端软

《现代前端技术解析》第七章读书笔记

<现代前端技术解析>是张成文写的一本书,2017年4月出版的.先看的最后一章(第七章),第七章主要讲的是未来前端技术的发展趋势及如何成为一名优秀的前端工程师. 过去几年,前端主流技术框架发展极快,在填补了原有技术框架空白和不足的同时也渐渐趋于成熟.未来前端的发展方向主要是等待下一个风口的到来,可能是VR丶人工智能或者其他.就前端应用开发方向来讲,MVVM丶Virtual DOM和同构的技术解决方案依然会延续发展一段时间,而且这段时间内前端框架技术的变化将不会像原来一样具有颠覆性.当MVVM丶V

TerarkDB 数据库的性能报告与技术解析

相信很多人都看过火爆的美剧<硅谷>,里面描述的未来科技就是,可以在压缩的数据上作检索,而无需事先将数据解压.在现实中,我们就在研发这种技术.基于这项核心技术,我们对外发布了存储引擎产品 TerarkDB,这个产品具有极高的技术壁垒.我们的目标就是超越 Facebook 的 RocksDB,Google的 LevelDB,MongoDB 的 Wiredtiger,作出世界上性能最好的存储引擎. TerarkDB 简介 TerarkDB 是一个拥有极高性能和数据压缩率的存储引擎.使用方法类似Fac

Hystrix线程隔离技术解析-线程池(转)

认识Hystrix Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程隔离.信号量隔离.降级策略.熔断技术. 在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等.我们要构建稳定.可靠的分布式系统,就必须要有这样一套容错方法. 本文主要讨论线程隔离技术. 为什么要做线程隔离 比如我们现在有3个业务调用分别是查询订单.查询商品.查询用户,且这三个业务请求都是依赖第三方服务-订单服务.商品服

Elasticsearch技术解析与实战 PDF (内含目录)

Elasticsearch技术解析与实战 下载地址:https://pan.baidu.com/s/1q46lwAqzbUMs0qbKyBNBqg 关注微信公众号获取提取码: 输入:esjs     获取提取码.                                   介绍: Elasticsearch是一个强[0大0]的搜索引擎,提供了近实时的索引.搜索.分析功能.本书作者根据自己多年的开发经验,总结了使用和开发Elasticsearch的实战经验.本书全面介绍Elasticsea

互联网DSP广告系统架构及关键技术解析

互联网DSP广告系统架构及关键技术解析 宿逆 关注 1.9 2017.10.09 17:05* 字数 8206 阅读 10271评论 2喜欢 60 广告和网络游戏是互联网企业主要的盈利模式 广告是广告主通过媒体以尽可能低成本的方式与用户达成接触的商业行为.也就是说按照某种市场意图接触相应人群,影响其中潜在用户,使其选择广告主产品的几率增加,或对广告主品牌产生认同,通过长期的影响逐步形成用户对品牌的转化. 一个好的DSP系统需要满足: 拥有强大的RTB(Real-Time Bidding)的基础设