web-dev-qa-db-ja.com

VSTOアドインプロジェクトを使用してExcelUDFを簡単に作成する方法

私がやろうとしているのは、VSTOのC#「Excel2007アドイン」プロジェクトタイプを使用してExcel用のユーザー定義関数(UDF)を作成することです(いくつかの一般的なUDFを生成したいだけなので)。私は(とにかくこの段階で)基本を学ぼうとしているだけなので、これは私のコードがどのように見えるかです:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;
using Microsoft.Office.Tools.Excel.Extensions;
using System.Runtime.InteropServices;

namespace ExcelAddIn1
{
    public partial class ThisAddIn
    {
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {}

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {}

        //My UDF
        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;
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }            
        #endregion
    }
}

正常にコンパイルされ、実行すると、Excelが新しいスプレッドシートでポップアップ表示され、「アドイン」リスト(Excelオプション内)を見ると、リスト(設定されている)に自分のアドインが表示されます。 「起動時にロード」に)。しかし、ここで問題が発生します。Excel内からUDFを呼び出そうとすると、Excelがメソッドを見つけることができません。

私が間違っていると思うのは、メソッドにExcel UDFのタグを付ける必要があるということです(たとえば、Webサービスのコーディング時に行われるように角かっこを使用->「[WebService]」)。しかし、私はこのタグを追跡することができませんでした(そして、私の予感が正しいかどうかまったくわからないので)、それが私がここSOであなたに素晴らしい人々に行くことに決めた理由です。

だから私の質問は基本的にです-私が私のコードを持っているところから、私のUDFをExcelにアクセスできるようにする簡単な方法はありますか?はいの場合、どのように?

現在のプロジェクトの全体的な目標は、VS2010/Excel2007でのC#UDFの実行が許容可能な速度で機能するかどうかを確認することなので、VSTOプロジェクトタイプ(アドイン、ワークブック、テンプレート)内にとどまりたいと思っています。これをテストするために、私はWindows7RCとVS2010beta1で作業しています。

21
user118193

VSTOは、ExcelUDFの作成をサポートしていません。自動化アドインは.Netで作成でき、Microsoftが承認した方法のようです。

ExcelDnaをご覧ください- http://www.codeplex.com/exceldna 。 ExcelDnaを使用すると、マネージアセンブリは、ネイティブの.xllインターフェイスを介してユーザー定義関数(UDF)とマクロをExcelに公開できます。このプロジェクトはオープンソースであり、自由に商用利用できます。また、.NetベースのUDFのパフォーマンスは、Excel用のネイティブ.xllアドインと同様であることがわかります。大きなシート、長いUnicode文字列、マルチスレッド再計算などのExcel2007機能がサポートされています。

ExcelDnaを使用すると、上記の関数はVSTOなしでExcelに公開されます。コードをxmlベースの.dnaファイルに入れたり、.dllにコンパイルしたりできます。

UDFを公開する.dnaファイルは次のようになります。

<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>

更新:最近、Excel-DNAを使い始める最も簡単な方法は、Visual Studioで新しいクラスライブラリプロジェクトを作成してから、 'ExcelDnaを追加することです。 NuGetの.AddIn 'パッケージ。これにより、スターターアドインが作成されます。コードを貼り付け、F5キーを押して実行するだけです。

21
Govert

エリックカーターがここで勝者を持っているように見えます:

http://blogs.msdn.com/b/eric_carter/archive/2004/12/01/273127.aspx

これは純粋な.NETであり、サードパーティのライブラリに依存しません。

今それをこぶを与える...

11
harvest316

私の知る限り、VSTOでUDFを直接作成することはできません。

Paul Stubbsの記事 VSTOマネージコードでExcel UDFを作成する方法 を参照してください。ここでは、VBAアドインを使用してVBA UDFを公開し、VSTOで記述されたマネージドUDFを呼び出します。

ただし、VSTOを使用していない場合は、マネージコードを使用してUDFを作成できます。これを行う方法については、Eric Carterの記事 。NETでのExcel用のユーザー定義関数の記述 を参照してください。

VSTOの実行速度については、ほぼすべてのタスクで問題ないと思います。ただし、すでにExcelの弱点であるセルのループは、実行内容によっては非常に遅くなる可能性があります。可能な限り、バッチで実行するようにしてください。たとえば、セルを1つずつループする代わりに、領域から値の2次元配列を返し、配列を処理してから、範囲に戻します。

例として、以下は、領域から値の2次元配列を返し、値を処理してから、結果の配列を1回のショットで元の領域に戻します。

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
Mike Rosenblum

私がうまく機能しているのは、COMオブジェクトの問題を回避するためにUDFをVBモジュールとして保持することです。

大量のC#コードを実行していて、リリースをビルドする準備ができたら、次のようにします。
1。モジュールを追加します。
開発者[Excelのタブ] | Visual Basic->プロジェクトウィンドウ、右クリック、モジュールの挿入
-VBコードをここにコピーして貼り付けるだけ
2。適切な参照ライブラリを含めます(同じVBウィンドウ内のツール)
3。 Excelファイルを.xlsmとして保存します(つまり、マクロが有効)

その後、.xlsxファイルを削除できます。

私がしていることは、ディレクトリ全体を圧縮して(たとえば、「リリース」)、ユーザーに送信することです。

0
Gary Huckabone