callm 7 місяців тому
батько
коміт
0916d630d4

+ 2 - 3
FileWatcher/AutoAnalysisDeviceKS.Designer.cs

@@ -147,7 +147,7 @@
             // 
             // Timer
             // 
-            this.Timer.Interval = 60000;
+            this.Timer.Interval = 5000;
             this.Timer.Tick += new System.EventHandler(this.Timer_Tick);
             // 
             // Device
@@ -155,8 +155,7 @@
             this.Device.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
             this.Device.FormattingEnabled = true;
             this.Device.Items.AddRange(new object[] {
-            "ATE设备",
-            "老化设备"});
+            "贴片机"});
             this.Device.Location = new System.Drawing.Point(224, 201);
             this.Device.Margin = new System.Windows.Forms.Padding(6);
             this.Device.Name = "Device";

+ 185 - 52
FileWatcher/AutoAnalysisDeviceKS.cs

@@ -92,9 +92,6 @@ namespace FileWatcher
             {
                 FolderPath.Text = BaseUtil.GetCacheData("FolderPath").ToString();
                 Device.Text = BaseUtil.GetCacheData("Device").ToString();
-                //BackUpFolderPath.Text = BaseUtil.GetCacheData("BackUpFolderPath").ToString();
-                //Master.Text = BaseUtil.GetCacheData("Master").ToString();
-                //AutoStart.Checked = (bool)BaseUtil.GetCacheData("AutoStart");
             }
             catch (Exception ex) { MessageBox.Show(ex.Message); }
             //获取岗位资源相关信息
@@ -128,7 +125,7 @@ namespace FileWatcher
             //设置缓存数据
             BaseUtil.SetCacheData("FolderPath", FolderPath.Text);
             BaseUtil.SetCacheData("Device", Device.Text);
-            Timer.Interval = 1000 * 60;
+            Timer.Interval = 1000 * 5;
             Timer.Start();
             //设置按钮不可点击
             StartWatch.Enabled = false;
@@ -223,80 +220,216 @@ namespace FileWatcher
 
         private void Timer_Tick(object sender, EventArgs e)
         {
-            string filePath = FolderPath.Text+ @"\LotLog.csv";
-            string connectionString = "Connection Timeout=0;Pooling=false;Password=select!#%*(;User ID=N_MES;Pooling=false;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.3.7)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)));";
-            // 读取Excel文件
-            var data = ReadExcelFile(filePath);
+            string filePath = FolderPath.Text + @"\LotLog.csv";
             // 插入Oracle数据库
-            InsertDataIntoOracle(data, connectionString);
+            List<string[]> csvData = ReadAndFilterCsvFile(filePath);
+            // 2. 解析数据并写入Oracle数据库
+            WriteToOracleDatabase(csvData);
         }
 
-        static List<Dictionary<string, string>> ReadExcelFile(string filePath)
+        static List<string[]> ReadAndFilterCsvFile(string filePath)
         {
-            var data = new List<Dictionary<string, string>>();
+            var filteredData = new List<string[]>();
+            DateTime currentTime = DateTime.Now;
+            DateTime fiveMinutesAgo = currentTime.AddMinutes(-1440);
 
-            using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+            // 使用StreamReader自动检测编码
+            using (var reader = new StreamReader(filePath, Encoding.Default, true))
             {
-                XSSFWorkbook workbook = new XSSFWorkbook(file);
-                ISheet sheet = workbook.GetSheetAt(0); // 获取第一个工作表
+                Console.WriteLine($"检测到文件编码: {reader.CurrentEncoding.EncodingName}");
 
-                IRow headerRow = sheet.GetRow(0); // 获取表头行
-                int cellCount = headerRow.LastCellNum;
+                // 跳过第一行(版本信息行)
+                reader.ReadLine();
 
-                for (int i = 1; i <= sheet.LastRowNum; i++) // 从第二行开始读取数据
+                // 读取标题行
+                string headerLine = reader.ReadLine();
+                if (headerLine == null)
                 {
-                    IRow row = sheet.GetRow(i);
-                    if (row == null) continue;
+                    throw new Exception("CSV文件格式不正确,缺少标题行");
+                }
 
-                    var rowData = new Dictionary<string, string>();
+                // 确定生产开始时间的列索引
+                string[] headers = headerLine.Split(',');
+                int startTimeIndex = Array.IndexOf(headers, "生产开始时间");
+                if (startTimeIndex == -1)
+                {
+                    throw new Exception("CSV文件中找不到'生产开始时间'列");
+                }
 
-                    for (int j = 0; j < cellCount; j++)
+                // 读取并过滤数据行
+                while (!reader.EndOfStream)
+                {
+                    string line = reader.ReadLine();
+                    if (!string.IsNullOrWhiteSpace(line))
                     {
-                        ICell cell = row.GetCell(j);
-                        string cellValue = cell?.ToString() ?? string.Empty;
-                        string header = headerRow.GetCell(j).ToString();
-
-                        rowData[header] = cellValue;
+                        string[] values = line.Split(',');
+
+                        // 解析生产开始时间
+                        if (startTimeIndex < values.Length &&
+                            DateTime.TryParse(values[startTimeIndex], out DateTime startTime))
+                        {
+                            // 只保留生产开始时间在当前时间5分钟以内的记录
+                            filteredData.Add(values);
+                        }
                     }
-
-                    data.Add(rowData);
                 }
             }
+            return filteredData;
+        }
 
-            return data;
+        public static Encoding DetectFileEncoding(string filePath)
+        {
+            // 读取文件前几个字节来检测编码
+            byte[] buffer = new byte[5];
+            using (FileStream file = new FileStream(filePath, FileMode.Open))
+            {
+                file.Read(buffer, 0, 5);
+                file.Close();
+            }
+
+            // 检测UTF-8 with BOM
+            if (buffer[0] == 0xEF && buffer[1] == 0xBB && buffer[2] == 0xBF)
+                return Encoding.UTF8;
+
+            // 检测UTF-16 (Big Endian)
+            if (buffer[0] == 0xFE && buffer[1] == 0xFF)
+                return Encoding.BigEndianUnicode;
+
+            // 检测UTF-16 (Little Endian)
+            if (buffer[0] == 0xFF && buffer[1] == 0xFE)
+                return Encoding.Unicode;
+
+            // 默认使用GB2312(中文常用编码)
+            return Encoding.GetEncoding("GB2312");
         }
 
-        static void InsertDataIntoOracle(List<Dictionary<string, string>> data, string connectionString)
+
+         void WriteToOracleDatabase(List<string[]> csvData)
         {
+            // Oracle连接字符串 - 根据实际情况修改
+            string connectionString = "Connection Timeout=0;Pooling=false;Password=select!#%*(;User ID=N_MES;Pooling=false;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.3.7)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)));";
+
+            // 字段索引映射(根据CSV标题行顺序调整)
+            const int BOARD_NAME_INDEX = 1;         // 基板名
+            const int START_TIME_INDEX = 4;         // 生产开始时间
+            const int END_TIME_INDEX = 6;           // 生产完成时间
+            const int ERROR_STOP_TIME_INDEX = 46;   // 出错停止时间(秒)
+            const int ERROR_REPAIR_TIME_INDEX = 47; // 出错修复时间(秒)
+            const int COMPLETED_PANELS_INDEX = 49;  // 完成贴装的拼板数
+            const int UPSTREAM_WAIT_INDEX = 50;     // 因上游待机的时间(秒)
+            const int DOWNSTREAM_WAIT_INDEX = 51;   // 因下游待机的时间(秒)
+            const int EFFICIENCY_INDEX = 52;        // 可动率(%)
+            const int PLACEMENT_POINTS_INDEX = 53;  // 贴装点数
+            const int COMPONENT_CONSUMP_INDEX = 54; // 元件消耗数
+            const int CONVEYOR_INDEX = 55;          // 输送台
+
             using (OracleConnection connection = new OracleConnection(connectionString))
             {
-                connection.Open();
-
-                foreach (var row in data)
+                try
                 {
-                    string query = @"
-                        INSERT INTO your_table_name (psl_program, psl_begintime, psl_endtime, psl_stop, psl_repair, psl_boards, psl_waitupper, psl_waitlower, psl_move, psl_points, psl_consumes, psl_plat)
-                        VALUES (:psl_program, :psl_begintime, :psl_endtime, :psl_stop, :psl_repair, :psl_boards, :psl_waitupper, :psl_waitlower, :psl_move, :psl_points, :psl_consumes, :psl_plat)";
-
-                    using (OracleCommand command = new OracleCommand(query, connection))
+                    connection.Open();
+
+                    // 使用参数化SQL防止注入
+                    string insertSql = @"
+                    INSERT INTO productsmtlocation_1 (psl_id,
+                        psl_program, psl_begintime, psl_endtime, psl_stop, 
+                        psl_repair, psl_boards, psl_waitupper, 
+                        psl_waitlower, psl_move, psl_points, 
+                        psl_consumes, psl_plat
+                    ) VALUES (productsmtlocation_seq.nextval,
+                        :boardName, :startTime, :endTime, :errorStopTime, 
+                        :errorRepairTime, :completedPanels, :upstreamWaitTime, 
+                        :downstreamWaitTime, :efficiency, :placementPoints, 
+                        :componentConsumption, :conveyor
+                    )";
+
+                    using (OracleCommand command = new OracleCommand(insertSql, connection))
                     {
-                        command.Parameters.Add("psl_program", OracleDbType.Varchar2).Value = row["基板名"];
-                        command.Parameters.Add("psl_begintime", OracleDbType.Date).Value = DateTime.Parse(row["生产开始时间"]);
-                        command.Parameters.Add("psl_endtime", OracleDbType.Date).Value = DateTime.Parse(row["生产完成时间"]);
-                        command.Parameters.Add("psl_stop", OracleDbType.Int32).Value = int.Parse(row["出错停止时间(秒)"]);
-                        command.Parameters.Add("psl_repair", OracleDbType.Int32).Value = int.Parse(row["出错修复时间(秒)"]);
-                        command.Parameters.Add("psl_boards", OracleDbType.Int32).Value = int.Parse(row["完成贴装的拼板数"]);
-                        command.Parameters.Add("psl_waitupper", OracleDbType.Int32).Value = int.Parse(row["因上游待机的时间(秒)"]);
-                        command.Parameters.Add("psl_waitlower", OracleDbType.Int32).Value = int.Parse(row["因下游待机的时间(秒)"]);
-                        command.Parameters.Add("psl_move", OracleDbType.Int32).Value = int.Parse(row["可动率(%)"]);
-                        command.Parameters.Add("psl_points", OracleDbType.Int32).Value = int.Parse(row["贴装点数"]);
-                        command.Parameters.Add("psl_consumes", OracleDbType.Int32).Value = int.Parse(row["元件消耗数"]);
-                        command.Parameters.Add("psl_plat", OracleDbType.Varchar2).Value = row["输送台"];
-
-                        command.ExecuteNonQuery();
+                        // 添加参数
+                        command.Parameters.Add(":boardName", OracleDbType.Varchar2);
+                        command.Parameters.Add(":startTime", OracleDbType.TimeStamp);
+                        command.Parameters.Add(":endTime", OracleDbType.TimeStamp);
+                        command.Parameters.Add(":errorStopTime", OracleDbType.Double);
+                        command.Parameters.Add(":errorRepairTime", OracleDbType.Double);
+                        command.Parameters.Add(":completedPanels", OracleDbType.Int32);
+                        command.Parameters.Add(":upstreamWaitTime", OracleDbType.Double);
+                        command.Parameters.Add(":downstreamWaitTime", OracleDbType.Double);
+                        command.Parameters.Add(":efficiency", OracleDbType.Double);
+                        command.Parameters.Add(":placementPoints", OracleDbType.Int32);
+                        command.Parameters.Add(":componentConsumption", OracleDbType.Int32);
+                        command.Parameters.Add(":conveyor", OracleDbType.Varchar2);
+
+                        // 遍历CSV数据行
+                        for (int i = 0; i < csvData.Count; i++)
+                        {
+                            string[] values = csvData[i];
+
+                            try
+                            {
+                                // 设置参数值
+                                command.Parameters[":boardName"].Value = GetStringValue(values, BOARD_NAME_INDEX);
+                                command.Parameters[":startTime"].Value = GetDateTimeValue(values, START_TIME_INDEX);
+                                command.Parameters[":endTime"].Value = GetDateTimeValue(values, END_TIME_INDEX);
+                                command.Parameters[":errorStopTime"].Value = GetDoubleValue(values, ERROR_STOP_TIME_INDEX);
+                                command.Parameters[":errorRepairTime"].Value = GetDoubleValue(values, ERROR_REPAIR_TIME_INDEX);
+                                command.Parameters[":completedPanels"].Value = GetIntValue(values, COMPLETED_PANELS_INDEX);
+                                command.Parameters[":upstreamWaitTime"].Value = GetDoubleValue(values, UPSTREAM_WAIT_INDEX);
+                                command.Parameters[":downstreamWaitTime"].Value = GetDoubleValue(values, DOWNSTREAM_WAIT_INDEX);
+                                command.Parameters[":efficiency"].Value = GetDoubleValue(values, EFFICIENCY_INDEX);
+                                command.Parameters[":placementPoints"].Value = GetIntValue(values, PLACEMENT_POINTS_INDEX);
+                                command.Parameters[":componentConsumption"].Value = GetIntValue(values, COMPONENT_CONSUMP_INDEX);
+                                command.Parameters[":conveyor"].Value = GetStringValue(values, CONVEYOR_INDEX);
+                                if (!dh.CheckExist("productsmtlocation_1", 
+                                    "to_char(PSL_BEGINTIME,'yyyy-mm-dd hh24:mi:ss')='"+ GetDateTimeValue(values, START_TIME_INDEX).ToString("yyyy-MM-dd HH:mm:ss") + "' " +
+                                    "and psl_plat='"+ GetStringValue(values, CONVEYOR_INDEX) + "'"))
+                                {
+                                    int rowsAffected = command.ExecuteNonQuery();
+                                    OperateResult.AppendText($"已插入记录 {i + 1}/{csvData.Count}: {GetStringValue(values, BOARD_NAME_INDEX)}\n");
+                                }
+                                // 执行插入
+                            }
+                            catch (Exception ex)
+                            {
+                                Console.WriteLine($"插入记录 {i + 1} 失败: {ex.Message}");
+                            }
+                        }
                     }
                 }
+                catch (Exception ex)
+                {
+                    Console.WriteLine($"数据库错误: {ex.Message}");
+                }
             }
         }
+
+        static double? GetDoubleValue(string[] values, int index)
+        {
+            if (values == null || index >= values.Length || string.IsNullOrWhiteSpace(values[index]))
+                return null;
+
+            double result;
+            return double.TryParse(values[index], out result) ? result : (double?)null;
+        }
+
+        static int? GetIntValue(string[] values, int index)
+        {
+            if (values == null || index >= values.Length || string.IsNullOrWhiteSpace(values[index]))
+                return null;
+
+            int result;
+            return int.TryParse(values[index], out result) ? result : (int?)null;
+        }
+
+        static string GetStringValue(string[] values, int index)
+        {
+            return (values != null && index < values.Length) ? values[index] : null;
+        }
+
+        static DateTime GetDateTimeValue(string[] values, int index)
+        {
+            DateTime result;
+             DateTime.TryParse(values[index], out result);
+            return result;
+        }
     }
 }

+ 2 - 0
FileWatcher/FileWatcher.csproj

@@ -295,6 +295,7 @@
     </EmbeddedResource>
     <EmbeddedResource Include="AutoAnalysisXLSJC.resx">
       <DependentUpon>AutoAnalysisXLSJC.cs</DependentUpon>
+      <SubType>Designer</SubType>
     </EmbeddedResource>
     <EmbeddedResource Include="UploadMakePlan.resx">
       <DependentUpon>UploadMakePlan.cs</DependentUpon>
@@ -310,6 +311,7 @@
     </EmbeddedResource>
     <EmbeddedResource Include="AutoAnalysisXmlByStep.resx">
       <DependentUpon>AutoAnalysisXmlByStep.cs</DependentUpon>
+      <SubType>Designer</SubType>
     </EmbeddedResource>
     <EmbeddedResource Include="AutoAnalysisXml.resx">
       <DependentUpon>AutoAnalysisXml.cs</DependentUpon>

+ 1 - 1
FileWatcher/Program.cs

@@ -46,7 +46,7 @@ namespace FileWatcher
                 Application.SetCompatibleTextRenderingDefault(false);
                 if (principal.IsInRole(WindowsBuiltInRole.Administrator))
                 {
-                    Application.Run(new UploadMakePlan());
+                    Application.Run(new AutoAnalysisDeviceKS());
                     //Application.Run(new AutoAnalysisXmlByStep());
                     //Application.Run(new SOP("", ""));
                     //Application.Run(new AutoMakeQTY());