2009-06-05 20 views
16

Quello che sto cercando di fare è creare UDF (User Defined Functions) per Excel usando il tipo di progetto CTO "Excel 2007 Add-in" di VSTO (dato che ho appena vuoi generare alcune UDF generali). Come sto solo cercando di imparare le basi (in questa fase comunque) questo è ciò che il mio codice è simile:Come creare facilmente un UDF di Excel con il progetto del componente aggiuntivo VSTO

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

Si compila bene, e quando l'eseguo, Excel si apre con un foglio di calcolo fresca, e quando Guardo la lista dei "Componenti aggiuntivi" (nelle opzioni di Excel) Posso vedere il mio componente aggiuntivo nell'elenco (che è impostato su "Carica all'avvio"). Ma ecco che arriva il mio problema, quando provo a chiamare la mia UDF da dentro con Excel, Excel non riesce a trovare il metodo!

Quello che immagino sia sbagliato, è che devo taggare il mio metodo come UDF di Excel (usando le parentesi quadre - come ad esempio fatto quando si codificano i webservices -> "[WebService]"). Ma non sono stato in grado di rintracciare questo tag (e dato che non ne sono affatto sicuro se la mia impressione è corretta), ed è per questo che ho deciso di andare da voi brave persone qui a SO.

Quindi la mia domanda è fondamentalmente - da dove sono con il mio codice c'è un modo semplice per rendere accessibile la mia UDF in Excel? Se sì, come?

Vorrei davvero rimanere all'interno dei tipi di progetto VSTO (componente aggiuntivo, cartella di lavoro, modello), poiché il mio obiettivo generale per il mio progetto corrente è stabilire se l'esecuzione C# UDF con VS2010/Excel2007 funziona in un velocità accettabile Per testare questo sto lavorando su Windows7RC e con il VS1010 beta1.

risposta

8

Per quanto ne so, non è possibile creare UDF direttamente in VSTO.

Vedere l'articolo How to create Excel UDFs in VSTO managed code di Paul Stubbs in cui utilizza un componente aggiuntivo VBA per esporre UDF VBA, che a sua volta chiamano le sue UDF gestite scritte in VSTO.

È possibile utilizzare il codice gestito per creare UDF, tuttavia, quando non si utilizza VSTO. Vedere l'articolo di Eric Carter Writing user defined functions for Excel in .NET su come farlo.

Per quanto riguarda la velocità di esecuzione di VSTO, penso che lo troverete perfetto per quasi tutte le attività. Il looping delle celle, tuttavia, che è già il punto debole di Excel, potrebbe essere dolorosamente lento, a seconda di cosa stai facendo. Cerca di eseguire le cose in batch, il più possibile. Ad esempio, anziché eseguire il looping delle celle una per una, restituire una matrice bidimensionale di valori da un'area, elaborare la matrice e quindi riportarla all'intervallo.

Per dimostrare, quanto segue restituirà una matrice bidimensionale di valori da una zona, processo i valori, e poi passare la matrice risultante di nuovo alla zona originale in un solo colpo:

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

Spero che questo aiuti !

Mike

19

VSTO non ha il supporto per la creazione di Excel UDF. I componenti aggiuntivi di automazione possono essere creati in. Net e sembrano essere il modo approvato da Microsoft per farlo.

Si dovrebbe dare un'occhiata a ExcelDna - http://www.codeplex.com/exceldna. ExcelDna consente agli assembly gestiti di esporre le funzioni definite dall'utente (UDF) e le macro in Excel tramite l'interfaccia nativa .xll. Il progetto è open source e consente liberamente l'uso commerciale. E scoprirai che le prestazioni della tua UDF basata su .Net sono simili ai componenti aggiuntivi nativi .xll per Excel. Sono supportate funzionalità di Excel 2007 come il grande foglio, le lunghe stringhe Unicode e il ricalcolo multi-thread.

Con ExcelDna la funzione sopra indicata verrà esposta a Excel senza VSTO: è possibile inserire il codice in un file .dna basato su xml o compilarlo in un file .dll.

Il file .dna di esporre l'UDF sarebbe simile a questa:

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

Aggiornamento: In questi giorni, il modo più semplice per iniziare con Excel-DNA è quello di fare un nuovo progetto Libreria di classi in Visual Studio, quindi aggiungi il pacchetto "ExcelDna.AddIn" da NuGet. Questo fa un add-in di avviamento: basta incollare il codice e premere F5 per correre.

0

Quello che ho trovato che funziona bene è quello di mantenere l'UDF come modulo VB per evitare i problemi con oggetti COM.

Ho tonnellate di codice C# in esecuzione e quando sono pronti a costruire il rilascio faccio la seguente:
1. Aggiungere un modulo:
      Developer [scheda in Excel] | Visual Basic - Finestra> progetto, tasto destro del mouse, inserire il modulo
      - solo copia/incolla il codice VB qui
2. Includere la libreria di riferimento appropriato (Strumenti in stessa finestra VB)
3. Salvare l'Excel file come .xlsm (ovvero, Macro-Enabled)

È quindi possibile eliminare il file .xlsx.

Quello che faccio è comprimere l'intera directory (ad es. "Rilascio") e inviarla ai nostri utenti.

Problemi correlati