Работа с гиперссылками в Excel через позднее привязывание
При обращении к свойствами или методами любых объектов приложений MS Office необходимо увязать эти обращения с целевыми объектами. Существует два типа связывания: раннее и позднее.
Раннее связывание позволяет осуществить ряд проверок на валидность типов параметров и сущностей вызываемых объектов, но не поддерживает совместимость в работе при вызове методов из разных версий документов MS Office.
Позднее привязывание сопоставляет вызовы свойств и методов соответствующим объектам уже в процессе выполнения программы. Данная схема применяется в системах, где используется несколько версий MS Office или поддерживаются разные архитектуры процессоров.
Столкнулся недавно с потребностью извлечения адресов гиперссылок, привязанных к ячейкам при работе с данными Excel документов.
Поиски готовых примеров, описаний или алгоритмов как это реализуется в интернете, ни к чему не привели. Поэтому предлагаю свою реализацию этого.
Код самой функции:
// Получить ссылку ячейки
public string GetLink(string AAddress)
{
try
{
FRange = FWorksheet.GetType().InvokeMember("Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress }); // Формируем Range для переданного AAddress
var HyperLinks = FRange.GetType().InvokeMember("Hyperlinks", System.Reflection.BindingFlags.GetProperty, null, FRange, null); // Получаем массив гиперссылок
if( HyperLinks != null )
{
var count =(int)HyperLinks.GetType().InvokeMember("Count", System.Reflection.BindingFlags.GetProperty, null, HyperLinks ,null); // Считаем ссылки
if( count > 0 )
{
var HyperLink = HyperLinks.GetType().InvokeMember("Item", System.Reflection.BindingFlags.GetProperty, null, HyperLinks , new object[]{1}); // Из массива ссылок берём первую
if(HyperLink != null )
{
return HyperLink .GetType().InvokeMember("Address", System.Reflection.BindingFlags.GetProperty, null, HyperLink , null).ToString(); // Возвращаем адрес гиперссылки
}
}
}
}
catch(Exception e)
{
Service.UI.ShowMessage( e.Message+"\r\nИсточник: " + e.Source.SafeToString() + "\r\nСтэк: " + e.StackTrace.SafeToString());
}
return null;
}
Код класса для работы с документом и пример вызова:
public static void Main(string[] args)
{
Excel doc = new Excel();
doc.Visible = true;
doc.OpenBook( @"C:\Имя_документа.xls" );
doc.OpenWorksheet(1);
string link = doc.GetLink("A1");
Service.UI.ShowMessage("Ссылка: "+link);
}
public class Excel : IDisposable
{
object FExcel = null;
object FWorkbooks, FWorkbook, FWorksheets, FWorksheet, FRange;
// Конструктор
public Excel()
{
FExcel = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
}
// Деструктор
public void Dispose()
{
FWorkbooks = null;
FWorkbook = null;
FWorksheets = null;
FWorksheet = null;
FRange = null;
System.Runtime.InteropServices.Marshal.ReleaseComObject(FExcel);
GC.GetTotalMemory(true);
}
// Видимость
public bool Visible
{
get
{
return Convert.ToBoolean(FExcel.GetType().InvokeMember(
"Visible", System.Reflection.BindingFlags.GetProperty, null, FExcel, null));
}
set
{
FExcel.GetType().InvokeMember(
"Visible", System.Reflection.BindingFlags.SetProperty, null, FExcel, new object[] { value });
}
}
// Открыть книгу
public void OpenBook(string AFilePath)
{
FWorkbooks = FExcel.GetType().InvokeMember(
"Workbooks", System.Reflection.BindingFlags.GetProperty, null, FExcel, null);
FWorkbook = FWorkbooks.GetType().InvokeMember(
"Open", System.Reflection.BindingFlags.InvokeMethod, null, FWorkbooks, new object[] { AFilePath, true });
FWorksheets = FWorkbook.GetType().InvokeMember(
"Worksheets", System.Reflection.BindingFlags.GetProperty, null, FWorkbook, null);
FWorksheet = FWorksheets.GetType().InvokeMember(
"Item", System.Reflection.BindingFlags.GetProperty, null, FWorksheets, new object[] { 1 });
}
// Выбрать страницу
public void OpenWorksheet(int AIndex)
{
FWorksheet = FWorksheets.GetType().InvokeMember(
"Item", System.Reflection.BindingFlags.GetProperty, null, FWorksheets, new object[] { AIndex });
}
// Закрыть книгу
public void CloseBook()
{
FWorkbook.GetType().InvokeMember(
"Close", System.Reflection.BindingFlags.InvokeMethod, null, FWorkbook, new object[] { false });
}
// Закрыть приложение
public void Quit()
{
FExcel.GetType().InvokeMember(
"Quit", System.Reflection.BindingFlags.InvokeMethod, null, FExcel, null );
}
// Количество строк
public int RowsCount()
{
FRange = FWorksheet.GetType().InvokeMember(
"UsedRange", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, null );
if ( FRange == null )
return 0;
object Rows = FRange.GetType().InvokeMember(
"Rows", System.Reflection.BindingFlags.GetProperty, null, FRange, null );
if ( Rows == null )
return 0;
int Count = (int)Rows.GetType().InvokeMember(
"Count", System.Reflection.BindingFlags.GetProperty, null, Rows, null );
Rows = null;
return Count;
}
// Получить значение с ячейки
public string GetValue(string AAddress)
{
try
{
FRange = FWorksheet.GetType().InvokeMember(
"Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress });
return FRange.GetType().InvokeMember(
"Value", System.Reflection.BindingFlags.GetProperty, null, FRange, null).ToString();
}
catch
{
}
return null;
}
// Получить ссылку ячейки
public string GetLink(string AAddress)
{
try
{
FRange = FWorksheet.GetType().InvokeMember("Range", System.Reflection.BindingFlags.GetProperty, null, FWorksheet, new object[] { AAddress }); // Формируем Range для переданного AAddress
var HyperLinks = FRange.GetType().InvokeMember("Hyperlinks", System.Reflection.BindingFlags.GetProperty, null, FRange, null); // Получаем массив гиперссылок
if( HyperLinks != null )
{
var count =(int)HyperLinks.GetType().InvokeMember("Count", System.Reflection.BindingFlags.GetProperty, null, HyperLinks ,null); // Считаем ссылки
if( count > 0 )
{
var HyperLink = HyperLinks.GetType().InvokeMember("Item", System.Reflection.BindingFlags.GetProperty, null, HyperLinks , new object[]{1}); // Из массива ссылок берём первую
if(HyperLink != null )
{
return HyperLink .GetType().InvokeMember("Address", System.Reflection.BindingFlags.GetProperty, null, HyperLink , null).ToString(); // Возвращаем адрес гиперссылки
}
}
}
}
catch(Exception e)
{
Service.UI.ShowMessage( e.Message+"\r\nИсточник: " + e.Source.SafeToString() + "\r\nСтэк: " + e.StackTrace.SafeToString());
}
return null;
}
}
Хотя список функций работы с Excel объектами далеко не полный, код класса приведён для наглядности.
Как добавить гиперссылку в ячейку?
ОтветитьУдалитьРешение найдено здесь http://zecl.hatenablog.com/entry/20080129/p1
УдалитьxlsRange = xlsSheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, xlsSheet, new object[] { "B1" });
string b1 = (string)xlsRange.GetType().InvokeMember("Value", BindingFlags.GetProperty, null, xlsRange, null);
xlHyperLinks = xlsSheet.GetType().InvokeMember("Hyperlinks", BindingFlags.GetProperty, null, xlsSheet, null);
xlHyperlink = xlHyperLinks.GetType().InvokeMember("Add",BindingFlags.InvokeMethod,null,xlHyperLinks,new object[]{xlsRange,b1});