Compare commits

...

2 Commits

Author SHA1 Message Date
Желонкин Денис
6f9ffe6875 Проверка на валидность + отчет 2025-01-24 14:08:12 +07:00
Желонкин Денис
1540e13d57 Добавлена проверка на валидность адресов 2025-01-24 13:53:57 +07:00
2 changed files with 219 additions and 26 deletions

View File

@ -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;
}
}

View File

@ -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
@ -72,40 +74,45 @@ namespace NoDuplicate
private List<string> removedEmails = new List<string>(); // Список для хранения удалённых адресов
private string reportsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyAppReports"); // Путь к папке для отчётов
private void SaveReport()
private void SaveReport(List<string> validEmails, List<string> invalidEmails, List<string> removedEmails)
{
try
{
// Проверяем и создаём директорию, если её нет
if (!Directory.Exists(reportsDirectory))
{
Directory.CreateDirectory(reportsDirectory);
}
// Проверяем, есть ли удалённые адреса
if (removedEmails.Count == 0)
{
MessageBox.Show("Нет удалённых адресов для отчёта.", "Информация");
return;
}
// Формируем имя файла отчёта
string reportFileName = $"RemovedEmailsReport_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
string reportFileName = $"EmailReport_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
string reportPath = Path.Combine(reportsDirectory, reportFileName);
// Записываем данные в файл
using (StreamWriter writer = new StreamWriter(reportPath))
{
writer.WriteLine($"Отчёт о удалённых адресах ({DateTime.Now}):");
writer.WriteLine($"Всего удалено: {removedEmails.Count}");
writer.WriteLine("Список удалённых адресов:");
writer.WriteLine($"Отчёт о проверке email-адресов ({DateTime.Now}):");
writer.WriteLine("\nКорректные email:");
writer.WriteLine($"Всего корректных адресов: {validEmails.Count}");
foreach (var email in validEmails)
{
writer.WriteLine(email);
}
writer.WriteLine("\nНевалидные email:");
writer.WriteLine($"Всего невалидных адресов: {invalidEmails.Count}");
foreach (var email in invalidEmails)
{
writer.WriteLine(email);
}
writer.WriteLine("\nУдалённые дубликаты:");
writer.WriteLine($"Всего удалено дубликатов: {removedEmails.Count}");
foreach (var email in removedEmails)
{
writer.WriteLine(email);
}
}
//MessageBox.Show($"Отчёт сохранён в папке: {reportsDirectory}", "Успех");
MessageBox.Show($"Отчёт сохранён в папке: {reportsDirectory}", "Успех");
}
catch (Exception ex)
{
@ -114,6 +121,9 @@ namespace NoDuplicate
}
private void btnRemoveDuplicates_Click(object sender, EventArgs e)
{
if (emailTable == null || emailTable.Rows.Count == 0)
@ -129,7 +139,11 @@ namespace NoDuplicate
.Select(row => row.Field<string>("Email").Trim())
.ToList();
var distinctEmails = allEmails.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
// Проверяем валидность email
var validEmails = allEmails.Where(email => IsValidEmail(email)).ToList();
var invalidEmails = allEmails.Except(validEmails).ToList();
var distinctEmails = validEmails.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
removedEmails = allEmails
.GroupBy(email => email, StringComparer.OrdinalIgnoreCase)
@ -145,7 +159,8 @@ namespace NoDuplicate
dataGridView1.DataSource = emailTable;
SaveReport();
// Передаем все три списка в метод SaveReport
SaveReport(validEmails, invalidEmails, removedEmails);
// Обновляем сообщение на форме
lblStatus.Text = $"Удаление завершено! Удалено {removedEmails.Count} адрес(ов).";
@ -215,5 +230,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<string>();
var invalidEmails = new List<string>();
foreach (DataRow row in emailTable.Rows)
{
string email = row.Field<string>("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;
}
}
}