Files
6150-HMI/CowainHmi/ProductionQty/ProductionDisplay.cs
2026-01-15 15:06:36 +08:00

552 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static CowainHmi.LogSearch;
using System.IO;
using System.Runtime.InteropServices;
using PCHMI;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ProgressBar;
using System.Data.OleDb;
using CowainHmi.ProductionQty;
using System.Drawing.Design;
using System.Threading;
namespace CowainHmi
{
public partial class ProductionDisplay : UserControl
{
public ProductionDisplay()
{
InitializeComponent();
}
[Category("PCHMI"), Description("PLC编号")]
public int PLCId
{
get;
set;
}
// 定义并添加自定义属性
[Browsable(true)]
[Category("Custom Properties")]
[Description("产量文件路径")]
public string ProductionFolderPath
{
get;
set;
}
[Browsable(true)]
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("Custom Properties")]
[Description("班别A开始时间")]
public string ShiftAStartAddress
{
get;
set;
}
[Browsable(true)]
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("Custom Properties")]
[Description("班别A结束时间")]
public string ShiftAEndAddress
{
get;
set;
}
[Browsable(true)]
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("Custom Properties")]
[Description("班别B开始时间")]
public string ShiftBStartAddress
{
get;
set;
}
[Browsable(true)]
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("Custom Properties")]
[Description("班别B结束时间")]
public string ShiftBEndAddress
{
get;
set;
}
[Browsable(true)]
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("Custom Properties")]
[Description("班别C开始时间")]
public string ShiftCStartAddress
{
get;
set;
}
[Browsable(true)]
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("Custom Properties")]
[Description("班别C结束时间")]
public string ShiftCEndAddress
{
get;
set;
}
[Category("PCHMI"), Description("工站名称")]
public string StationName { get; set; }
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("PCHMI"), Description("上传命令地址")]
public string UpCmdAddr { get; set; }
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("PCHMI"), Description("上传命令计数地址")]
public string RetCmdAddr { get; set; }
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("PCHMI"), Description("反馈命令计数地址")]
public string RetCountAddr { get; set; }
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("PCHMI"), Description("上传工单地址")]
public string UpOrderAddr { get; set; }
[Editor(typeof(StringText), typeof(UITypeEditor))]
[Category("PCHMI"), Description("上传部件号地址")]
public string UpPartNumAddr { get; set; }
private void SetCombox()
{
string text = System.Windows.Forms.Application.StartupPath + @"\" + ProductionFolderPath;
if (!Directory.Exists(text) && text.Length > 0)
{
Directory.CreateDirectory(text);
}
string productionFile = text + @"\" + dateTimePicker1.Value.ToString("yyMMdd") + ".csv";
List<> productionData = ReadProductionData(productionFile);
//PartNum下拉框获取唯一的零部件编号
if (productionData.Count == 0)
{
partNum.DataSource = null;
return;
}
var listDown = (from item in productionData
where !string.IsNullOrWhiteSpace(item.)
select item.).Distinct().ToList();
listDown.Insert(0, "全部");
partNum.DataSource = listDown;
}
private void button1_Click(object sender, EventArgs e)
{
CalcProductionQty();
}
private void CalcProductionQty()
{
string text = System.Windows.Forms.Application.StartupPath + @"\" + ProductionFolderPath;
if (!Directory.Exists(text) && text.Length > 0)
{
Directory.CreateDirectory(text);
}
string productionFile = text + @"\" + dateTimePicker1.Value.ToString("yyMMdd") + ".csv";
List<> productionData = ReadProductionData(productionFile);
List<Hours> hoursList = new List<Hours>();
for (int i = 0; i < shiftTime.Count; i++)
{
var item = shiftTime[i];
DateTime shiftStartTime = item.;
while (shiftStartTime < item.)
{
DateTime nextShiftStartTime = item.;
// Check if there is a next shift
if (i + 1 < shiftTime.Count)
{
nextShiftStartTime = shiftTime[i + 1].;
}
DateTime endTime = shiftStartTime.AddHours(1);
// Adjust the end time if it overlaps with the next shift
if (endTime > nextShiftStartTime)
{
endTime = nextShiftStartTime;
}
Hours hours1 = new Hours()
{
= shiftStartTime,
= endTime,
= item.,
};
hoursList.Add(hours1);
shiftStartTime = endTime;
}
}
List<> shift = new List<>();
string partFilter = partNum.Text == "全部" ? "" : partNum.Text;
foreach (var item in hoursList)
{
var info = productionData
.Where(pd => pd. >= item. && pd. < item.
&& (partFilter == "" || pd. == partFilter));
production = new ()
{
= item.,
= info.Any() ? info.FirstOrDefault(). : "",
= info.Any() ? info.FirstOrDefault(). : "",
= item.,
= info.Any() ? info.Where(pd => pd. >= item. && pd. < item.).Count() : 0,
= info.Any() ? info.Where(pd => pd. >= item. && pd. < item. && pd. == 1).Count() : 0,
= info.Any() ? info.Where(pd => pd. >= item. && pd. < item. && pd. == 2).Count() : 0,
};
shift.Add(production);
};
dataGridView1.DataSource = shift;
//统计按班别的总产量,总合格,总不合格
var shiftSum = (from item in shift
group item by item. into g
select new
{
= g.Key,
= g.Sum(x => x.),
= g.Sum(x => x.),//合格=1则直接对1求和
= g.Sum(x => x.)//不合格=2则对2-1求和
}).ToList();
var shiftASum = shiftSum.FirstOrDefault(x => x. == "A");
var shiftBSum = shiftSum.FirstOrDefault(x => x. == "B");
var shiftCSum = shiftSum.FirstOrDefault(x => x. == "C");
totalA.Text = shiftASum..ToString();
totalB.Text = shiftBSum..ToString();
totalC.Text = shiftCSum..ToString();
OK_A.Text = shiftASum..ToString();
OK_B.Text = shiftBSum..ToString();
OK_C.Text = shiftCSum..ToString();
NG_A.Text = shiftASum..ToString();
NG_B.Text = shiftBSum..ToString();
NG_C.Text = shiftCSum..ToString();
}
public bool IsWithinShiftTime(int hour, double startTime, double endTime)
{
if (startTime < endTime)
{
// 普通时间段
return hour >= startTime && hour < endTime;
}
else
{
// 跨越午夜的时间段
return hour >= startTime || hour < endTime;
}
}
private List<> ReadProductionData(string filePath)
{
var productionData = new List<>();
if (!File.Exists(filePath))
{
return productionData;
}
int N = 1;
foreach (var line in File.ReadAllLines(filePath, Encoding.GetEncoding("GB2312")))
{
try
{
if (N == 1)
{
N++;
continue;
}
var parts = line.Split(',');
var time = DateTime.ParseExact(parts[0].Trim(), "yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture);
productionData.Add(new
{
= time,
= parts[1],
= parts[2],
= int.Parse(parts[3])
}
);
}
catch (Exception ex)
{
//throw;
}
N++;
}
return productionData;
}
public class
{
public string { get; set; }
public DateTime { get; set; }
public DateTime { get; set; }
}
public class Hours
{
public string { get; set; }
public DateTime { get; set; }
public DateTime { get; set; }
}
public class
{
public DateTime { get; set; }
public string { get; set; }
public string { get; set; }
public string { get; set; }
public int { get; set; }
public int { get; set; }
public int { get; set; }
public int SortOrder { get; set; } // 新增排序字段
}
public class
{
public DateTime { get; set; }
public string { get; set; }
public string { get; set; }
public int { get; set; }
}
static string ConvertTimeToFormattedString(string timeString)
{
if (string.IsNullOrWhiteSpace(timeString) || timeString.Length != 4)
{
throw new ArgumentException("Invalid time format. Please use 'HHmm' format.");
}
// 提取小时和分钟
int hour = int.Parse(timeString.Substring(0, 2));
int minute = int.Parse(timeString.Substring(2, 2));
// 创建TimeSpan对象
TimeSpan timeSpan = new TimeSpan(hour, minute, 0);
// 将TimeSpan转换为字符串
return timeSpan.ToString("hh\\:mm\\:ss");
}
public class CalcStartEndTime
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
private CalcStartEndTime GetDateTime(string startTimeChar, string endTimeChar, DateTime queryDateTime)
{
CalcStartEndTime calcStartEndTime = new CalcStartEndTime();
int startTime = int.Parse(startTimeChar.Substring(0, 2));
int endTime = int.Parse(endTimeChar.Substring(0, 2));
DateTime startDateTime;
DateTime endDateTime;
// Determine the start and end dates
if (startTime > endTime)
{
startDateTime = queryDateTime;
endDateTime = queryDateTime.AddDays(1);
}
else
{
if (startTime < 9 && endTime < 9)
{
startDateTime = queryDateTime.AddDays(1);
endDateTime = queryDateTime.AddDays(1);
}
else
{
startDateTime = queryDateTime;
endDateTime = queryDateTime;
}
}
// Parse the exact times
calcStartEndTime.StartTime = DateTime.ParseExact(startDateTime.ToString("yyyy-MM-dd ") + ConvertTimeToFormattedString(startTimeChar), "yyyy-MM-dd HH:mm:ss", null);
calcStartEndTime.EndTime = DateTime.ParseExact(endDateTime.ToString("yyyy-MM-dd ") + ConvertTimeToFormattedString(endTimeChar), "yyyy-MM-dd HH:mm:ss", null);
return calcStartEndTime;
}
private void SetShiftTime()
{
ReadShiftTime();
var shiftATime = GetDateTime(shiftTimePLC[0], shiftTimePLC[1], dateTimePicker1.Value);
var shiftBTime = GetDateTime(shiftTimePLC[2], shiftTimePLC[3], dateTimePicker1.Value);
var shiftCTime = GetDateTime(shiftTimePLC[4], shiftTimePLC[5], dateTimePicker1.Value);
shiftTime = new List<>()
{
new { ="A", = shiftATime.StartTime, = shiftATime.EndTime },
new { ="B", = shiftBTime.StartTime, = shiftBTime.EndTime },
new { ="C", = shiftCTime.StartTime, = shiftCTime.EndTime }
};
}
private List<string> shiftTimePLC = new List<string>();
private void ReadShiftTime()
{
if (!PClass.SystemRun)
{
return;
}
shiftTimePLC.Clear();
List<string> shiftTimeDuration = new List<string>()
{
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftAStartAddress,4),
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftAEndAddress,4),
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftBStartAddress, 4),
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftBEndAddress, 4),
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftCStartAddress, 4),
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftCEndAddress, 4),
};
foreach (var item in shiftTimeDuration)
{
if (!string.IsNullOrEmpty(item))
{
shiftTimePLC.Add(item);
}
}
if (shiftTimePLC.Count != 6)
{
shiftTimePLC.Clear();
shiftTimePLC.Add("0830");
shiftTimePLC.Add("1630");
shiftTimePLC.Add("1700");
shiftTimePLC.Add("0130");
shiftTimePLC.Add("0130");
shiftTimePLC.Add("0830");
}
}
/// <summary>
/// 根据当前时间,获取存储的文件名
/// </summary>
private string GetFileName()
{
var dateTime = DateTime.Now;
var shiftATime = GetDateTime(shiftTimePLC[0], shiftTimePLC[1], dateTime.AddDays(-1));
var shiftBTime = GetDateTime(shiftTimePLC[2], shiftTimePLC[3], dateTime.AddDays(-1));
var shiftCTime = GetDateTime(shiftTimePLC[4], shiftTimePLC[5], dateTime.AddDays(-1));
List<> shiftTimeLastDay = new List<>()
{
new { ="A", = shiftATime.StartTime, = shiftATime.EndTime },
new { ="B", = shiftBTime.StartTime, = shiftBTime.EndTime },
new { ="C", = shiftCTime.StartTime, = shiftCTime.EndTime }
};
var shiftDuration = shiftTimeLastDay.Where(item => item. <= dateTime && dateTime < item.);
if (shiftDuration.Any())
{
return shiftTimeLastDay[0]..ToString("yyMMdd");
}
return dateTime.ToString("yyMMdd");
}
private List<> shiftTime;
private async void ProductionDisplay_Load(object sender, EventArgs e)
{
if (!PClass.SystemRun)
{
return;
}
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftAStartAddress, 4);
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftAEndAddress, 4);
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftBStartAddress, 4);
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftBEndAddress, 4);
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftCStartAddress, 4);
PCHMI.VL.GET_SIEMENS_STRING(PLCId, ShiftCEndAddress, 4);
PCHMI.RT.GET_INT16s(PLCId, UpCmdAddr, 6);
PCHMI.RT.GET_SIEMENS_STRING(PLCId, UpOrderAddr, 30);
PCHMI.RT.GET_SIEMENS_STRING(PLCId, UpPartNumAddr, 50);
await Task.Delay(300);
SetShiftTime();
dataGridView1.AutoGenerateColumns = false;
SetCombox();
ReadShiftTime();
this.timer1.Enabled = true;
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
SetShiftTime();
}
private short retCountSave;
private void timer1_Tick(object sender, EventArgs e)
{
if (PClass.IsPlcLink(PLCId) && !string.IsNullOrEmpty(UpCmdAddr))
{
var ar = PCHMI.RT.GET_INT16s(PLCId, UpCmdAddr, 6);
var order = PCHMI.RT.GET_SIEMENS_STRING(PLCId, UpOrderAddr, 30);
var partNum = PCHMI.RT.GET_SIEMENS_STRING(PLCId, UpPartNumAddr, 50);
if (ar[0] == 1 && retCountSave != ar[1])
{
//PLC触发产量上传
string fileName = GetFileName();
string stName = string.Empty;
if (string.IsNullOrEmpty(StationName))
{
stName = this.Name;
}
else
{
stName = StationName;
}
SaveData(stName, fileName, order, partNum, ar[5]);
PCHMI.RT.SEND_INT16(PLCId, RetCmdAddr, 1);
PCHMI.RT.SEND_INT16(PLCId, RetCountAddr, ar[1]);
retCountSave = ar[1];
}
}
}
public void SaveData(string stationName, string fileName, string order, string partNum, short isPass)
{
if (PClass.SystemRun)
{
string text = System.Windows.Forms.Application.StartupPath + @"\" + ProductionFolderPath;
if (!Directory.Exists(text) && text.Length > 0)
{
Directory.CreateDirectory(text);
}
string productionFile = text + @"\" + fileName + ".csv";
if (!File.Exists(productionFile))
{
CsvHelper.CreateCsv(productionFile, new string[]
{
"时间",
"工单",
"零部件",
"合格否"
});
}
CsvHelper.WriteLine(productionFile, new List<string>() { DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), order, partNum, isPass.ToString() });
}
}
private void btnTimeEdit_Click(object sender, EventArgs e)
{
List<string> strings = new List<string>() { ShiftAStartAddress, ShiftAEndAddress, ShiftBStartAddress, ShiftBEndAddress, ShiftCStartAddress, ShiftCEndAddress };
DlgProductionTimeEdit dlg = new DlgProductionTimeEdit(PLCId, strings);
var result = dlg.ShowDialog();
if (result == DialogResult.OK)
{
SetShiftTime();
ReadShiftTime();
}
}
private void partNum_MouseDown(object sender, MouseEventArgs e)
{
SetCombox();
}
}
}