Как передать прерывистый диапазон ячеек из Excel в функцию ExcelDNA

Рассмотрим такое определение функции ExcelDNA:

[ExcelFunction(Name = "Fnc1", Description = "Fnc1")]
public static object Fnc1(
    [ExcelArgument(Name = "Arg1", Description = "Arg1", AllowReference = true)]
    object rng)
{
    // ...
}
  • Он отлично работает при вызове с одной ячейкой, подобной этой =Fnc1(A1), или с непрерывным диапазоном ячеек, подобным этой =Fnc1(A1:A3).
  • Но это не работает при вызове с прерывистым диапазоном ячеек, например. =Fnc1(A1,A5,A10). Ошибка #VALUE! возвращается.

Есть ли способ вызвать функцию ExcelDNA с прерывистым диапазоном неизвестного количества ячеек?

Я попытался объявить такой параметр params object[] rng, но тоже не повезло.


person glick    schedule 05.02.2020    source источник


Ответы (2)


Чтобы иметь функцию Excel-DNA, которая позволяет передавать неизвестное количество аргументов во время выполнения, вам нужно использовать params object[] в аргументах функции.

public static class MyFunctions
{
    [ExcelFunction]
    public static object Hello(params object[] values)
    {
        return "Hello " + DateTime.Now;
    }
}

Тогда не имеет значения, вызываете ли вы его с жестко закодированными значениями, например. =Hello(10, 20) или если вы используете ссылки на ячейки, например. =Hello(A1,A5,A10).

Однако переменное количество аргументов не поддерживается Excel-DNA «из коробки», и поэтому вам придется использовать ExcelDna.Registration для регистрации ваших функций.

Установите пакет ExcelDna.Registration NuGet, затем в файле .dna отметьте свое добавление -в ссылке на сборку для использования ExplicitRegistration например:

<?xml version="1.0" encoding="utf-8"?>
<DnaLibrary Name="My Add-In" (...)>
  <ExternalLibrary Path="MyAddIn.dll" ExplicitRegistration="true" (...) />
</DnaLibrary>

Затем в вашем AutoOpen вы регистрируете функции с вызовом ProcessParamsRegistrations... например.

public class AddIn : IExcelAddIn
{
    public void AutoOpen()
    {
        ExcelRegistration
            .GetExcelFunctions()
            .ProcessParamsRegistrations()
            .RegisterFunctions();

        // ...
    }

    public void AutoClose()
    {
        // ...
    }
}

Неявная и явная регистрация функций

По умолчанию Excel-DNA ищет каждый метод public static в вашей сборке и регистрирует их как функции в Excel. Это неявный процесс регистрации.

ExplicitRegistration="true" отключает неявную регистрацию отключает, и, таким образом, ничего не регистрируется автоматически — вы должны сделать это самостоятельно — что я и делаю в AutoOpen выше с вызовом ... RegisterFunctions(). Если вы не отключите неявную регистрацию, функции будут зарегистрированы дважды (один раз неявным процессом, а затем вашим кодом) и вы получаете сообщения об ошибках

person C. Augusto Proiete    schedule 05.02.2020
comment
Да, это сработало, спасибо! В чем разница между неявной и явной регистрацией? Что еще неявная регистрация делает за кулисами? - person glick; 05.02.2020
comment
По умолчанию Excel-DNA ищет каждый метод public static в вашей сборке и регистрирует их как функции в Excel. Это неявный процесс регистрации. ExplicitRegistration="true" отключает неявную регистрацию, и, таким образом, ничего не будет регистрироваться автоматически — вы должны сделать это самостоятельно — что я и делаю в AutoOpen выше с вызовом ...RegisterFunctions(). Если вы не отключите неявную регистрацию, функции в конечном итоге будут зарегистрированы дважды (один раз процессом неявной, а затем еще раз вашим кодом), и вы получите сообщение об ошибке Сообщения. - person C. Augusto Proiete; 06.02.2020
comment
Я вижу, спасибо большое! Не могли бы вы добавить свой комментарий к ответу, пожалуйста? Мне кажется, это очень полезно! - person glick; 06.02.2020
comment
@barpa Добавлена ​​​​неявная и явная регистрация функций в ответ - person C. Augusto Proiete; 06.02.2020

Другие ответы полезны, если вы хотите разрешить несколько параметров и, возможно, их проще всего использовать конечному пользователю. Но вы также можете передать прерывистые диапазоны непосредственно в один параметр AllowReference=true, с которого вы начинаете, добавив круглые скобки в формулу:

=Fnc1((A1,A5,A10:A12))

У одного ExcelReference, который вы получите, будет несколько InnerReferences для непересекающихся частей.

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

person Govert    schedule 07.02.2020
comment
Спасибо за Ваш ответ! Да, я уже нашел и протестировал решение со скобками. Это сработало, но никто, вероятно, не узнает, почему прекращенные ячейки/диапазоны не работают, и никто не будет использовать круглые скобки. Так что решение с params object[] в данном случае для меня предпочтительнее. - person glick; 07.02.2020