552 lines
21 KiB
C#
552 lines
21 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using System.Windows.Forms.DataVisualization.Charting;
|
|
using JY.DAL;
|
|
using JY.Model;
|
|
using JY.Utility;
|
|
using MetroFramework.Forms;
|
|
|
|
namespace JY.Inspection.Frm
|
|
{
|
|
public partial class FrmStatistics : MetroForm
|
|
{
|
|
/// <summary>
|
|
/// 数据库访问接口
|
|
/// </summary>
|
|
private IDbHelper dbHelper = new OpSqlDataBase();
|
|
/// <summary>
|
|
/// 读取成功
|
|
/// </summary>
|
|
public bool isReadOK = true;
|
|
/// <summary>
|
|
/// Timer是否运行
|
|
/// </summary>
|
|
public bool isEnabled = false;
|
|
/// <summary>
|
|
/// chart图表Y轴的上限值
|
|
/// </summary>
|
|
int iChartHeight = 5000;
|
|
|
|
|
|
/// <summary>
|
|
/// 读取
|
|
/// </summary>
|
|
public System.Timers.Timer timerStatistics1;
|
|
/// <summary>
|
|
/// 读取24小时产能统计
|
|
/// </summary>
|
|
public System.Timers.Timer timer_HourProd;
|
|
|
|
/// <summary>
|
|
/// 投入产出饼状图显示委托
|
|
/// </summary>
|
|
/// <param name="xData"></param>
|
|
/// <param name="yData"></param>
|
|
private delegate void UpdateDataChart2(List<string> xData, List<int> yData);
|
|
/// <summary>
|
|
/// 各不良统计NG显示委托
|
|
/// </summary>
|
|
/// <param name="dt"></param>
|
|
private delegate void UpdateDataChart3(List<string> xData, List<int> yData);
|
|
/// <summary>
|
|
/// 不良统计项目
|
|
/// </summary>
|
|
List<ChartDataType> NGList = new List<ChartDataType>();
|
|
/// <summary>
|
|
/// 生产统计项目
|
|
/// </summary>
|
|
List<ChartDataType> ProductionList = new List<ChartDataType>();
|
|
|
|
|
|
public FrmStatistics()
|
|
{
|
|
InitializeComponent();
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 窗体实例
|
|
/// </summary>
|
|
private static FrmStatistics _instance;
|
|
internal static FrmStatistics Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
_instance = new FrmStatistics();
|
|
return _instance;
|
|
}
|
|
}
|
|
|
|
private void FrmStatistics_Load(object sender, EventArgs e)
|
|
{
|
|
|
|
//SetProductionList();
|
|
//OrgChart();
|
|
//GetValue();
|
|
//InitTimer();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化Timer控件
|
|
/// </summary>
|
|
internal void InitTimer()
|
|
{
|
|
|
|
OrgChart();
|
|
SetProductionList();
|
|
isEnabled = true;
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
///定义饼图和右上角柱状图显示类型
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
internal void SetProductionList()
|
|
{
|
|
//不良统计项目
|
|
NGList.Add(new ChartDataType() { DataType = "线扫扫码NG" });
|
|
NGList.Add(new ChartDataType() { DataType = "分档扫码NG" });
|
|
NGList.Add(new ChartDataType() { DataType = "侧面不良" });
|
|
NGList.Add(new ChartDataType() { DataType = "正极不良" });
|
|
NGList.Add(new ChartDataType() { DataType = "负极不良" });
|
|
//生产统计项目
|
|
ProductionList.Add(new ChartDataType() { DataType = "生产总数" });
|
|
ProductionList.Add(new ChartDataType() { DataType = "良品数" });
|
|
ProductionList.Add(new ChartDataType() { DataType = "不良数" });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chart控件初始化
|
|
/// </summary>
|
|
internal void OrgChart()
|
|
{
|
|
#region 24小时统计
|
|
chart1.Series.Clear();
|
|
chart1.Titles.Clear();
|
|
chart1.ChartAreas[0].AxisY.Minimum = 0;
|
|
chart1.ChartAreas[0].AxisY.Maximum = iChartHeight + 500;
|
|
|
|
ChartHelper.AddSeries(chart1, "投入", SeriesChartType.Column, Color.DodgerBlue, Color.Red, true);
|
|
ChartHelper.AddSeries(chart1, "产出", SeriesChartType.Column, Color.Lime, Color.Red, true);
|
|
ChartHelper.AddSeries(chart1, "优率", SeriesChartType.Spline, Color.Red, Color.Red);
|
|
|
|
ChartHelper.SetTitle(chart1, "当日每2小时投入与产出", new Font("微软雅黑", 18), Docking.Top, Color.Black);
|
|
ChartHelper.SetStyle(chart1, Color.White, Color.Black);
|
|
ChartHelper.SetLegend(chart1, Docking.Top, StringAlignment.Center, Color.White, Color.Black);
|
|
ChartHelper.SetXY(chart1, "时间", "数值", StringAlignment.Far, Color.Black, Color.Black, AxisArrowStyle.None, 1, 2);
|
|
ChartHelper.SetMajorGrid(chart1, Color.White, 20, 2);
|
|
#endregion
|
|
|
|
#region 数据统计
|
|
chartNgShow.Series.Clear();
|
|
chartNgShow.Titles.Clear();
|
|
chartNgShow.ChartAreas[0].AxisY.Minimum = 0;
|
|
chartNgShow.ChartAreas[0].AxisY.Maximum = iChartHeight + 500;
|
|
foreach (var item in NGList)
|
|
{
|
|
ChartHelper.AddSeries(chartNgShow, item.DataType, SeriesChartType.Column, Color.Red, Color.Red, true);
|
|
}
|
|
ChartHelper.SetTitle(chartNgShow, "各不良项", new Font("微软雅黑", 22), Docking.Top, Color.Black);
|
|
ChartHelper.SetStyle(chartNgShow, Color.White, Color.Black);
|
|
ChartHelper.SetLegend(chartNgShow, Docking.Top, StringAlignment.Center, Color.White, Color.Black);
|
|
ChartHelper.SetXY(chartNgShow, "不良项", "数值", StringAlignment.Far, Color.Black, Color.Black, AxisArrowStyle.None, 1, 2);
|
|
ChartHelper.SetMajorGrid(chartNgShow, Color.White, 20, 2);
|
|
#endregion
|
|
|
|
//投入产出统计
|
|
ChartHelper.SetTitle(chartToalShow, "投入产出", new Font("微软雅黑", 22), Docking.Top, Color.Black);
|
|
chartToalShow.Series[0].ChartType = SeriesChartType.Pie;//设置图表类型为饼图
|
|
//chart2.Series[0].CustomProperties="PieLabel"+"PieSize = 50";//设置饼图参数
|
|
chartToalShow.Series[0].CustomProperties = "DoughnutRadius=60, PieLabelStyle=Disabled, PieDrawingStyle=SoftEdge";
|
|
chartToalShow.Series[0]["PieLabelStyle"] = "Inside";//将文字移到外侧
|
|
chartToalShow.Series[0].XValueType = ChartValueType.String;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 读取PLC产能统计
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void TimerUpGetData()
|
|
{
|
|
if (!HomeForm.startup)
|
|
{
|
|
return;
|
|
}
|
|
if (isReadOK)
|
|
{
|
|
isReadOK = false;
|
|
GetValue();
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取图表数据
|
|
/// </summary>
|
|
public void GetValue()
|
|
{
|
|
try
|
|
{
|
|
if (isEnabled)
|
|
{
|
|
|
|
int ProdAllQty = HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg("HMI.生产总数");
|
|
int ProdOKQty = HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg("HMI.OK总数");
|
|
int ProdNGQty= HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg("HMI.NG总数");
|
|
int ProdSanNgQty = 123;//扫码NG
|
|
int ProdVolNgQty = 145;//电压NG
|
|
|
|
//從PLC讀取數據賦值給到NGList
|
|
ProductionList.Where(p => p.DataType == "生产总数").FirstOrDefault().DataCount = ProdAllQty;
|
|
ProductionList.Where(p => p.DataType == "良品数").FirstOrDefault().DataCount = ProdOKQty;
|
|
ProductionList.Where(p => p.DataType == "不良数").FirstOrDefault().DataCount = ProdNGQty;
|
|
|
|
|
|
|
|
//從PLC讀取數據賦值給到NGList
|
|
NGList.Where(p => p.DataType == "线扫扫码NG").FirstOrDefault().DataCount = ProdSanNgQty;
|
|
NGList.Where(p => p.DataType == "分档扫码NG").FirstOrDefault().DataCount = ProdSanNgQty;
|
|
NGList.Where(p => p.DataType == "侧面不良").FirstOrDefault().DataCount = ProdVolNgQty;
|
|
NGList.Where(p => p.DataType == "正极不良").FirstOrDefault().DataCount = ProdVolNgQty;
|
|
NGList.Where(p => p.DataType == "负极不良").FirstOrDefault().DataCount = ProdSanNgQty;
|
|
|
|
ShowChartData();
|
|
//------------------------------每小时产能------------------------------------------
|
|
string strErr = "";
|
|
DateTime dateTime = DateTime.Now;
|
|
string strDate = dateTime.ToString("yyyy-MM-dd");
|
|
int Hour = dateTime.Hour;
|
|
|
|
//读取PLC投入总数
|
|
int ProdCurrAllQty = GetToDayHourQty(Hour, true);
|
|
//读取PLC产出数
|
|
int ProdCurrOKQty = GetToDayHourQty(Hour, false);
|
|
HourprodEntity mh = new HourprodEntity();
|
|
mh.FDate = strDate;
|
|
mh.FHour = Hour;
|
|
mh.ProdIn = ProdCurrAllQty;
|
|
mh.ProdOut = ProdCurrOKQty;
|
|
mh.TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
|
var iResult = dbHelper.UpdateHourprodData(mh);
|
|
if (iResult <= 0)
|
|
{
|
|
MessageBox.Show("存储每小时产能失败" + strErr, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand);
|
|
LogHelper.Error("存储每小时产能失败" + strErr, new Exception("异常信息"));
|
|
}
|
|
isReadOK = true;
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Error(ex.Message, new Exception("异常信息"));
|
|
timerStatistics1.Enabled = false;
|
|
isReadOK = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 每小时产能读取处理
|
|
/// </summary>
|
|
/// <param name="hour"></param>
|
|
/// <param name="flag"></param>
|
|
/// <returns></returns>
|
|
private int GetToDayHourQty(int hour, bool flag)
|
|
{
|
|
try
|
|
{
|
|
string strAddr = "";
|
|
if (hour == 0)
|
|
{
|
|
hour = 24;
|
|
}
|
|
//else
|
|
//{
|
|
// hour = hour - 1;
|
|
//}
|
|
if (flag)//产出
|
|
{
|
|
strAddr = "W" + (1040 + hour);
|
|
}
|
|
else//良品数
|
|
{
|
|
strAddr = "W" + (1070 + hour);
|
|
}
|
|
int ProdNGQty = HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg(strAddr);//生产NG数量
|
|
return ProdNGQty;
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Error(ex.Message, new Exception("异常信息"));
|
|
MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 刷新饼图生产统计信息;刷新生产不良统计信息
|
|
/// </summary>
|
|
public void ShowChartData()
|
|
{
|
|
try
|
|
{
|
|
//不良类型统计
|
|
List<string> xData = NGList.Select(c => c.DataType).ToList();
|
|
List<int> yData = NGList.Select(c => c.DataCount).ToList();
|
|
ShowNGChart(xData, yData);
|
|
|
|
//生产总数统计
|
|
var xlist = ProductionList.Select(c => c.DataType).ToList();
|
|
var ylist = ProductionList.Select(c => c.DataCount).ToList();
|
|
ShowChartToal(xlist, ylist);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Error(ex.Message, new Exception("异常信息"));
|
|
MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 投入产出饼状图显示
|
|
/// </summary>
|
|
/// <param name="xData"></param>
|
|
/// <param name="yData"></param>
|
|
private void ShowChartToal(List<string> xData, List<int> yData)
|
|
{
|
|
if (chartToalShow.InvokeRequired)
|
|
{
|
|
UpdateDataChart2 c = new UpdateDataChart2(ShowChartToal);
|
|
this.Invoke(c, new object[] { xData, yData });
|
|
}
|
|
else
|
|
{
|
|
chartToalShow.Series[0].Points.DataBindXY(xData, yData);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 不良数统计显示
|
|
/// </summary>
|
|
/// <param name="dt"></param>
|
|
private void ShowNGChart(List<string> xData, List<int> yData)
|
|
{
|
|
if (chartNgShow.InvokeRequired)
|
|
{
|
|
UpdateDataChart3 c = new UpdateDataChart3(ShowNGChart);
|
|
this.Invoke(c, new object[] { xData, yData });
|
|
}
|
|
else
|
|
{
|
|
chartNgShow.Series[0].Points.DataBindXY(xData, yData);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 读取产入产出
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
///
|
|
private void TimerUpHourProd()
|
|
{
|
|
try
|
|
{
|
|
if (isEnabled)
|
|
{
|
|
List<Chart24HourData> chart24Hours = new List<Chart24HourData>();
|
|
DateTime dtTime = DateTime.Now;
|
|
string strDate = dtTime.ToString("yyyy-MM-dd");
|
|
int Hour = dtTime.Hour;
|
|
var listTotal = dbHelper.GetProdTotal(strDate, 0);// 查询稼动率表中total数据
|
|
|
|
if (listTotal != null && listTotal.Count > 0)
|
|
{
|
|
for (int i = 1; i <= 12; i++)
|
|
{
|
|
if (!isEnabled)
|
|
{
|
|
break;
|
|
}
|
|
int j = i * 2;
|
|
int m = j - 2;
|
|
int n = j - 1;
|
|
//当前时段第一个小时
|
|
var hour1 = listTotal.Where(p => p.FHour == m).FirstOrDefault();
|
|
//当前时段第二个小时
|
|
var hour2 = listTotal.Where(p => p.FHour == n).FirstOrDefault();
|
|
int ProdALLQty = 0;
|
|
int ProdOKQty = 0;
|
|
int ProdNGQty = 0;
|
|
string strOkRatio = "0";
|
|
|
|
if (hour1 != null)
|
|
{
|
|
ProdALLQty += hour1.ProdIn;
|
|
ProdOKQty += hour1.ProdOut;
|
|
}
|
|
if (hour2 != null)
|
|
{
|
|
ProdALLQty += hour2.ProdIn;
|
|
ProdOKQty += hour2.ProdOut;
|
|
}
|
|
ProdNGQty = ProdALLQty - ProdOKQty;
|
|
if (ProdNGQty > 0)
|
|
{
|
|
strOkRatio = Math.Round((ProdOKQty * 1.0 / ProdALLQty) * 100, 2) + "%";
|
|
}
|
|
|
|
chart24Hours.Add(new Chart24HourData()
|
|
{
|
|
DisplayTime = m + ":00~" + n + ":59",
|
|
ProdIn = ProdALLQty,
|
|
ProdOut = ProdOKQty,
|
|
ProdNg = ProdNGQty,
|
|
OKRatio = strOkRatio
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Random rand = new Random();
|
|
for (int i = 1; i < 13; i++)
|
|
{
|
|
if (!isEnabled)
|
|
{
|
|
break;
|
|
}
|
|
int j = i * 2;
|
|
int m = j - 2;
|
|
int n = j - 1;
|
|
|
|
int ranOK = rand.Next(1000, 3000);
|
|
int ranNG = rand.Next(400, 1200);
|
|
int total = ranOK + ranNG;
|
|
|
|
chart24Hours.Add(new Chart24HourData()
|
|
{
|
|
DisplayTime = m + ":00~" + n + ":59",
|
|
ProdIn = ranOK + ranNG,
|
|
ProdOut = ranOK,
|
|
ProdNg = ranNG,
|
|
OKRatio = Math.Round((ranOK * 1.0 / total) * 100, 2) + "%"
|
|
});
|
|
}
|
|
}
|
|
if (!isEnabled)
|
|
{
|
|
return;
|
|
}
|
|
UpdateGV(chart24Hours);
|
|
BindChart(chart24Hours);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogHelper.Error(ex.Message, new Exception("异常信息"));
|
|
MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand);
|
|
timer_HourProd.Enabled = false;
|
|
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 更新24小时产能
|
|
/// </summary>
|
|
/// <param name="dt"></param>
|
|
private void UpdateGV(List<Chart24HourData> list)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.BeginInvoke(new EventHandler(delegate
|
|
{
|
|
DataTable dtsShow = new DataTable();
|
|
for (int i = 1; i <= 13; i++)
|
|
{
|
|
dtsShow.Columns.Add("Col" + i);
|
|
}
|
|
dtsShow.Rows.Add(new object[] { "优率", list[0].OKRatio, list[1].OKRatio, list[2].OKRatio, list[3].OKRatio, list[4].OKRatio, list[5].OKRatio
|
|
,list[6].OKRatio, list[7].OKRatio, list[8].OKRatio, list[9].OKRatio, list[10].OKRatio, list[11].OKRatio });
|
|
dtsShow.Rows.Add(new object[] { "产出" , list[0].ProdOut, list[1].ProdOut, list[2].ProdOut, list[3].ProdOut, list[4].ProdOut, list[5].ProdOut
|
|
,list[6].ProdOut, list[7].ProdOut, list[8].ProdOut, list[9].ProdOut, list[10].ProdOut, list[11].ProdOut });
|
|
dtsShow.Rows.Add(new object[] { "投入", list[0].ProdIn, list[1].ProdIn, list[2].ProdIn, list[3].ProdIn, list[4].ProdIn, list[5].ProdIn
|
|
,list[6].ProdIn, list[7].ProdIn, list[8].ProdIn, list[9].ProdIn, list[10].ProdIn, list[11].ProdIn});
|
|
dtsShow.Rows.Add(new object[] { "时间" , list[0].DisplayTime, list[1].DisplayTime, list[2].DisplayTime, list[3].DisplayTime, list[4].DisplayTime, list[5].DisplayTime
|
|
,list[6].DisplayTime, list[7].DisplayTime, list[8].DisplayTime, list[9].DisplayTime, list[10].DisplayTime, list[11].DisplayTime });
|
|
dgvHShow.DataSource = dtsShow;
|
|
dgvHShow.Refresh();
|
|
}));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新24小时产能Chart柱状图显示
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public void BindChart(List<Chart24HourData> list)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.BeginInvoke(new EventHandler(delegate
|
|
{
|
|
var x1 = list.Select(c => c.DisplayTime).ToList();
|
|
var y1 = list.Select(c => c.ProdIn).ToList();
|
|
var y2 = list.Select(c => c.ProdOut).ToList();
|
|
|
|
chart1.Series[0].Points.DataBindXY(x1, y1);
|
|
chart1.Series[1].Points.DataBindXY(x1, y2);
|
|
chart1.Series[2].Points.DataBindXY(x1, y2);
|
|
}));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 窗口渐变透明
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void timerOpacity_Tick(object sender, EventArgs e)
|
|
{
|
|
this.Opacity += 0.1;
|
|
if (this.Opacity == 1.0)
|
|
{
|
|
timerOpacity.Stop();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 关闭界面
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
public void FrmStatistics_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
this.Visible = false;
|
|
e.Cancel = true;
|
|
}
|
|
|
|
public void timerStatistics_Tick(object sender, EventArgs e)
|
|
{
|
|
TimerUpGetData();
|
|
}
|
|
|
|
public void timer_HourProd2_Tick(object sender, EventArgs e)
|
|
{
|
|
TimerUpHourProd();
|
|
}
|
|
}
|
|
}
|