Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный_практикум.doc
Скачиваний:
74
Добавлен:
15.11.2019
Размер:
45.35 Mб
Скачать

4. Модификация приложения Windows Forms: чтение данных с документа Microsoft Excel

Разместим вторую группу элементов как показано на рисунке ниже:

Рис. 4. 1. Модифицированная форма приложения и расстановка второй группы элементов

Здесь у нас один RichTextBox, один Button, один GroupBox, TextBox и OpenFileDialog. Свойства задаём такие:

Button:

(Name):

B_Get

Text:

Получить данные

Size:

130; 23

GroupBox:

(Name):

GB_Get

Text:

Получение данных из Excel

TextBox:

(Name):

textBox4

ToolTip на Hint:

Столбец

Size:

130; 23

RichTextBox:

(Name):

richTextBox1

OpenFileDialog:

(Name):

OFD_Get

FileName:

Данные для извлечения

Filter:

Файлы Excel или файлы Access|*.*

События Click кнопки Получить данные:

private void B_Get_Click(object sender, EventArgs e)

{

// Открываем файл Excel

if (OFD_Get.ShowDialog() == DialogResult.OK)

{

// Создаём приложение

Excel.Application ObjExcel2 = new Excel.Application();

// Открываем книгу

Excel.Workbook ObjWorkBook2 = ObjExcel2.Workbooks.Open(OFD_Get.FileName, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);

// Выбираем таблицу (лист)

Excel.Worksheet ObjWorkSheet2;

ObjWorkSheet2 = (Excel.Worksheet)ObjWorkBook2.Sheets[1];

// Очищаем от старого текста окно вывода

richTextBox1.Clear();

for (int i = 1; i < 101; i++)

{

// Выбираем область таблицы (в нашем случае просто ячейку)

Excel.Range range = ObjWorkSheet2.get_Range(textBox4.Text + i.ToString(), textBox4.Text + i.ToString());

// Добавляем полученный из ячейки текст

richTextBox1.Text = richTextBox1.Text + range.Text.ToString() + "\n";

// Чтобы форма прорисовывалась (не подвисала)

Application.DoEvents();

}

//Удаляем приложение (выходим из Excel)

ObjExcel2.Quit();

}

}

Найдём в файле LWP13Main.cs строчку:

InitializeComponent();

B_Insert.Enabled = false;

Добавим после:

textBox4.Text = "A";

Готово. Можно компилировать и проверять работоспособность.

Второй блок нашего приложение, как нетрудно догадаться считывает данные из столбцов. При открытии файла (базы данных Access или непосредственно книги Excel), программа считывает все данные из одного конкретного столбца (зависит от буквы или цифры в текстовом поле) и заносит всё в RichTexBox.

Рис. 4. 2. Окончательная работа второго блока: открытие базы данных Access и запрос на выбор таблицы или запроса для открытия в Excel (в Excel 2010)

Рис. 4. 3. Окончательная работа второго блока: открытие таблицы базы данных через Excel (в Excel 2010)

Жмём Не сохранять.

Рис. 4. 4. Окончательная работа второго блока: вывод данных столбца таблицы через Excel (столбец А) в приложение (в Excel 2010)

О проблеме разных версий Microsoft Office (Excel):

Существует несколько вариантов работы с Excel из C#: автоматизация Excel, подключение через OleDB/ODBC, дополнительные библиотеки (Aspose Excel), работа через XML, через Open XML и прочее.

Наиболее простой вариант воспользоваться автоматизацией Excel. Да, скорость работы - не впечатляет. Зато удобно использовать, код пишется быстро, объёмы кода не велики. Из .NET автоматизация подключается парой кликов мыши. Достаточно добавить в Ссылки сборку Microsoft.Office.Interop.Excel и можно работать с привычными объектами COM: Application, Workbook, Worksheet и прочее.

Проблема одна сборки «Microsoft.Office.Interop.Excel» для каждой версии Excel разные. Если установлен Office 2003 и, соответственно, Interop-сборка версии 11. А что делать, если мне нужно разработать приложение, которое может работать с Excel 97? Или с любыми версиями Excel? Для того, чтобы считать или записать пару значений в ячейки листа Excel сложного API не требуется любой Excel сгодится. Но приходится привязываться к конкретной версии.

Можно воспользоваться поздним связыванием. Но если его использовать «в лоб», то ни о каком удобстве работы речи уже не идёт код станет сложным, а вызовы методов косвенными, не типизированными. Ошибок будет много.

На СodeProject (http://www.codeproject.org) существует статья «SafeCOMWrapper - Managed Disposable Strongly Typed safe wrapper to late bound COM». В ней изложена элегантная методика использования позднего связывания, устраняющая все проблемы: связывание становится поздним (привязки к конкретной версии Excel нет), для объектов автоматизации автоматически реализуется шаблон IDisposable (отработанные объекты уничтожаются автоматически), все вызовы методов явные.

Идея реализации, вкратце, следующая. Для каждого COM-объекта автоматизации прописывается отдельный интерфейс. В интерфейс включаются все методы и свойства, которые необходимо использовать у этого COM-объекта. Обратим внимание только те, которые необходимо использовать, а вовсе не все, реализуемые COM-объектом.

Каждый COM-объект автоматизации «заворачивается» в класс COMWrapper, унаследованный от RealProxy. RealProxy это стандартный класс, позволяющий организовать перехват вызовов методов. При создании COM-объекта создаетётся экземпляр COMWrapper и указывается требуемый интерфейс. Среда динамически генерирует прокси-объект, реализующий этот интерфейс. С этим прокси-объектом в дальнейшем и нужно работаетть как с объектом автоматизации. Вызов любого метода прокси-объетка перехватывается и транслируется в вызов метода Invoke класса RealProxy, перекрытый в классе COMWrapper. Здесь его можно обработать как угодно. В реализации по умолчанию, вызовы свойств транслируются в вызовы соответствующих методов get_ и set_, создаваемых .NET, возвращаемые объекты автоматизации автоматически заворачиваются в COMWrapper и прочее.

В оригинальной статье приведен пример использования данной методики для Microsoft Outlook. Сам код подобной реализации из статьи можно загрузить по ссылке в конце этого материала (сслыка доступна в программном продукте).