Intereting Posts
Создание графического интерфейса с несколькими формами Как получить IP-адрес вызывающего абонента в WebMethod? Windows Phone, выберите файл с помощью PickSingleFileAndContinue или PickMultipleFilesAndContinue Entity Framework – значения по умолчанию не заданы в таблице сервера sql .NET заменяет непечатаемый ASCII строковым представлением шестнадцатеричного кода Получить член, к которому был применен атрибут из внутреннего конструктора атрибутов? Может ли задача иметь несколько ожидающих? Как я могу добавить в первую позицию списка? Как написать в определенном месте zapfdingbatslist в pdf-документе с помощью iTextSharp 64-разрядная арифметика указателя в C #, проверка поведения арифметических переполнений C # назначить char и char array для строки? Скрыть некоторую ячейку флажка datagridview Как легко создать Excel UDF с проектом надстройки VSTO Ядро Entity Framework: тип Udt не поддерживается на этой платформе. (Пространственные данные – география) Как отправить большие данные с помощью C # UdpClient?

Как выставить class C # для модуля VBA в надстройке уровня документа?

Это гипотетическая ситуация.

Я хотел бы узнать, можно ли выставить class C # для VBA в надстройке уровня документа.

Вот SSCCE:

В VS PRO 2012 я начал новый проект, Selected Office -> Excel 2010 Workbook . ( убедитесь, что вы выбрали .Net framework ver 4 )

Я добавил элемент управления DateTimePicker в Sheet1.

Я могу установить / получить свойство .Value с помощью DateTimePicker управления DateTimePicker в решении C # без проблем.

При отладке: В VBA свойство .Value не отображается. ( проверено .OLEFormat.Object.Value )

введите описание изображения здесь

Не все свойства могут быть выставлены VBA, потому что элемент управления ActiveX DateTimePicker обернут MSForms поэтому Excel распознает его (совместимость).

Мне нужно иметь возможность захватить фактическое значение обернутого элемента управления из VBA, но я не уверен, как это сделать (возможно ли это или нет ) …

Я знаю, что сам элемент управления поддерживает события, но это не тот путь, который я хочу принять. Я хочу, чтобы убрать значение статического / текущего с элемента управления.

Это то, что я хотел бы сделать:

  • Добавить class в мое решение C #

  • Выложите его, поэтому он может быть исправлен с VBA, как Dim obj as new MyExposedClass

  • тогда MyExposedClass сохранит ссылку на DateTimePicker как она появляется на C # (все доступные свойства)

  • то я могу определить функцию GetValue(string controlName) которая возвращает значение из C # POV

Поэтому я нашел это решение + ( этот ), которое, похоже, работает с надстройкой уровня приложения, но оно не работает с надстройкой уровня документа .

Когда я отлаживаю свое решение и открываю браузер объектов VBA, я вижу, что ссылки автоматически добавляются в Microsoft Visual Studio 2008 Tools for Office Execution Engine 9.0 Type Library но я не думаю, что могу добавить к ней дополнительный class …

Когда я открываю ссылки в VBE, в проект не добавляются дополнительные ссылки, но в папке / debug моего решения есть ExcelWorkbook1.dll так как он даже привязан к решению?

Поэтому мой вопрос:

Как я могу открыть class в надстройке уровня документа для Excel с помощью C #, чтобы расширить диапазон свойств, доступных по умолчанию на элементах управления .Net?

Обновить:

Это самое близкое, что я получил до сих пор, но он позволяет вам показывать объект хоста, такой как Рабочий лист, Рабочая тетрадь, Диаграмма и т. Д. Это позволяет вам вызывать методы, поэтому я собираюсь изучить это дальше и вернуться с некоторой обратной связью

Вызов кода в настройках уровня документа из VBA

Практическое руководство. Предоставление кода VBA в Visual C # Project

Пошаговое руководство: код вызова из VBA в проекте Visual C #

Вам нужно будет создать публичный интерфейс, чтобы подвергнуть class VBA, это работает для меня как дополнение уровня документа.

  1. Откройте новую книгу Excel и скопируйте ее в МОДУЛЬ

     Sub CallVSTOMethod() Dim dt As Date Dim VSTOSheet1 As DocLevelAddin.Sheet1 Set VSTOSheet1 = GetManagedClass(Sheet1) dt = VSTOSheet1.GetDatePickerVal End Sub 
  2. Сохраните Excel как «TestProj.xlsm» и закройте.

  3. Откройте VS, новый проект, Excel 20xx Workbook и назовите проект «DocLevelAddin»
  4. В мастере выберите копию существующего документа и выберите вновь созданную книгу «TestProj.xlsm»,
  5. На листе Excel1 добавьте элемент DateTimePicker на лист из wihin VS, дважды щелкните, чтобы создать событие ValueChanged и обновите код в Sheet1.cs, чтобы прочитать

     private DateTime dtVal; private void dateTimePicker1_ValueChanged(object sender, EventArgs e) { dtVal = dateTimePicker1.Value; } 
  6. Еще в Sheet1.cs добавьте общеansible метод для возврата dtVal

     public DateTime GetDatePickerVal() { return dtVal; } 
  7. Также добавьте следующее в Sheet1.cs

     protected override object GetAutomationObject() { return this; } 
  8. Над публичным частичным classом Sheet1 в Sheet1.cs добавьте следующее

     [System.Runtime.InteropServices.ComVisible(true)] [System.Runtime.InteropServices.ClassInterface( System.Runtime.InteropServices.ClassInterfaceType.None)] 
  9. Теперь вам нужно создать открытый интерфейс для этого метода. В Sheet1.cs щелкните правой кнопкой мыши пункт Refactor, Extract Interface и проверьте общеansible метод GetDatePickerVal

  10. Сделать интерфейс общедоступным и COM видимым

     [System.Runtime.InteropServices.ComVisible(true)] public interface ISheet1 { DateTime GetDatePickerVal(); } 
  11. Дважды щелкните Sheet1.cs, чтобы лист Excel был виден. Выберите любую ячейку, чтобы открыть окно свойств и изменить свойство ReferenceAssemblyFromVbaProject = true

  12. В Excel вам может потребоваться перейти к настройкам центра доверия и добавить папку решения и подпапки решения VS в качестве надежного местоположения

  13. Запустите проект, и код в Excel MODULE вернет DateTimepicker через открытый метод GetDatePickerVal.

введите описание изображения здесь

Sheet1.cs:

 using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using System.Xml.Linq; using Microsoft.Office.Tools.Excel; using Microsoft.VisualStudio.Tools.Applications.Runtime; using Excel = Microsoft.Office.Interop.Excel; using Office = Microsoft.Office.Core; namespace DocLevelAddin { [System.Runtime.InteropServices.ComVisible(true)] [System.Runtime.InteropServices.ClassInterface( System.Runtime.InteropServices.ClassInterfaceType.None)] public partial class Sheet1 : DocLevelAddin.ISheet1 { private void Sheet1_Startup(object sender, System.EventArgs e) { } private void Sheet1_Shutdown(object sender, System.EventArgs e) { } #region VSTO Designer generated code ///  /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///  private void InternalStartup() { this.dateTimePicker1.ValueChanged += new System.EventHandler(this.dateTimePicker1_ValueChanged); this.Startup += new System.EventHandler(this.Sheet1_Startup); this.Shutdown += new System.EventHandler(this.Sheet1_Shutdown); } #endregion private DateTime dtVal; private void dateTimePicker1_ValueChanged(object sender, EventArgs e) { dtVal = dateTimePicker1.Value; } public DateTime GetDatePickerVal() { return dtVal; } protected override object GetAutomationObject() { return this; } } } 

ISheet1.cs:

 using System; namespace DocLevelAddin { [System.Runtime.InteropServices.ComVisible(true)] public interface ISheet1 { DateTime GetDatePickerVal(); } }