Работа с бинарными данными и реестром Windows на платформе .NET

Статья - Компьютеры, программирование

Другие статьи по предмету Компьютеры, программирование

p>Если Excel уже запущен (COM-объект Excel присутствует), то вызов данного метода вернет ссылку на объект-отображение Excel в .NET, которые Вы сможете использовать для дальнейшей работы. Если Excel не запущен, то возникнет исключение.

Для запуска Excel необходимо воспользоваться классом Activator, описанным в пространстве имен System.

string sAppProgID = "Excel.Application";

// Получаем ссылку на интерфейс IDispatch

Type tExcelObj = Type.GetTypeFromProgID(sAppProgID);

// Запускаем Excel

object oExcel = Activator.CreateInstance(tExcelObj);

После того, как Вы получили ссылку на работающее приложение Excel, или же запустили его, Вам становится доступно вся объектная модель Excel. С точки зрения программиста она выглядит так:

Рис. 1. Объектная модель Excel

Нам для работы необходимо получить вместе с объектом Excel, ссылку на его коллекцию книг, и с ее помощью мы можем получить доступ к любой книге. У каждой книги есть коллекция страниц, ссылку на которую мы также должны получить для доступа к конкретной странице. Хочу сразу заметить, что доступ к книгам и к страницам мы можем получить как по их имени, так и по их порядковому номеру, причем, что самое важное: нумерация книг и страниц в коллекции начинается с единицы, а не с нуля (как принято нумеровать массивы в .NET). Отмечу, что хотя в Visual Basic for Excel есть директива Option Base, на порядок нумерации в коллекциях в наше случае он не влияет.

Для того, чтобы корректно завершить работу с приложением Excel, для всех объектов, которые мы получаем поздним связыванием, нам необходимо применить метод ReleaseComObject класса Marshal:

// Уничтожение объекта Excel.

Marshal.ReleaseComObject(oExcel);

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

GC.GetTotalMemory(true);

Отмечу сразу, что если вызов GC.Collect() не помогает, то попробуйте очистку памяти этим способом. Если проигнорировать эту операцию, то в памяти останутся объекты Excel, которые будут существовать даже после того, как Вы завершите свое приложение и Excel. Если после этого запустить приложение NET и попытаться получить ссылку на работающий Excel, то мы без проблем ее получим. Но если мы заходим сделать Excel видимым (Установив ему свойство Visible в true), то при наличии MSExcel версии ранней, чем 2003, основное окно Excel прорисовывалось не полностью. На экране присутствовали только панели инструментов и окантовка основного окна. В MS Excel 2003 вроде бы такого не наблюдается.

Но, тем не менее, если Ваша программа получает ссылки на какие-либо объекты Excel, Вы обязательно должны вызвать для них ReleaseComObject() класса Marshal.

А перед завершением работы с Excel обязательно произведите очистку памяти:

GC.GetTotalMemory(true);

3. Управление книгами и страницами.

Позднее связывание подразумевает, что нам неизвестен тип объекта, с которым мы хотим работать, а это значит, что мы не можем применять непосредственно обращаться к его методам и полям, используя оператор ".". Поэтому для вызова метода, нам необходимо знать его название и список формальных параметров, которые он принимает. Для вызова метода в классе Type предусмотрен метод InvokeMember(). Поэтому нам достаточно получить ссылку на экземпляр класса Type, описывающий тип объекта, с которым мы устанавливаем позднее связывание, и вызвать метод InvokeMember()/ Я не буду останавливаться подробно на этом методе, он достаточно хорошо описан в технической документации. Отмечу только самое необходимое, с которым мы будем непосредственно работать.

Метод InvokeMember() перегружен, и имеет три модификации.

public object InvokeMember(string name, BindingFlags flags, Binder binder, object target, object[] args);

public object InvokeMember(string name, BindingFlags flags, Binder binder, object target, object[] args, CultureInfo info);

public abstract object InvokeMember(string name, BindingFlags flags, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo info, string[] namedParameters);

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

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

BindingFlags.InvokeMethod - Найти метод, определить его точку входа, и выполнить передав ему массив фактических параметров.

BindingFlags.GetProperty - Установить свойство

BindingFlags.SetProperty - Получить значение свойства.

Третий параметр - binder - мы устанавливаем в null - он нам не нужен.

Через четвертый параметр - target - мы передаем ссылку на объект, к методу которого мы хотим обратиться.

Пятый параметр - args - это массив с параметрами, который принимает на вход вызываемый поздним связыванием метод, или массив, который содержит один элемент - значение свойство, которое мы устанавливаем.

Метод InvokeMember() возвращает результат выполнения метода или значение свойства.

Для управления книгами и страницами в первую очередь нужно получить ссылку на их коллекции. Для получения ссылки на коллекцию книг необходимо выполнить следующий код (считается, что ссылка на oExcel успешно получена):

object oWorkbooks = oExcel.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, oExcel, null);

Объект oWorkbooks и есть managed-ссылка на коллекцию книг.

Для получения доступа к конкретной книге выполняем следующий код, используя коллекцию книг:

// Доступ к книге по ее порядковому номеру

// Создаем массив параметров

object[] args = new object[1];

// Мы хотим получить доступ к первой книге Excel

args[0] = 1;

// Получаем ссылку на первую книгу в коллекции Excel

object oWorkbook = oWorkbooks.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, oWorkbooks, ar