Разработка
NTA

Создание программы на C# для объединения похожих Excel-файлов в один

Как не тратить драгоценное время на объединение Excel-файлов одинакового формата в один файл? Расскажем в статье…

Часто аналитикам в работе необходимо объединять Excel-файлы одинакового формата в один файл. Для этого приходится открывать каждый файл, копировать из него информацию и вставлять в сводный файл. Эта работа занимает порой от 5 до 30 минут, а иногда и больше. Чтобы не тратить драгоценное в наши дни время на данное рутинное занятие, можно создать программу, которая будет делать это за вас.

Рассмотрим пример несложной программы, написанной на языке программирования C#. Ее функционал следующий:

— объединять несколько одинаковых Excel-файлов в один. В каждом файле будем считывать только первый лист. Все файлы могут быть расположены в одной папке (1)или во вложенных папках (2):

Изображение 1
Изображение 2

— В файлах первая строка может содержать названия столбцов (3) или названия столбцов могут отсутствовать (4).

Изображение 3
Изображение 4

— Программа может объединять не все столбцы, а определенное количество, считая с первого. Например, в файлах может быть 20 столбцов, но нужно объединить только первые 10.

Для создания программы используется Visual Studio.

На форме (5) нужно создать следующие элементы:

  1. текстовое поле (TextBox) для отображения выбранной директории, где размещены Excel-файлы, которые необходимо обработать.
  2. текстовое поле с маской (MaskedTextBox) для указания количества столбцов, считая с 1. Выставляем свойство Mask равным Numeric.
  3. кнопка Button1 – свойство Text: «Выбрать директорию».
  4. кнопка Button2 – свойство Text: «Запуск».
  5. «галочка» (CheckBox) – свойство Text: «Первая строка содержит заголовки».
  6. «галочка» (CheckBox) – свойство Text: «Склеить файлы во вложенных папках».
  7. текстовая подпись Label1 – свойство Text: «Директория на выбранные файлы:».
  8. текстовая подпись Label2 – свойство Text: «Кол-во столбцов».
Изображение 5

Теперь нужно создать события нажатия (Click) на кнопки Button1 и Button2.

Кнопка Button1 «Выбрать директорию» будет открывать диалоговое окно для указания директории, где расположены все Excel-файлы, которые нужно объединить.

Код:

private void button1_Click(object sender, EventArgs e) { FolderBrowserDialog fbd = new FolderBrowserDialog(); if (fbd.ShowDialog() == DialogResult.OK) { textBox1.Text= fbd.SelectedPath; } }

Кнопка Button2 «Запуск» проверяет, что выбрана директория и указано количество столбцов и запускает функцию, которая объединяет файлы.

private void button2_Click(object sender, EventArgs e) { if (maskedTextBox1.Text != "" && textBox1.Text != "") { button1.Enabled = false; button2.Enabled = false; //Функция объединения файлов JoinExcelFiles(); GC.GetTotalMemory(true); Application.Exit(); } }

Теперь нужно создать функцию, которая объединяет все файлы Excel в один:

private void JoinExcelFiles() { string dataInd = DateTime.Now.ToString("dd.MM.yyyy HH mm ss");//дата время запуска программы string pathExe = Application.StartupPath.ToString() + "\\";//путь к файлу exe string nameFolder = ""; Excel.Application excel; Excel.Workbook wbInputExcel, wbResultExcel;//книги Excel Excel.Worksheet wshInputExcel, wshResultExcel;//листы Excel //создаем папку в которой будем сохранять все промежуточные файлы и результат nameFolder = "Выгрузка_" + dataInd + "\\"; if (Directory.Exists(pathExe + nameFolder)) { } else { DirectoryInfo di = Directory.CreateDirectory(pathExe + nameFolder); } excel = new Excel.Application(); //создание сводного файла Excel, в который будут объединяться все файлы wbResultExcel = excel.Workbooks.Add(System.Reflection.Missing.Value); wshResultExcel = wbResultExcel.Sheets[1]; wshResultExcel.Name = "Лист1"; string nameFile = "Result.xlsx"; wbResultExcel.SaveAs(pathExe + nameFolder + nameFile); excel.DisplayAlerts = false; string[] ourfiles; //если отмечена галочка в CheckBox, то ищем файлы по всех вложенных папках if (checkBox2.Checked) { ourfiles = Directory.GetFiles(textBox1.Text, "*xls*", SearchOption.AllDirectories); } else { ourfiles = Directory.GetFiles(textBox1.Text, "*xls*", SearchOption.TopDirectoryOnly);} //открываем первый файл и полностью его копируем. wbInputExcel = excel.Workbooks.Open(ourfiles[0]); wshInputExcel = (Excel.Worksheet)wbInputExcel.Worksheets.get_Item(1); int numInputRow = wshInputExcel.Cells[wshInputExcel.Rows.Count, "A"].End[Excel.XlDirection.xlUp].Row; wshInputExcel.Range[wshInputExcel.Cells[1, 1], wshInputExcel.Cells[numInputRow, Convert.ToInt32(maskedTextBox1.Text)]].Copy(); //вставляем в сводный файл wshResultExcel.Range["A1"].PasteSpecial(Excel.XlPasteType.xlPasteValues); wbResultExcel.Save(); wbInputExcel.Close(); ReleaseObject(wshInputExcel); ReleaseObject(wbInputExcel); int strBeginInput = 0; //если отмечена галочка, что в файлах первая строка содержит названия столбцов, то все остальные файлы копируем со второй строки if (checkBox1.Checked) strBeginInput = 2; else strBeginInput = 1; //проходимся по остальным файлам, копируем данные и вставляем в сводный файл for (int f = 1; f <= ourfiles.Length - 1; f++) { wbInputExcel = excel.Workbooks.Open(ourfiles[f]); wshInputExcel = (Excel.Worksheet)wbInputExcel.Worksheets.get_Item(1); numInputRow = wshInputExcel.Cells[wshInputExcel.Rows.Count, "A"].End[Excel.XlDirection.xlUp].Row; wshInputExcel.Range[wshInputExcel.Cells[strBeginInput, 1], wshInputExcel.Cells[numInputRow, Convert.ToInt32(maskedTextBox1.Text)]].Copy(); int numResultRow = wshResultExcel.Cells[wshResultExcel.Rows.Count, "A"].End[Excel.XlDirection.xlUp].Row; wshResultExcel.Range[wshResultExcel.Cells[numResultRow+1,1], wshResultExcel.Cells[numResultRow+numInputRow, Convert.ToInt32(maskedTextBox1.Text)]].PasteSpecial(Excel.XlPasteType.xlPasteValues); wbInputExcel.Close(false); } //сохраняем итоговый файл, закрываем, обнуляем все ссылки, запускаем «сборщик мусора» wbResultExcel.Save(); wbResultExcel.Close(false); wshInputExcel = null; wshResultExcel = null; wbInputExcel = null; wbResultExcel = null; excel = null; GC.Collect(); //выдается сообщение пользователю об окончании и открывается папка с итоговым файлом MessageBox.Show("ВСЕ ОК"); System.Diagnostics.Process.Start("explorer.exe", @"/select, " + pathExe + nameFolder); }

Это был пример самой простой программы, которая позволит быстро объединить одинаковые файлы. Конечно, ее можно еще дорабатывать и сделать более универсальной. Например, чтобы она объединяла файлы, в которых: названия столбцов занимают несколько строк, указывать перечень столбцов для обработки и т.д.

Такие несложные программы высвобождают много времени, которое можно потратить на более интересное и важное занятие.

0
4 комментария
Yarik Elk

Почему вы не использовали PowerQuery, который "из коробки" есть в Excel?

Ответить
Развернуть ветку
NTA
Автор

Вы правы! PowerQuery - очень удобный инструмент. Переводим постепенно на него решение многих задач! 

Ответить
Развернуть ветку
Alexey Kuznetsov

Сколько трудочасов потратили на эту задачу интересно)) разрабам совсем скучно у вас)

Ответить
Развернуть ветку
NTA
Автор

Задача по объединению файлов ставится довольно часто, поэтому решили автоматизировать её таким способом.

Ответить
Развернуть ветку
Читать все 4 комментария
null