diff --git a/NoDuplicate/Form1.Designer.cs b/NoDuplicate/Form1.Designer.cs index 87ae82e..79dcb8a 100644 --- a/NoDuplicate/Form1.Designer.cs +++ b/NoDuplicate/Form1.Designer.cs @@ -38,8 +38,13 @@ this.помощьToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.label1 = new System.Windows.Forms.Label(); this.lblStatus = new System.Windows.Forms.Label(); + this.dataGridView2 = new System.Windows.Forms.DataGridView(); + this.btnValidateEmails = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); this.menuStrip1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit(); this.SuspendLayout(); // // dataGridView1 @@ -48,17 +53,17 @@ this.dataGridView1.AllowUserToDeleteRows = false; this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.dataGridView1.Location = new System.Drawing.Point(12, 36); + this.dataGridView1.Location = new System.Drawing.Point(12, 51); this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.ReadOnly = true; - this.dataGridView1.Size = new System.Drawing.Size(464, 389); + this.dataGridView1.Size = new System.Drawing.Size(281, 389); this.dataGridView1.TabIndex = 0; // // btnRemoveDuplicates // - this.btnRemoveDuplicates.Location = new System.Drawing.Point(12, 431); + this.btnRemoveDuplicates.Location = new System.Drawing.Point(12, 446); this.btnRemoveDuplicates.Name = "btnRemoveDuplicates"; - this.btnRemoveDuplicates.Size = new System.Drawing.Size(126, 23); + this.btnRemoveDuplicates.Size = new System.Drawing.Size(134, 23); this.btnRemoveDuplicates.TabIndex = 1; this.btnRemoveDuplicates.Text = "Удалить дубликаты"; this.btnRemoveDuplicates.UseVisualStyleBackColor = true; @@ -71,7 +76,7 @@ this.помощьToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(488, 24); + this.menuStrip1.Size = new System.Drawing.Size(620, 24); this.menuStrip1.TabIndex = 2; this.menuStrip1.Text = "menuStrip1"; // @@ -108,7 +113,7 @@ // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(159, 436); + this.label1.Location = new System.Drawing.Point(159, 451); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(44, 13); this.label1.TabIndex = 3; @@ -118,16 +123,60 @@ // this.lblStatus.AutoSize = true; this.lblStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.lblStatus.Location = new System.Drawing.Point(209, 436); + this.lblStatus.Location = new System.Drawing.Point(209, 451); this.lblStatus.Name = "lblStatus"; this.lblStatus.Size = new System.Drawing.Size(0, 13); this.lblStatus.TabIndex = 4; // + // dataGridView2 + // + this.dataGridView2.AllowUserToAddRows = false; + this.dataGridView2.AllowUserToDeleteRows = false; + this.dataGridView2.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; + this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView2.Location = new System.Drawing.Point(315, 51); + this.dataGridView2.Name = "dataGridView2"; + this.dataGridView2.ReadOnly = true; + this.dataGridView2.Size = new System.Drawing.Size(291, 389); + this.dataGridView2.TabIndex = 5; + // + // btnValidateEmails + // + this.btnValidateEmails.Location = new System.Drawing.Point(12, 475); + this.btnValidateEmails.Name = "btnValidateEmails"; + this.btnValidateEmails.Size = new System.Drawing.Size(134, 23); + this.btnValidateEmails.TabIndex = 6; + this.btnValidateEmails.Text = "Проверить валидность"; + this.btnValidateEmails.UseVisualStyleBackColor = true; + this.btnValidateEmails.Click += new System.EventHandler(this.btnValidateEmails_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(9, 35); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(65, 13); + this.label2.TabIndex = 7; + this.label2.Text = "Все адреса"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(312, 35); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(110, 13); + this.label3.TabIndex = 8; + this.label3.Text = "Навалидные адреса"; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(488, 462); + this.ClientSize = new System.Drawing.Size(620, 506); + this.Controls.Add(this.label3); + this.Controls.Add(this.label2); + this.Controls.Add(this.btnValidateEmails); + this.Controls.Add(this.dataGridView2); this.Controls.Add(this.lblStatus); this.Controls.Add(this.label1); this.Controls.Add(this.btnRemoveDuplicates); @@ -140,6 +189,7 @@ ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -156,6 +206,10 @@ private System.Windows.Forms.ToolStripMenuItem помощьToolStripMenuItem; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label lblStatus; + private System.Windows.Forms.DataGridView dataGridView2; + private System.Windows.Forms.Button btnValidateEmails; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; } } diff --git a/NoDuplicate/Form1.cs b/NoDuplicate/Form1.cs index 8a52137..f81058f 100644 --- a/NoDuplicate/Form1.cs +++ b/NoDuplicate/Form1.cs @@ -10,6 +10,8 @@ using System.Threading.Tasks; using System.Windows.Forms; using OfficeOpenXml; using OfficeOpenXml; +using System.Text.RegularExpressions; +using System.Diagnostics; namespace NoDuplicate @@ -215,5 +217,129 @@ namespace NoDuplicate { MessageBox.Show("Инструкция по работе с программой\r\nПрограмма для работы с email-адресами позволяет удалять дубликаты из списка адресов и создавать отчёты об удалённых данных. Следуйте этим шагам:\r\n\r\n1. Импорт файла\r\nНажмите кнопку \"Импорт\" или выберите пункт меню \"Файл → Импорт\".\r\nВ появившемся окне выберите файл в формате .xlsx, содержащий список email-адресов.\r\nПрограмма загрузит данные и отобразит их в таблице.\r\n2. Удаление дубликатов\r\nПосле импорта нажмите кнопку \"Удалить дубликаты\".\r\nПрограмма автоматически:\r\nУдалит повторяющиеся email-адреса (с учётом регистра и пробелов).\r\nОбновит таблицу, оставив только уникальные адреса.\r\nСоздаст отчёт в папке MyAppReports в \"Моих документах\". Отчёт содержит список удалённых адресов.\r\n3. Экспорт файла\r\nЧтобы сохранить уникальные адреса, нажмите кнопку \"Экспорт\" или выберите пункт меню \"Файл → Экспорт\".\r\nВыберите место и имя для нового файла в формате .xlsx.\r\nПрограмма создаст файл с уникальными адресами.\r\n4. Папка отчётов\r\nВсе отчёты об удалённых адресах сохраняются в папке MyAppReports (расположена в \"Моих документах\").\r\nКаждый отчёт содержит:\r\nОбщее количество удалённых адресов.\r\nПолный список удалённых адресов.\r\nВы можете открыть эту папку вручную или добавить кнопку для её быстрого открытия."); } + + private bool IsValidEmail(string email) + { + if (string.IsNullOrWhiteSpace(email)) return false; + + // Регулярное выражение для проверки email + var emailRegex = new Regex(@"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z]{2,}$"); + if (!emailRegex.IsMatch(email.Trim())) return false; + + // Проверяем валидность домена + string domain = email.Split('@').LastOrDefault(); + if (!IsValidDomain(domain)) return false; + + // Проверяем, что нет двойной точки в любом месте email + if (email.Contains("..")) return false; + + return true; + } + + + + + private bool IsValidDomain(string domain) + { + // Список валидных доменных окончаний + string[] validTlds = { + "com", "org", "net", "edu", "gov", "io", "co", "uk", "ru", "de", "fr", + "jp", "cn", "us", "museum", "jobs", "info", "biz", "xyz", "ai", "name" + }; + + string[] parts = domain.Split('.'); + if (parts.Length < 2) return false; // Минимум 2 части: имя домена и TLD + + // Проверяем, что каждая часть домена не пуста, не начинается и не заканчивается тире + foreach (string part in parts) + { + if (string.IsNullOrEmpty(part) || part.StartsWith("-") || part.EndsWith("-")) + return false; + } + + // Проверяем валидность TLD + string tld = parts.LastOrDefault(); + if (!validTlds.Contains(tld)) return false; + + return true; + } + + + + + + + private void btnValidateEmails_Click(object sender, EventArgs e) + { + if (emailTable == null || emailTable.Rows.Count == 0) + { + lblStatus.Text = "Таблица пуста или не загружена."; + lblStatus.ForeColor = Color.Red; + return; + } + + var validEmails = new List(); + var invalidEmails = new List(); + + foreach (DataRow row in emailTable.Rows) + { + string email = row.Field("Email").Trim(); // Убираем пробелы + bool isValid = IsValidEmail(email); + + if (isValid) + { + validEmails.Add(email); + } + else + { + invalidEmails.Add(email); + } + + // Отладочный вывод + Debug.WriteLine($"Email: '{email}', Корректный: {isValid}"); + } + + // Проверяем, что корректные email записываются обратно + Debug.WriteLine("Корректные email:"); + foreach (var email in validEmails) + { + Debug.WriteLine(email); + } + + Debug.WriteLine("Невалидные email:"); + foreach (var email in invalidEmails) + { + Debug.WriteLine(email); + } + + // Обновляем основную таблицу (только валидные email) + emailTable.Rows.Clear(); + foreach (var email in validEmails) + { + emailTable.Rows.Add(email); + } + dataGridView1.DataSource = emailTable; + + // Обновляем таблицу невалидных email + var invalidEmailTable = new DataTable(); + invalidEmailTable.Columns.Add("Invalid Emails", typeof(string)); + foreach (var email in invalidEmails) + { + invalidEmailTable.Rows.Add(email); + } + dataGridView2.DataSource = invalidEmailTable; + + // Обновляем статус + lblStatus.Text = $"Проверка завершена! Корректных адресов: {validEmails.Count}, невалидных: {invalidEmails.Count}."; + lblStatus.ForeColor = Color.Green; + } + + + + + + + + } }