Как легко создать Excel UDF с Дополнительным проектом VSTO

Я не говорю, что что-то должно использоваться.

Это просто вопрос твоей привычки.

Некоторые рекомендации:

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

  • Используйте COMPILE_DEFINITIONS для тонкой настройки цели или конкретных источников.

20
задан Mark Byers 17 January 2013 в 10:50
поделиться

2 ответа

Насколько мне известно, вы не можете напрямую создавать UDF в VSTO.

См. Статью Пола Стаббса Как создать UDF Excel в управляемом коде VSTO , где он использует надстройку VBA для предоставления UDF VBA, которые, в свою очередь, вызывают его управляемые UDF, написанные на VSTO.

Однако вы можете использовать управляемый код для создания UDF, когда не используете VSTO. См. Статью Эрика Картера Написание пользовательских функций для Excel в .NET о том, как это сделать.

Что касается скорости выполнения VSTO, я думаю, вы найдете ее подходящей практически для всех задач. Однако переход по ячейкам, который уже является слабым местом Excel, может быть мучительно медленным, в зависимости от того, что вы делаете. Пытаться выполнять задачи в пакетном режиме, как можно больше. Например, вместо того, чтобы перебирать ячейки одну за другой, верните двумерный массив значений из области, обработайте массив и затем передайте его обратно в диапазон.

Чтобы продемонстрировать, следующее будет возвращать двумерный массив значений из области, обрабатывать значения, а затем передавать полученный массив обратно в исходную область одним выстрелом:

Excel.Range rng = myWorksheet.get_Range("A1:D4", Type.Missing);

//Get a 2D Array of values from the range in one shot:
object[,] myArray = (object[,])rng.get_Value(Type.Missing);

// Process 'myArray' however you want here.
// Note that the Array returned from Excel is base 1, not base 0.
// To be safe, use GetLowerBound() and GetUpperBound:
for (int row = myArray.GetLowerBound(0); row <= myArray.GetUpperBound(0); row++)
{
    for (int column = myArray.GetLowerBound(1); column <= myArray.GetUpperBound(1); column++)
    {
        if (myArray[row, column] is double)
        {
            myArray[row, column] = (double)myArray[row, column] * 2;
        }
    }
}

// Pass back the results in one shot:
rng.set_Value(Type.Missing, myArray);

Надеюсь, это поможет!

Майк

8
ответ дан 29 November 2019 в 23:57
поделиться

VSTO has no support for creating Excel UDFs. Automation Add-Ins can be created in .Net, and seem to be the Microsoft approved way of doing it.

You should have a look at ExcelDna - http://www.codeplex.com/exceldna. ExcelDna allows managed assemblies to expose user-defined functions (UDFs) and macros to Excel through the native .xll interface. The project is open-source and freely allows commercial use. And you'll find that the performance of your .Net-based UDF is similar to native .xll add-ins for Excel. Excel 2007 features like the large sheet, long Unicode strings and multi-threaded recalculation are supported.

With ExcelDna your function as posted above will be exposed to Excel with no VSTO - you can put to code into an xml-based .dna file or compile it to a .dll.

The .dna file exposing your UDF would look like this:

<DnaLibrary Language="C#">
   using System;
   using ExcelDna.Integration;

   public class MyFunctions
   {
      [ExcelFunction(Description="Calculate Stuff", Category="Cool Functions")]
      public static double HeronicCal(int a, int b, int c)
      {
         //first compute S = (a+b+c)/2
         double S = (a + b + c) / 2;
         double area = Math.Sqrt(S * (S - a) * (S - b) * (S - c));
         return area;        
      }
   }
</DnaLibrary>

Update: These days, the easiest way to get started with Excel-DNA is to make a new Class Library project in Visual Studio, then add the 'ExcelDna.AddIn' package from NuGet. That makes a starter add-in - just paste your code and press F5 to run.

21
ответ дан 29 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: