using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using OfficeOpenXml; using OfficeOpenXml; namespace NoDuplicate { public partial class Form1 : Form { private DataTable emailTable; // Таблица для хранения данных public Form1() { InitializeComponent(); } private void импортToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog { Filter = "Excel Files|*.xlsx", Title = "Выберите файл с email-адресами" }; if (openFileDialog.ShowDialog() == DialogResult.OK) { string filePath = openFileDialog.FileName; try { // Указываем лицензионный контекст для EPPlus OfficeOpenXml.ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; using (var package = new ExcelPackage(new FileInfo(filePath))) { var worksheet = package.Workbook.Worksheets[0]; // Первый лист int rows = worksheet.Dimension.Rows; // Количество строк emailTable = new DataTable(); emailTable.Columns.Add("Email", typeof(string)); for (int row = 1; row <= rows; row++) { string email = worksheet.Cells[row, 1].Text; if (!string.IsNullOrEmpty(email)) { emailTable.Rows.Add(email); } } dataGridView1.DataSource = emailTable; //MessageBox.Show("Данные успешно загружены!", "Импорт"); } } catch (Exception ex) { MessageBox.Show($"Ошибка при импорте файла: {ex.Message}", "Ошибка"); } } } private List removedEmails = new List(); // Список для хранения удалённых адресов private string reportsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyAppReports"); // Путь к папке для отчётов private void SaveReport() { try { // Проверяем и создаём директорию, если её нет if (!Directory.Exists(reportsDirectory)) { Directory.CreateDirectory(reportsDirectory); } // Проверяем, есть ли удалённые адреса if (removedEmails.Count == 0) { MessageBox.Show("Нет удалённых адресов для отчёта.", "Информация"); return; } // Формируем имя файла отчёта string reportFileName = $"RemovedEmailsReport_{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("Список удалённых адресов:"); foreach (var email in removedEmails) { writer.WriteLine(email); } } //MessageBox.Show($"Отчёт сохранён в папке: {reportsDirectory}", "Успех"); } catch (Exception ex) { MessageBox.Show($"Ошибка при сохранении отчёта: {ex.Message}", "Ошибка"); } } private void btnRemoveDuplicates_Click(object sender, EventArgs e) { if (emailTable == null || emailTable.Rows.Count == 0) { lblStatus.Text = "Таблица пуста или не загружена."; lblStatus.ForeColor = Color.Red; // Красный цвет для ошибки return; } try { var allEmails = emailTable.AsEnumerable() .Select(row => row.Field("Email").Trim()) .ToList(); var distinctEmails = allEmails.Distinct(StringComparer.OrdinalIgnoreCase).ToList(); removedEmails = allEmails .GroupBy(email => email, StringComparer.OrdinalIgnoreCase) .Where(group => group.Count() > 1) .SelectMany(group => group.Skip(1)) .ToList(); emailTable.Rows.Clear(); foreach (var email in distinctEmails) { emailTable.Rows.Add(email); } dataGridView1.DataSource = emailTable; SaveReport(); // Обновляем сообщение на форме lblStatus.Text = $"Удаление завершено! Удалено {removedEmails.Count} адрес(ов)."; lblStatus.ForeColor = Color.Green; // Зелёный цвет для успеха } catch (Exception ex) { lblStatus.Text = $"Ошибка: {ex.Message}"; lblStatus.ForeColor = Color.Red; // Красный цвет для ошибки } } private void экспортToolStripMenuItem_Click(object sender, EventArgs e) { if (emailTable == null || emailTable.Rows.Count == 0) { MessageBox.Show("Нет данных для экспорта.", "Ошибка"); return; } // Открываем диалог для выбора места сохранения файла SaveFileDialog saveFileDialog = new SaveFileDialog { Filter = "Excel Files|*.xlsx", Title = "Сохранить как", FileName = "Emails.xlsx" }; if (saveFileDialog.ShowDialog() == DialogResult.OK) { string filePath = saveFileDialog.FileName; try { OfficeOpenXml.ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; using (var package = new OfficeOpenXml.ExcelPackage()) { // Создаем новый лист var worksheet = package.Workbook.Worksheets.Add("Emails"); // Записываем данные из DataTable в Excel for (int i = 0; i < emailTable.Rows.Count; i++) { worksheet.Cells[i + 1, 1].Value = emailTable.Rows[i]["Email"]; // Первая строка без заголовка } // Сохраняем файл package.SaveAs(new FileInfo(filePath)); } //MessageBox.Show("Данные успешно экспортированы!", "Успех"); } catch (Exception ex) { MessageBox.Show($"Ошибка при экспорте файла: {ex.Message}", "Ошибка"); } } } private void помощьToolStripMenuItem_Click(object sender, EventArgs e) { 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Вы можете открыть эту папку вручную или добавить кнопку для её быстрого открытия."); } } }