Compare commits

..

No commits in common. "master" and "1.0.0" have entirely different histories.

2 changed files with 26 additions and 219 deletions

View File

@ -38,13 +38,8 @@
this.помощьToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.помощьToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
this.lblStatus = 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(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.menuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// dataGridView1 // dataGridView1
@ -53,17 +48,17 @@
this.dataGridView1.AllowUserToDeleteRows = false; this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Location = new System.Drawing.Point(12, 51); this.dataGridView1.Location = new System.Drawing.Point(12, 36);
this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true; this.dataGridView1.ReadOnly = true;
this.dataGridView1.Size = new System.Drawing.Size(281, 389); this.dataGridView1.Size = new System.Drawing.Size(464, 389);
this.dataGridView1.TabIndex = 0; this.dataGridView1.TabIndex = 0;
// //
// btnRemoveDuplicates // btnRemoveDuplicates
// //
this.btnRemoveDuplicates.Location = new System.Drawing.Point(12, 446); this.btnRemoveDuplicates.Location = new System.Drawing.Point(12, 431);
this.btnRemoveDuplicates.Name = "btnRemoveDuplicates"; this.btnRemoveDuplicates.Name = "btnRemoveDuplicates";
this.btnRemoveDuplicates.Size = new System.Drawing.Size(134, 23); this.btnRemoveDuplicates.Size = new System.Drawing.Size(126, 23);
this.btnRemoveDuplicates.TabIndex = 1; this.btnRemoveDuplicates.TabIndex = 1;
this.btnRemoveDuplicates.Text = "Удалить дубликаты"; this.btnRemoveDuplicates.Text = "Удалить дубликаты";
this.btnRemoveDuplicates.UseVisualStyleBackColor = true; this.btnRemoveDuplicates.UseVisualStyleBackColor = true;
@ -76,7 +71,7 @@
this.помощьToolStripMenuItem}); this.помощьToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(620, 24); this.menuStrip1.Size = new System.Drawing.Size(488, 24);
this.menuStrip1.TabIndex = 2; this.menuStrip1.TabIndex = 2;
this.menuStrip1.Text = "menuStrip1"; this.menuStrip1.Text = "menuStrip1";
// //
@ -113,7 +108,7 @@
// label1 // label1
// //
this.label1.AutoSize = true; this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(159, 451); this.label1.Location = new System.Drawing.Point(159, 436);
this.label1.Name = "label1"; this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(44, 13); this.label1.Size = new System.Drawing.Size(44, 13);
this.label1.TabIndex = 3; this.label1.TabIndex = 3;
@ -123,60 +118,16 @@
// //
this.lblStatus.AutoSize = true; 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.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, 451); this.lblStatus.Location = new System.Drawing.Point(209, 436);
this.lblStatus.Name = "lblStatus"; this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(0, 13); this.lblStatus.Size = new System.Drawing.Size(0, 13);
this.lblStatus.TabIndex = 4; 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 // Form1
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(620, 506); this.ClientSize = new System.Drawing.Size(488, 462);
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.lblStatus);
this.Controls.Add(this.label1); this.Controls.Add(this.label1);
this.Controls.Add(this.btnRemoveDuplicates); this.Controls.Add(this.btnRemoveDuplicates);
@ -189,7 +140,6 @@
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.menuStrip1.ResumeLayout(false); this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout(); this.menuStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@ -206,10 +156,6 @@
private System.Windows.Forms.ToolStripMenuItem помощьToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem помощьToolStripMenuItem;
private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lblStatus; 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,8 +10,6 @@ using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using OfficeOpenXml; using OfficeOpenXml;
using OfficeOpenXml; using OfficeOpenXml;
using System.Text.RegularExpressions;
using System.Diagnostics;
namespace NoDuplicate namespace NoDuplicate
@ -74,45 +72,40 @@ namespace NoDuplicate
private List<string> removedEmails = new List<string>(); // Список для хранения удалённых адресов private List<string> removedEmails = new List<string>(); // Список для хранения удалённых адресов
private string reportsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyAppReports"); // Путь к папке для отчётов private string reportsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyAppReports"); // Путь к папке для отчётов
private void SaveReport(List<string> validEmails, List<string> invalidEmails, List<string> removedEmails) private void SaveReport()
{ {
try try
{ {
// Проверяем и создаём директорию, если её нет
if (!Directory.Exists(reportsDirectory)) if (!Directory.Exists(reportsDirectory))
{ {
Directory.CreateDirectory(reportsDirectory); Directory.CreateDirectory(reportsDirectory);
} }
string reportFileName = $"EmailReport_{DateTime.Now:yyyyMMdd_HHmmss}.txt"; // Проверяем, есть ли удалённые адреса
if (removedEmails.Count == 0)
{
MessageBox.Show("Нет удалённых адресов для отчёта.", "Информация");
return;
}
// Формируем имя файла отчёта
string reportFileName = $"RemovedEmailsReport_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
string reportPath = Path.Combine(reportsDirectory, reportFileName); string reportPath = Path.Combine(reportsDirectory, reportFileName);
// Записываем данные в файл
using (StreamWriter writer = new StreamWriter(reportPath)) using (StreamWriter writer = new StreamWriter(reportPath))
{ {
writer.WriteLine($"Отчёт о проверке email-адресов ({DateTime.Now}):"); writer.WriteLine($"Отчёт о удалённых адресах ({DateTime.Now}):");
writer.WriteLine($"Всего удалено: {removedEmails.Count}");
writer.WriteLine("\nКорректные email:"); writer.WriteLine("Список удалённых адресов:");
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) foreach (var email in removedEmails)
{ {
writer.WriteLine(email); writer.WriteLine(email);
} }
} }
MessageBox.Show($"Отчёт сохранён в папке: {reportsDirectory}", "Успех"); //MessageBox.Show($"Отчёт сохранён в папке: {reportsDirectory}", "Успех");
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -121,9 +114,6 @@ namespace NoDuplicate
} }
private void btnRemoveDuplicates_Click(object sender, EventArgs e) private void btnRemoveDuplicates_Click(object sender, EventArgs e)
{ {
if (emailTable == null || emailTable.Rows.Count == 0) if (emailTable == null || emailTable.Rows.Count == 0)
@ -139,11 +129,7 @@ namespace NoDuplicate
.Select(row => row.Field<string>("Email").Trim()) .Select(row => row.Field<string>("Email").Trim())
.ToList(); .ToList();
// Проверяем валидность email var distinctEmails = allEmails.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
var validEmails = allEmails.Where(email => IsValidEmail(email)).ToList();
var invalidEmails = allEmails.Except(validEmails).ToList();
var distinctEmails = validEmails.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
removedEmails = allEmails removedEmails = allEmails
.GroupBy(email => email, StringComparer.OrdinalIgnoreCase) .GroupBy(email => email, StringComparer.OrdinalIgnoreCase)
@ -159,8 +145,7 @@ namespace NoDuplicate
dataGridView1.DataSource = emailTable; dataGridView1.DataSource = emailTable;
// Передаем все три списка в метод SaveReport SaveReport();
SaveReport(validEmails, invalidEmails, removedEmails);
// Обновляем сообщение на форме // Обновляем сообщение на форме
lblStatus.Text = $"Удаление завершено! Удалено {removedEmails.Count} адрес(ов)."; lblStatus.Text = $"Удаление завершено! Удалено {removedEmails.Count} адрес(ов).";
@ -230,129 +215,5 @@ 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Вы можете открыть эту папку вручную или добавить кнопку для её быстрого открытия."); 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;
}
} }
} }