Excel 2007 UDF:как добавить описание функции, справку по аргументам?

StackOverflow https://stackoverflow.com/questions/1592440

  •  22-09-2019
  •  | 
  •  

Вопрос

Описание

Я пишу пару UDF-файлов Excel на COM-серверах.Я бы хотел получить стандартную справку (Функция вставки диалоговое окно), которое вы получаете, когда нажимаете валюта.Да, я вижу свой COM-сервер, указанный в раскрывающемся списке Категории, но

  • Я также вижу Equals, GetHashCode, GetType и toString (которые довольно нежелательно предоставлять пользователю Excel),
  • при выборе моего COM-сервера открывается диалоговое окно *Аргументы функции* [1] без информации об аргументах и описания функции.

Вот хромота, которую я получаю:

Диалоговое окно вставки функции http://www.iwebthereforeiam.com/files/Insert%20function%20dialog.gif

Диалоговое окно Параметров функции Excel http://www.iwebthereforeiam.com/files/Function%20Arguments%20dialog.gif

Этот вопрос

Существуют ли атрибуты .NET, которые я мог бы добавить к методам для передачи этого в Excel?

  • Могу ли я предоставить описание этой функции?
  • Могу ли я предоставить описание параметров?
  • Могу ли я указать название категории для своих функций, чтобы получить что-то лучшее, чем просто ProgID?

(Я вижу, что это выглядит печально простым в ExcelDNA, но я не иду этим путем.Эмулировать код говерта [пользовательские атрибуты, какой-то загрузчик и т.д.], похоже, было бы довольно сложно.)


Дополнительная справочная информация

Если вы раньше не работали с серверами Excel + COM, вот несколько полезных ресурсов для ускорения работы:

Предыдущие вопросы StackOverflow:
Как получить COM Server для Excel, написанный в VB.NET установленный и зарегистрированный в списке серверов автоматизации?
Как добавить .NET-проект, открытый для COM, в диалоговое окно ссылок на VB6 (или VBA)?

Другие ресурсы:
Написание пользовательских функций для Excel в .NET
Сборка и развертывание сборки .NET COM
Написание пользовательских функций рабочего листа Excel на C#


Редактировать 2009-10-20 14:10

Я попробовал позвонить Application.MacroOptions в Sub New().

  1. Нет дополнительного Нового ()
    Полу-приемлемый:Функция указана в категории ProgID.
  2. Общий Sub New()
    Неприемлемо:ошибка времени сборки.
    Cannot register assembly "...\Foo.dll".
    Exception has been thrown by the target of an invocation.
  3. Sub Новый()
    Неприемлемо:категория не указана в диалоговом окне Вставки функции.

Я подозреваю, что это проблема как для макроопционов, так и для более сложного маршрута, рекомендованного Чарльзом.


Редактировать 2009-10-20 14:55

С положительной стороны, рекомендация Майка создать интерфейс для реализации действительно убила раздражающие дополнительные методы, которые были предоставлены.


Редактировать 2009-10-20 15:00

Эта статья Корпорации Майкрософт с начала 2007 года (через Ссылка Майка) кажется довольно полным ответом по теме:

Надстройки автоматизации и функции Мастер

Каждая надстройка автоматизации имеет свою собственную категорию в мастере функций Excel.Название категории является идентификатором программы для надстройки;вы не можете указать другое название категории для автоматизации Функции надстройки.Кроме того, невозможно указать функцию описания, описания аргументов или справку по надстройке автоматизации функции в мастере функций.


1 Ха, ошибка StackOverflow.Похоже, вы не можете выделить строку курсивом внутри явного HTML ul-списка?

Это было полезно?

Решение

Кое-что из этого легко исправить, другие части довольно сложны.Однако все это выполнимо, если вы готовы потратить на это время.

Вы написали:

Я также вижу Equals, GetHashCode, GetType и toString (которые довольно нежелательно предоставлять пользователю Excel )

Да, согласен, это определенно нежелательно, но это можно предотвратить.Это происходит потому, что ваш класс наследуется от 'System.Object', как и все классы .NET, и ваш интерфейс по умолчанию, который доступен для COM, включает в себя эти элементы.Это происходит, например, если вы используете 'ClassInterfaceAttribute', используя параметр 'ClassInterfaceType.AutoDual'.

Например.в C#:

[ClassInterface(ClassInterfaceType.AutoDual)]

В VB.NET:

<ClassInterface(ClassInterfaceType.AutoDual)>

Однако следует избегать использования 'ClassInterfaceType.AutoDual', чтобы предотвратить наследование элементов от 'System.Объект" от раскрытия (а также для предотвращения потенциальных проблем с управлением версиями в будущем).Вместо этого определите свой собственный интерфейс, реализуйте интерфейс в своем классе, а затем пометьте свой класс атрибутом 'ClassInterface' со значением 'ClassInterfaceType.None'.

Например, используя C#:

[ComVisible(true)]
[Guid("5B88B8D0-8AF1-4741-A645-3D362A31BD37")]
public interface IClassName
{
    double AddTwo(double x, double y);
}

[ComVisible(true)]
[Guid("010B0245-55BB-4485-ABAF-46DF4356DB7B")]
[ProgId("ProjectName.ClassName")]
[ComDefaultInterface(typeof(IClassName))]
[ClassInterface(ClassInterfaceType.None)]
public class ClassName : IClassName
{
    public double AddTwo(double x, double y)
    {
        return x + y;
    }
}

Используя VB.NET:

<ComVisible(True)> _
<Guid("5B88B8D0-8AF1-4741-A645-3D362A31BD37")> _
Public Interface IClassName
    Function AddTwo(ByVal x As Double, ByVal y As Double) As Double
End Interface

<ComVisible(True)> _
<Guid("010B0245-55BB-4485-ABAF-46DF4356DB7B")> _
<ProgId("ProjectName.ClassName")> _
<ComDefaultInterface(GetType(IClassName))> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class ClassName
    Implements IClassName

    Public Function AddTwo(ByVal x As Double, ByVal y As Double) As Double _
        Implements IClassName.AddTwo
        Return x + y
    End Function
End Class

Используя 'classinterfaceатрибут' со значением 'ClassInterfaceType.None', унаследованный 'System.Члены объекта исключаются, поскольку интерфейс класса не становится COM-видимым.Вместо этого в COM экспортируется только реализованный интерфейс ('IClassName' в этом примере).

В приведенном выше примере также используется 'ComDefaultInterfaceAttribute' .Это не очень важно и ничего не дает, если вы реализуете только один интерфейс - как в этом примере, - но это хорошая идея на случай, если вы добавите интерфейс позже, например IDTExtensibility2.

Для получения более подробной информации об этом см.:

(1) Управляемые надстройки Автоматизации автор: Эндрю Уайтчепел.

(2) Написание пользовательских функций рабочего листа Excel на C# автор: Габан Берри.

Хорошо, теперь перейдем к самой сложной части.Вы написали:

При выборе моего COM-сервера появляется Аргументы функции[1] диалоговое окно без информации об аргументах и без описания функции.

Могу ли я предоставить описание функции ?

Могу ли я предоставить описание параметров ?

Могу ли я указать название категории для своих функций, чтобы я получал что-то лучшее, чем просто ProgID?

Самый простой подход здесь заключается в использовании Приложение.Макроопционы способ.Этот метод позволяет вам предоставить описание функции и указать, в какой категории вы хотите, чтобы она отображалась.К сожалению, этот подход не позволяет вам указывать какую-либо информацию для параметров функций, но методы, которые позволяют вам это сделать, очень сложны, к которым я вернусь позже. [Исправление:Метод 'Application.MacroOptions' работает только для UDF, созданных с помощью VBA, и не может использоваться для надстроек автоматизации.Читайте дальше о более сложных подходах к обработке регистрации содержимого UDFs в надстройках автоматизации - Майк Розенблюм 2009.10.20]

Обратите внимание, что файлы справки для Excel 2003 и файлы справки для Excel 2007 укажите, что строка может быть предоставлена в аргумент category, чтобы предоставить пользовательское имя категории по вашему выбору.Остерегайтесь, однако, что файлы справки для Excel 2002 не делай этого.Я не знаю, является ли это упущением в файлах справки Excel 2002, или это новая возможность, начиная с Excel 2003.Я предполагаю последнее, но вам придется проверить, чтобы быть уверенным.

Единственный способ получить информацию о ваших параметрах в мастере функций - использовать довольно сложную технику, включающую метод 'Excel.Application.ExecuteExcel4Macro'.Однако будьте осторожны:многие MVP Excel сталкивались с трудностями при таком подходе и не смогли добиться надежного результата.Однако совсем недавно, похоже, Ян Карел Питерсе (JKP) разобрался с этим и опубликовал подробности здесь: Регистрация пользовательской функции в Excel.

Просмотрев эту статью, вы увидите, что она не для слабонервных.Частично проблема в том, что он написал это для VBA / VB 6.0, и поэтому весь этот код пришлось бы перевести на VB.NET или C #.Ключевой командой, однако, является метод 'Excel.Application.ExecuteExcel4Macro', который доступен для .NET, поэтому все должно работать нормально.

Однако с практической точки зрения я предпочитаю использовать подход "Excel.Application.MacroOptions", потому что он прост и надежен.Он не предоставляет информацию о параметрах, но у меня пока не было сильной потребности мотивировать меня использовать подход 'ExecuteExcel4Macro'.

Итак, удачи вам с этим, но мой совет был бы использовать "Макроопции", если только вам не платят почасово.;-)

-- Майк

Продолжение ответов Хью

Я попробовал вызвать Приложение.Макроопции в подразделе New().

Нет Sub New() Полу-приемлемого:Функция указана в категории ProgID.

Общий Sub New() Не приемлем:ошибка времени сборки.Не удается зарегистрировать сборку "...\Foo.dll ".Исключение было вызвано целью вызова.

Sub New() Не приемлемо:категория отсутствует в списке в диалоговом окне Вставки функции.Я подозреваю, что это проблема как для макроопционов, так и для более сложных маршрут, рекомендованный Чарльзом.

Вы не можете использовать общие (они же "статические") классы или конструкторы при предоставлении своих классов COM, потому что COM не знает об этой концепции и поэтому не может компилироваться - как вы выяснили!Возможно, вы сможете применить 'ComVisibleAttribute' со значением 'False' к общему конструктору, чтобы, по крайней мере, разрешить ему компилироваться.Но это все равно не помогло бы вам в данном случае...

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

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

(1) Если вы помещаете свой регистрационный код в конструктор для вашего класса, то, по определению, информация о вашем мастере функций не может существовать до тех пор, пока функция не будет вызвана в первый раз.

(2) Ваш конструктор может выполняться, когда Excel не готов принимать команды автоматизации.Например, надстройка автоматизации обычно загружается по запросу, когда пользователь начинает вводить имя одной из пользовательских функций (UDFS), определенных в надстройке автоматизации.В результате ячейка находится в режиме редактирования при первой загрузке вашей надстройки автоматизации.Если у вас есть код автоматизации в вашем конструкторе в режиме редактирования, многие команды завершатся ошибкой.Я не знаю, является ли 'Excel.Приложение.Макроопции' или 'Excel.Приложение.У методов Excel4Macro есть проблема с этим, но многие команды будут прерываться при попытке выполнить, пока ячейка находится в режиме редактирования.И если надстройка автоматизации загружается в первый раз, потому что она вызывается во время работы Мастера функций, я понятия не имею, могут ли эти методы работать правильно.

Для этого нет простого решения, если вы хотите, чтобы ваша надстройка автоматизации была полностью автономной, без какой-либо другой поддержки.Однако вы можете создать управляемую COM-надстройку, которая зарегистрирует вашу автоматизированную надстройку для вас через "Excel.Приложение.Макроопции" или "Excel.Приложение.Подход Excel4Macro при запуске Excel.Класс управляемой COM-надстройки может находиться в той же сборке, что и ваша надстройка автоматизации, поэтому вам по-прежнему нужна только одна сборка.

Кстати, вы могли бы даже использовать рабочую книгу VBA или надстройку .XLA, чтобы сделать то же самое - используйте рабочую книгу.Откройте событие в VBA для вызова регистрационного кода.Вам просто нужно что - то для вызова вашего регистрационного кода при запуске Excel.Преимущество использования VBA в этом случае заключается в том, что вы могли бы использовать код из книги Яна Карела Питерса Регистрация пользовательской функции в Excel статья как есть, без необходимости переводить ее в .NET.

С другой стороны, Майк рекомендации для создания интерфейса для осуществления же убить раздражает дополнительными методами, которые были выставлены.

лол, я рад, что что-то сработало!

Эта статья Microsoft от начала 2007 года (по ссылке Майка) кажется довольно полным ответом по теме:

Надстройки автоматизации и функции Мастер

Каждая надстройка автоматизации имеет свою собственную категорию в мастере функций Excel.Название категории является идентификатором программы для надстройки;вы не можете указать другое название категории для автоматизации Функции надстройки.Кроме того, невозможно указать функцию описания, описания аргументов или справку по надстройке автоматизации функции в мастере функций.

Это ограничение относится только к подходу "Excel.Application.MacroOptions".(Мои извинения, я забыл об этом ограничении метода 'Excel.Application.MacroOptions' в отношении надстроек автоматизации, когда я писал свой первоначальный ответ выше.) Более сложный "Excel.Приложение.Однако подход ExecuteExcel4Macro абсолютно работает для надстроек автоматизации.Это также должно работать и для надстроек автоматизации .NET ("управляемых"), поскольку Excel понятия не имеет, загружает ли он надстройку автоматизации COM, созданную с помощью VB 6.0 / C ++, или управляемую надстройку автоматизации COM, созданную с помощью VB.NET/C #.Механика точно такая же со стороны COM, потому что Excel понятия не имеет, что такое .NET или это .NET даже существует.

Тем не менее, подход 'Excel.Application.Excel4Macro' определенно потребовал бы много работы...

Другие советы

Вы могли бы либо использовать одну из .Системы Net Excel, такие как ExcelDNA или ADDIN Express, либо попытаться адаптировать одно из решений VBA / VB6:посмотрите на FunCustomise Лорана Лонгре http://xcell05.free.fr/english/index.html или статья Яна Карела Питерса в http://www.jkp-ads.com/Articles/RegisterUDF00.asp который использует функцию, перегружающую hack.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top