用友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" alt="">
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事件中绑定的数据
截图效果(在主界面点击相应的产品相应的仓库的具体库龄):
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenNtMTM2NzY3MzQ5NzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
截图效果(具体库龄的主界面):
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenNtMTM2NzY3MzQ5NzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
左边为产品相应的库龄与及相应库龄的数量,右边为相应产品的出入库情况(时间、数量)
截图效果(点击同样库龄合并数量):
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenNtMTM2NzY3MzQ5NzAw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
将同样库龄的数量加起来(为什么出现同样库龄?由于在某天对该产品的进出次数多。)
代码:
(一)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; //为出库
}
}
}
以上技术仅供參考。禁止用于商业用途,上述内容不代表用友立场!
用友ERP T6技术解析(六) 库龄分析的更多相关文章
- vue技术解析六之生命周期函数
- 学习PHP爬虫--《Webbots、Spiders和Screen Scrapers:技术解析与应用实践(原书第2版)》
<Webbots.Spiders和Screen Scrapers:技术解析与应用实践(原书第2版)> 译者序 前言 第一部分 基础概念和技术 第1章 本书主要内容3 1.1 发现互联网的真 ...
- 干货|爱奇艺CDN巡检系统技术解析
小结: 1. 中心处理系统 /1/将定制后的巡检任务拆分,通过配置与任务分发系统.CMDB*( configuration management database)将派发到边缘拨测系统/2/处理边缘拨 ...
- Hystrix线程隔离技术解析-线程池(转)
认识Hystrix Hystrix是Netflix开源的一款容错框架,包含常用的容错方法:线程隔离.信号量隔离.降级策略.熔断技术. 在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有 ...
- 互联网DSP广告系统架构及关键技术解析
互联网DSP广告系统架构及关键技术解析 宿逆 关注 1.9 2017.10.09 17:05* 字数 8206 阅读 10271评论 2喜欢 60 广告和网络游戏是互联网企业主要的盈利模式 广告是广告 ...
- 我是如何一步步编码完成万仓网ERP系统的(六)产品库设计 2.百度Ueditor编辑器
https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...
- Elasticsearch技术解析与实战 PDF (内含目录)
Elasticsearch技术解析与实战 介绍: Elasticsearch是一个强[0大0]的搜索引擎,提供了近实时的索引.搜索.分 ...
- elasticsearch技术解析与实战ES
elasticsearch技术解析与实战ES 下载地址: https://pan.baidu.com/s/1NpPX05C0xKx_w9gBYaMJ5w 扫码下面二维码关注公众号回复100008 获取 ...
- Tensor Core技术解析(下)
Tensor Core技术解析(下) 让FP16适用于深度学习 Volta的深度学习能力是建立在利用半精度浮点(IEEE-754 FP16)而非单精度浮点(FP32)进行深度学习训练的基础之上. 该能 ...
随机推荐
- c18---数组和指针
// // main.c // day09 #include <stdio.h> int main(int argc, const char * argv[]) { ; int *numP ...
- hdu 1002(大数)
A + B Problem II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- The Triangle--nyoj 18
The Triangle 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure ...
- Android平台下的TCP/IP传输(客户端)
在工科类项目中,嵌入式系统与软件系统或后台数据库之间的信息传输是实现“物联网”的一种必要的途径,对已简单概念的物联网,通常形式都是一个单片机/嵌入式系统实现数据的采集及其处理,通过蓝牙,wifi或者是 ...
- iOS布局---pch头文件设置和字号适配
由于4s,5s,6,6p,界面尺寸差别过大,如果在界面上,只是用同一个字号,在4s和5s上就会略显偏大,而在6p上就会显小.并且ios9系统原生字体相较于ios8和之前原生字体略粗,在字号上也错了一号 ...
- JDK和Cglib实现动态代理实例及优缺点分析
Spring AOP使用的核心技术是动态代理,说到动态代理就不得不和设计模式中的代理模式联系起来,通过代理模式我们可以对目标类进行功能增强,在某个方法的执行前后增加一些操作,例如计算方法执行效率.打印 ...
- mybatis 高级映射和spring整合之高级映射(4)
mybatis 高级映射和spring整合之高级映射 ----------------学习结构-------------------- 0.0 对订单商品数据模型进行分析 1.0 高级映射 1.1 一 ...
- The AJAX response: XML, HTML, or JSON?
shared from: http://www.quirksmode.org/blog/archives/2005/12/the_ajax_respon.html 1. 返回XML文档 对返回的XML ...
- auto_ftp_sh
#!/usr/bin/env python # -*- coding:utf-8 -*- import paramiko import time mydate = time.strftime( ...
- 【转】【Oracle 集群】Linux下Oracle RAC集群搭建之Oracle DataBase安装(八)
原文地址:http://www.cnblogs.com/baiboy/p/orc8.html 阅读目录 目录 数据库安装 参考文献 相关文章 Oracle 11G RAC数据库安装(八) 概述:写 ...