Я пытаюсь автоматизировать некоторые тесты для надстройки Excel, которая находится в форме xll. У меня есть некоторые проблемы при загрузке xll. Я пишу его в С#, и мой код выглядит так:
using Microsoft.Office.Interop.Excel;
Application xlApp;
Workbook xlWorkBook;
Worksheet xlWorkSheet;
// create application, open workbook, etc ...
// now try to register xll
xlApp.RegisterXLL("C:\\SomePath\\Whatever.xll");
Однако это всегда возвращает false. Я пытаюсь увидеть, что Excel тайно делает, когда я загружаю xll вручную, записывая макрос. Макрос выглядит так:
Sub Macro1()
ChDir "C:\SomePath"
Application.RegisterXLL Filename:= _
"C:\SomePath\Whatever.xll"
End Sub
Единственное отличие - это ChDir, поэтому я изменил свой код на:
FileSystem.ChDir("C:\\SomePath");
xlApp.RegisterXLL("C:\\SomePath\\Whatever.xll");
Но это все еще не работает. Еще одна особенность заключается в том, что когда я поставил точку останова перед линией RegisterXLL и сначала загрузил xll вручную, метод RegisterXLL вернет true. Но в противном случае он вернет false.
Спасибо за все предложения.
Я решил проблему, изменив путь к файлу по умолчанию для приложения Excel.
Application.xlApp = new ApplicationClass();
xlApp.DefaultFilePath = "C:\\SomePath";
xlApp.RegisterXLL("Whatever.xll");
Да, команда ChDir может быть важной. Это помогает Windows найти любые DLL файлы, от которых зависит любое. Причина, по которой он не решает вашу проблему, заключается в том, что FileSystem.ChDir() изменяет рабочий каталог для вашей тестовой программы, а не Excel.
Не все, что вы можете сделать. Развертывание xll делает каталог, который в системе PATH решит его. Прагматичным решением является просто запустить этот макрос.
Правильное решение было бы:
1- сохранить текущий каталог с помощью
string CurrentDir = Directory.GetCurrentDirectory()
2-, тогда вы используете
Directory.SetCurrentDirectory(dirXll);
где dirXll - это местоположение вашего xll (cf GetExecutingAssembly()).
3- Загрузите xll (RegisterXLL)
4- и окончательно используйте CurrentDir, чтобы вернуть текущий каталог в исходное местоположение.
Не забудьте добавить все DLL файлы, к которым вы хотите перевести xll в той же папке, что и xll.
Я знаю, что это не прямой ответ на ваш вопрос, но вы можете взглянуть на использование VSTO в Visual Studio. VSTO автоматизирует многие из этих проблем. Версия в VS 2010 намного лучше, чем у них, и вы можете создавать надстройки уровня приложений, а не только надстройки уровня документа. Если вам нужны пользовательские функции, вы можете использовать надстройку COM, как описано здесь:
http://blogs.officezealot.com/whitechapel/archive/2005/04/10/4514.aspx
Первоначально он был основан на этой статье:
http://blogs.msdn.com/eric_carter/archive/2004/12/01/273127.aspx
Мы используем комбинацию VSTO для нашего основного приложения и надстройку COM для пользовательских функций. Что приятно в том, что они загружаются в один и тот же домен приложения, чтобы они могли разговаривать друг с другом.
У меня возникли проблемы с загрузкой пользовательской функции [UDF] в код VBA. Он смог загрузить xll файл, но не смог вызвать.
Следующий код успешно загружает файлы XLL и позволяет вызывать функцию, определенную пользователем, из кода VBA. В этом модуле может быть реализована команда redudendent, но она работает!
Sub InstallAddIn()
On Error GoTo ErrorHandle
Application.DefaultFilePath = "D:\\MyFolder"
Application.RegisterXLL ("MyXLLFileName.xll")
Set AI = AddIns.Add(Filename:="D:\MyFolder\MyXLLFileName.xll")
If AddIns("MyXLLFileName").Installed Then
LogInformation ("My XLL is installed")
Else
LogInformation ("My XLL is NOT installed")
End If
Exit Sub
ErrorHandle:
LogInformation ("------------------------") 'Logging function that I have written. Not a std api
LogInformation (Err.HelpFile)
LogInformation (Err.HelpContext)
LogInformation (Err.Description)
LogInformation ("Error in InstallAddIn module")
LogInformation ("------------------------")
End
End Sub