Время прочтения: 5 мин.

Часто аналитикам в работе необходимо объединять 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);
        }

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

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