Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6f9ffe6875 | ||
![]() |
1540e13d57 |
70
NoDuplicate/Form1.Designer.cs
generated
70
NoDuplicate/Form1.Designer.cs
generated
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user