diff --git a/ПХД/Form1.Designer.cs b/ПХД/Form1.Designer.cs index f7d20fc..f206125 100644 --- a/ПХД/Form1.Designer.cs +++ b/ПХД/Form1.Designer.cs @@ -31,6 +31,7 @@ this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.файлToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.экспортToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.импортToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.помощьToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.datePickerRegistration = new System.Windows.Forms.DateTimePicker(); this.cmbEngineType = new System.Windows.Forms.ComboBox(); @@ -63,7 +64,9 @@ this.dataGridView1 = new System.Windows.Forms.DataGridView(); this.btnSearch = new System.Windows.Forms.Button(); this.label11 = new System.Windows.Forms.Label(); - this.импортToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.datePickerVerification = new System.Windows.Forms.DateTimePicker(); + this.label12 = new System.Windows.Forms.Label(); + this.txtNotification = new System.Windows.Forms.RichTextBox(); this.menuStrip1.SuspendLayout(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); @@ -78,7 +81,7 @@ this.помощьToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(1079, 24); + this.menuStrip1.Size = new System.Drawing.Size(1142, 24); this.menuStrip1.TabIndex = 1; this.menuStrip1.Text = "menuStrip1"; // @@ -94,10 +97,17 @@ // экспортToolStripMenuItem // this.экспортToolStripMenuItem.Name = "экспортToolStripMenuItem"; - this.экспортToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.экспортToolStripMenuItem.Size = new System.Drawing.Size(119, 22); this.экспортToolStripMenuItem.Text = "Экспорт"; this.экспортToolStripMenuItem.Click += new System.EventHandler(this.экспортToolStripMenuItem_Click); // + // импортToolStripMenuItem + // + this.импортToolStripMenuItem.Name = "импортToolStripMenuItem"; + this.импортToolStripMenuItem.Size = new System.Drawing.Size(119, 22); + this.импортToolStripMenuItem.Text = "Импорт"; + this.импортToolStripMenuItem.Click += new System.EventHandler(this.импортToolStripMenuItem_Click); + // // помощьToolStripMenuItem // this.помощьToolStripMenuItem.Name = "помощьToolStripMenuItem"; @@ -412,7 +422,7 @@ this.dataGridView1.Location = new System.Drawing.Point(12, 312); this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.ReadOnly = true; - this.dataGridView1.Size = new System.Drawing.Size(1055, 328); + this.dataGridView1.Size = new System.Drawing.Size(1118, 328); this.dataGridView1.TabIndex = 21; this.dataGridView1.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.dataGridView1_CellFormatting); // @@ -436,18 +446,39 @@ this.label11.TabIndex = 23; this.label11.Text = "Дата постановки на учет"; // - // импортToolStripMenuItem + // datePickerVerification // - this.импортToolStripMenuItem.Name = "импортToolStripMenuItem"; - this.импортToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - this.импортToolStripMenuItem.Text = "Импорт"; - this.импортToolStripMenuItem.Click += new System.EventHandler(this.импортToolStripMenuItem_Click); + this.datePickerVerification.Location = new System.Drawing.Point(218, 47); + this.datePickerVerification.Name = "datePickerVerification"; + this.datePickerVerification.Size = new System.Drawing.Size(200, 20); + this.datePickerVerification.TabIndex = 24; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.label12.Location = new System.Drawing.Point(215, 31); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(90, 13); + this.label12.TabIndex = 25; + this.label12.Text = "Дата поверки"; + // + // txtNotification + // + this.txtNotification.Location = new System.Drawing.Point(829, 79); + this.txtNotification.Name = "txtNotification"; + this.txtNotification.Size = new System.Drawing.Size(301, 198); + this.txtNotification.TabIndex = 26; + this.txtNotification.Text = ""; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1079, 652); + this.ClientSize = new System.Drawing.Size(1142, 652); + this.Controls.Add(this.txtNotification); + this.Controls.Add(this.label12); + this.Controls.Add(this.datePickerVerification); this.Controls.Add(this.label11); this.Controls.Add(this.btnSearch); this.Controls.Add(this.dataGridView1); @@ -514,6 +545,9 @@ private System.Windows.Forms.Label label11; private System.Windows.Forms.ToolStripMenuItem экспортToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem импортToolStripMenuItem; + private System.Windows.Forms.DateTimePicker datePickerVerification; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.RichTextBox txtNotification; } } diff --git a/ПХД/Form1.cs b/ПХД/Form1.cs index 0c80d34..2478e20 100644 --- a/ПХД/Form1.cs +++ b/ПХД/Form1.cs @@ -4,6 +4,7 @@ using System.Windows.Forms; using System.Data.SQLite; using System.IO; using OfficeOpenXml; +using System.Collections.Generic; namespace ПХД { @@ -25,6 +26,8 @@ namespace ПХД LoadEngines(); txtReason.Enabled = false; datePickerOutOfOrder.Enabled = false; + dbManager.UpdateDatabaseSchema(); + } private void LoadEngines() @@ -32,6 +35,7 @@ namespace ПХД try { dataGridView1.DataSource = dbManager.GetAllEngines(); + CheckVerificationDates(); } catch (Exception ex) { @@ -55,11 +59,12 @@ namespace ПХД bool isOutOfOrder = chkOutOfOrder.Checked; string reason = isOutOfOrder ? txtReason.Text : null; string outOfOrderDate = isOutOfOrder ? datePickerOutOfOrder.Value.ToString("yyyy-MM-dd") : null; + string verificationDate = datePickerVerification.Value.ToString("yyyy-MM-dd"); dbManager.AddEngine( registrationDate, engineType, power, rpm, mountingType, uniqueNumber, factoryNumber, partNumber, installationSite, - isOutOfOrder, reason, outOfOrderDate + isOutOfOrder, reason, outOfOrderDate, verificationDate ); LoadEngines(); @@ -159,6 +164,14 @@ namespace ПХД DataPropertyName = "OutOfOrderDate", Width = 150 }); + + dataGridView1.Columns.Add(new DataGridViewTextBoxColumn + { + Name = "VerificationDate", + HeaderText = "Дата поверки", + DataPropertyName = "VerificationDate", + Width = 120 + }); } private void btnDelete_Click(object sender, EventArgs e) @@ -210,28 +223,40 @@ namespace ПХД } private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { - if (dataGridView1.Columns[e.ColumnIndex].Name == "IsOutOfOrder") + // Проверяем, что это столбец "Id" + if (dataGridView1.Columns[e.ColumnIndex].Name == "Id") { var row = dataGridView1.Rows[e.RowIndex]; + // Проверяем существование столбца "IsOutOfOrder" и его значения if (row.Cells["IsOutOfOrder"] != null && row.Cells["IsOutOfOrder"].Value != null) { - var value = row.Cells["IsOutOfOrder"].Value; + string value = row.Cells["IsOutOfOrder"].Value.ToString(); - if (value != DBNull.Value) + // Пытаемся преобразовать значение в bool + if (bool.TryParse(value, out bool isOutOfOrder)) { - bool isOutOfOrder = Convert.ToBoolean(value); - - // Подсвечиваем фон ячейки - e.CellStyle.BackColor = isOutOfOrder - ? System.Drawing.Color.LightCoral // Красный фон - : System.Drawing.Color.White; // Белый фон + // Подсвечиваем цвет, если двигатель вышел из строя + if (isOutOfOrder) + { + e.CellStyle.BackColor = System.Drawing.Color.LightCoral; + } + else + { + e.CellStyle.BackColor = System.Drawing.Color.White; + } } else { + // Если преобразование не удалось, используем белый фон e.CellStyle.BackColor = System.Drawing.Color.White; } } + else + { + // Если значение отсутствует, используем белый фон + e.CellStyle.BackColor = System.Drawing.Color.White; + } } } @@ -398,10 +423,43 @@ namespace ПХД return; } - // Загружаем данные в DataGridView - dataGridView1.DataSource = importedTable; + // Сохраняем импортированные данные в базу данных + foreach (DataRow row in importedTable.Rows) + { + // Обработка столбца IsOutOfOrder + bool isOutOfOrder = false; + if (row["IsOutOfOrder"] != null && !string.IsNullOrWhiteSpace(row["IsOutOfOrder"].ToString())) + { + // Попытка преобразования строки в bool + if (!bool.TryParse(row["IsOutOfOrder"].ToString(), out isOutOfOrder)) + { + // Проверяем числовые значения ("1" => true, "0" => false) + isOutOfOrder = row["IsOutOfOrder"].ToString() == "1"; + } + } - MessageBox.Show("Данные успешно импортированы!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information); + // Добавляем запись в базу данных + dbManager.AddEngine( + row["RegistrationDate"].ToString(), + row["EngineType"].ToString(), + double.Parse(row["Power"].ToString()), + int.Parse(row["RPM"].ToString()), + row["MountingType"].ToString(), + row["UniqueNumber"].ToString(), + row["FactoryNumber"].ToString(), + row["PartNumber"].ToString(), + row["InstallationSite"].ToString(), + isOutOfOrder, + row["Reason"].ToString(), + row["OutOfOrderDate"].ToString(), + row["VerificationDate"].ToString() + ); + } + + // Обновляем DataGridView + LoadEngines(); + + MessageBox.Show("Данные успешно импортированы и сохранены в базу данных!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } @@ -413,6 +471,8 @@ namespace ПХД + + private DataTable ImportFromExcel(string filePath) { DataTable table = new DataTable(); @@ -428,24 +488,34 @@ namespace ПХД throw new Exception("В файле отсутствуют листы."); } - // Создаем колонки на основе заголовков DataGridView + // Создаем DataTable на основе столбцов DataGridView foreach (DataGridViewColumn column in dataGridView1.Columns) { table.Columns.Add(column.DataPropertyName); } + // Проверяем наличие заголовков в Excel + Dictionary excelColumnIndices = new Dictionary(); + for (int col = 1; col <= worksheet.Dimension.End.Column; col++) + { + string columnHeader = worksheet.Cells[1, col].Text.Trim(); + foreach (DataGridViewColumn dgvColumn in dataGridView1.Columns) + { + if (dgvColumn.HeaderText == columnHeader) + { + excelColumnIndices[dgvColumn.DataPropertyName] = col; + break; + } + } + } + // Читаем данные начиная со второй строки for (int row = 2; row <= worksheet.Dimension.End.Row; row++) { DataRow newRow = table.NewRow(); - for (int col = 1; col <= worksheet.Dimension.End.Column; col++) + foreach (var mapping in excelColumnIndices) { - // Сопоставляем заголовки Excel с DataPropertyName - string columnName = worksheet.Cells[1, col].Text.Trim(); - if (table.Columns.Contains(columnName)) - { - newRow[columnName] = worksheet.Cells[row, col].Text.Trim(); - } + newRow[mapping.Key] = worksheet.Cells[row, mapping.Value].Text.Trim(); } table.Rows.Add(newRow); } @@ -455,6 +525,32 @@ namespace ПХД } + private void CheckVerificationDates() + { + txtNotification.Clear(); + txtNotification.ForeColor = System.Drawing.Color.Black; + var engines = dbManager.GetAllEngines(); + + foreach (DataRow row in engines.Rows) + { + if (DateTime.TryParse(row["VerificationDate"].ToString(), out DateTime verificationDate)) + { + if (verificationDate <= DateTime.Now.AddMonths(1) && verificationDate > DateTime.Now) + { + txtNotification.ForeColor = System.Drawing.Color.Red; + txtNotification.AppendText( + $"Двигатель с заводским номером {row["FactoryNumber"]} нуждается в поверке {verificationDate:dd-MM-yyyy}.\r\n"); + } + } + } + if (string.IsNullOrEmpty(txtNotification.Text)) + { + txtNotification.ForeColor = System.Drawing.Color.Black; // Нет уведомлений — чёрный текст + txtNotification.Text = "Уведомлений нет."; + } + } + + @@ -506,7 +602,7 @@ namespace ПХД string registrationDate, string engineType, double power, int rpm, string mountingType, string uniqueNumber, string factoryNumber, string partNumber, string installationSite, bool isOutOfOrder, - string reason, string outOfOrderDate) + string reason, string outOfOrderDate, string verificationDate) { using (var connection = new SQLiteConnection(connectionString)) { @@ -515,11 +611,11 @@ namespace ПХД INSERT INTO Engines (RegistrationDate, EngineType, Power, RPM, MountingType, UniqueNumber, FactoryNumber, PartNumber, InstallationSite, - IsOutOfOrder, Reason, OutOfOrderDate) + IsOutOfOrder, Reason, OutOfOrderDate, VerificationDate) VALUES (@RegistrationDate, @EngineType, @Power, @RPM, @MountingType, @UniqueNumber, @FactoryNumber, @PartNumber, @InstallationSite, - @IsOutOfOrder, @Reason, @OutOfOrderDate)"; + @IsOutOfOrder, @Reason, @OutOfOrderDate, @VerificationDate)"; SQLiteCommand command = new SQLiteCommand(insertQuery, connection); command.Parameters.AddWithValue("@RegistrationDate", registrationDate); @@ -534,6 +630,7 @@ namespace ПХД command.Parameters.AddWithValue("@IsOutOfOrder", isOutOfOrder ? 1 : 0); command.Parameters.AddWithValue("@Reason", reason ?? (object)DBNull.Value); command.Parameters.AddWithValue("@OutOfOrderDate", outOfOrderDate ?? (object)DBNull.Value); + command.Parameters.AddWithValue("@VerificationDate", verificationDate ?? (object)DBNull.Value); command.ExecuteNonQuery(); } @@ -546,11 +643,12 @@ namespace ПХД connection.Open(); string selectQuery = @" - SELECT - Id, RegistrationDate, EngineType, Power, RPM, MountingType, - UniqueNumber, FactoryNumber, PartNumber, InstallationSite, - IsOutOfOrder, Reason, OutOfOrderDate - FROM Engines"; +SELECT + Id, RegistrationDate, EngineType, Power, RPM, MountingType, + UniqueNumber, FactoryNumber, PartNumber, InstallationSite, + IsOutOfOrder, Reason, OutOfOrderDate, VerificationDate +FROM Engines"; + SQLiteDataAdapter adapter = new SQLiteDataAdapter(selectQuery, connection); @@ -584,6 +682,29 @@ namespace ПХД } } + public void UpdateDatabaseSchema() + { + using (var connection = new SQLiteConnection(connectionString)) + { + connection.Open(); + string addColumnQuery = @" + ALTER TABLE Engines ADD COLUMN VerificationDate TEXT"; + + try + { + SQLiteCommand command = new SQLiteCommand(addColumnQuery, connection); + command.ExecuteNonQuery(); + } + catch (SQLiteException ex) + { + if (!ex.Message.Contains("duplicate column name")) // Игнорируем, если столбец уже существует + { + throw; + } + } + } + } + }