Domanda

La descrizione

Sto scrivendo un paio di Excel UDF nel server COM. Mi piacerebbe ottenere l'aiuto standard ( Inserisci funzione finestra di dialogo), che si ottiene quando si preme fx . Sì, posso vedere il mio server COM elencato nella Categoria fra discesa, ma

  • Vedo anche Eguali, GetHashCode, GetType, e ToString (che sono piuttosto indesiderabili per esporre per l'utente di Excel),
  • selezionando il mio server COM porta in primo piano gli argomenti * Funzione * [1] finestra di dialogo con nessuna informazione e nessun argomento descrizione della funzione.

Questa è la zoppia che ottengo:

dialogo Inserisci funzione http://www.iwebthereforeiam.com/files/ Inserire% 20function% 20dialog.gif

di dialogo Argomenti funzione di Excel http://www.iwebthereforeiam.com/files /Function%20Arguments%20dialog.gif

La domanda

Ci sono .NET attributi ho potuto mettere sui metodi di passare attraverso questo in Excel?

  • Posso fornire una descrizione della funzione?
  • Posso fornire una descrizione dei parametri?
  • Posso fornire un nome di categoria per le mie funzioni, in modo che ho qualcosa di meglio che il ProgID?

(vedo che sembra purtroppo facile da fare in ExcelDNA, ma non ho intenzione quell'itinerario. Emulando il codice di Govert [attributi personalizzati, un caricatore di qualche tipo, ecc] sembra che sarebbe stato piuttosto difficile.)


sfondo aggiuntive

Se non è stato fatto funzionare con i server di Excel + COM prima, qui ci sono alcune risorse utili per arrivare fino alla velocità:

precedenti domande StackOverflow:
Come arrivare server COM per Excel scritto in VB.NET installato e registrato nella lista dei server di automazione?
Come Aggiungere un COM Progetto NET -Exposed al VB6 (o VBA) Riferimenti Dialog?

Altre risorse:
Scrittura di funzioni definite dall'utente per Excel in .NET < br> Creare e distribuire un NET COM Assembly
scrittura personalizzato Funzioni foglio di lavoro Excel in C #


Modifica 2009-10-20 14:10

Ho provato chiamando Application.MacroOptions in un Sub New().

  1. Nessun Sub New ()
    Semi-accettabili:. Funzione è elencato nella categoria ProgID
  2. Shared Sub New ()
    Non accettabile:. Errore di generazione in tempo
    Cannot register assembly "...\Foo.dll".
    Exception has been thrown by the target of an invocation.
  3. Sub New ()
    Non accettabile:. Categoria non è elencato nella finestra di dialogo Inserisci funzione

Ho il sospetto che questo è un problema sia per MacroOptions e per il percorso più coinvolti consigliato da Charles.


Modifica 2009-10-20 14:55

Sul lato positivo, la raccomandazione di Mike per creare un'interfaccia per implementare ha uccidere i metodi in più fastidiosi che sono stati esposti.


Modifica 2009-10-20 15:00

Questo Microsoft articolo da inizio 2007 (tramite link di Mike) sembra una risposta piuttosto completa sul tema:

  

Automazione componenti aggiuntivi e la funzione   Wizard

     

Ogni componente aggiuntivo di automazione ha il suo   categoria nella Creazione guidata Funzione Excel.   Il nome della categoria è il ProgID per   l'Add-in; Non è possibile specificare un   diverso nome della categoria per l'automazione   Add-in funzioni. Inoltre, ci   c'è modo di specificare la funzione   le descrizioni, le descrizioni degli argomenti,   o aiuto per componente aggiuntivo di automazione   funzioni nella Creazione guidata funzione.


1 Eh, un bug StackOverflow. Sembra che non si può in corsivo una stringa all'interno di un esplicito HTML ul-list?

È stato utile?

Soluzione

Alcune di queste è facile da correggere, altre parti di esso è piuttosto difficile. Tutto è fattibile, però, se si è disposti a mettere il tempo.

Hai scritto:

  

Vedo anche Equals, GetHashCode,   GetType e ToString (che sono   abbastanza indesiderabile esporre al   utente di Excel)

Sì, d'accordo, questo sicuramente auspicabile, ma può essere prevenuta. Questo si verifica perché la classe eredita da 'System.Object', come tutte le classi .NET fanno, e l'interfaccia di default che è esposto a COM è compreso questi membri. Ciò si verifica, ad esempio, se si utilizza il 'ClassInterfaceAttribute', utilizzando l'impostazione 'ClassInterfaceType.AutoDual'.

es. in C #:

[ClassInterface(ClassInterfaceType.AutoDual)]

In VB.NET:

<ClassInterface(ClassInterfaceType.AutoDual)>

L'uso di 'ClassInterfaceType.AutoDual' dovrebbe essere evitato, tuttavia, al fine di evitare che i membri ereditati da 'System.Object' di essere esposti (così come per prevenire potenziali problemi delle versioni in futuro). Invece, definire la propria interfaccia, implementare l'interfaccia nella classe, e quindi contrassegnare la classe con l'attributo 'ClassInterface' con un valore di 'ClassInterfaceType.None'.

per esempio, utilizzando 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;
    }
}

Utilizzo 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

Facendo uso del 'ClassInterfaceAtribute' con un valore di 'ClassInterfaceType.None', i membri in chat ereditati 'System.Object' sono esclusi, perché l'interfaccia della classe non è fatta COM-visibile. Al contrario, solo l'interfaccia implementata ( 'IClassName' in questo esempio) viene esportato in COM.

È possibile che questo è anche avvalendosi del 'ComDefaultInterfaceAttribute'. Questo non è molto importante, e non fa nulla se si implementa una sola interfaccia - come in questo esempio -. Ma è una buona idea nel caso in cui si aggiunge un'interfaccia più tardi, come ad esempio IDTExtensibility2

Per maggiori dettagli su questo, si veda:

(1) Managed componente aggiuntivo di automazione -ins da Andrew Whitechapel.

(2) Writing personalizzato foglio di lavoro Excel Funzioni in C # di Gabhan Berry.

Ok, ora per la parte più difficile. Hai scritto:

  

La selezione mio server COM porta in primo piano la    Argomenti funzione [1] finestra di dialogo con nessuna informazione e nessun argomento   descrizione della funzione.

     

Posso fornire una descrizione del   Funzione?

     

Posso fornire una descrizione del   parametri?

     

Posso fornire un nome per la mia categoria   funzioni, in modo che io ottenere qualcosa   meglio che solo il ProgID?

L'approccio più semplice è quello di utilizzare il Application.MacroOptions metodo. Questo metodo consente di fornire una descrizione della funzione e specificare quale categoria in cui si desidera che venga visualizzato. Questo approccio non consente di specificare tutte le informazioni per i parametri delle funzioni, purtroppo, ma le tecniche che consentono di farlo sono molto complicati, che ne parlerò più tardi. [Correzione: Il metodo 'Application.MacroOptions' funziona solo per i UDF create tramite VBA e non può essere utilizzato per l'automazione componenti aggiuntivi. Continua a leggere per approcci più complessi per gestire la registrazione dei UDF containe in un'automazione componenti aggiuntivi - Mike Rosenblum 2009.10.20]

Si noti che il file di aiuto per Excel 2003 di aiuto per Excel 2007 stato che una stringa può essere fornito a> e l'argomento categoria, al fine di fornire un nome categoria personalizzata di vostra scelta. Attenzione, però, che il file di aiuto per Excel 2002 non lo fanno. Non so se questa è una lacuna nel file di aiuto di Excel 2002, o se si tratta di una nuova funzionalità, come di Excel 2003. Sto cercando di indovinare il secondo, ma si dovrebbe verificare per essere sicuri.

L'unico modo per ottenere le informazioni di parametro nella Creazione guidata funzione è quella di utilizzare una tecnica piuttosto complessa che coinvolge il metodo 'Excel.Application.ExecuteExcel4Macro'. Attenzione però: molti MVP Excel hanno lottato con questo approccio e non è riuscito a produrre un risultato che sia affidabile. Più di recente, però, sembra che Jan Karel Pieterse (JKP) ha ottenuto ha funzionato e ha pubblicato i dettagli qui: Registrazione di una funzione definita dall'utente con Excel .

Skimming tale articolo vedrai che non è per i deboli di cuore. Parte del problema è che lui ha scritto per VBA / VB 6.0 e così tutto ciò che il codice dovrebbe essere tradotto in VB.NET e C #. Il comando chiave, tuttavia, è il metodo 'Excel.Application.ExecuteExcel4Macro', che è esposto a .NET, quindi tutto dovrebbe funzionare bene.

In pratica, però, ho enormemente preferiscono utilizzando l'approccio 'Excel.Application.MacroOptions' perché è semplice e affidabile. Non fornisce informazioni sui parametri, ma non ho ancora avuto un forte bisogno di motivare me prendere sull'approccio 'ExecuteExcel4Macro'.

Quindi, buona fortuna con questo, ma il mio consiglio sarebbe quello di utilizzare le 'MacroOptions', a meno che non vengono pagati a ore. ; -)

- Mike

Follow-up alle risposte di Hugh

  

Ho provato chiamando   Application.MacroOptions in un Comparto   New ().

     

No Sub New () Semi-accettabili: Funzione   è elencato nella categoria ProgID.

     

Shared Sub New () Non accettabile:   costruire Errore. Non è possibile registrare   montaggio "... \ Foo.dll". eccezione ha   stata generata dalla destinazione di una   invocazione.

     

Sub New () Non accettabile: categoria è   non elencati nella finestra di dialogo Inserisci funzione.   Ho il sospetto che questo è un problema sia per   MacroOptions e per la più coinvolti   itinerario consigliato da Charles.

Non si può ad uso comune (alias "statici") classi o costruttori quando esporre le classi di COM perché COM non è a conoscenza di questo concetto e quindi non possono compilare - come hai scoperto! Potreste essere in grado di applicare un 'ComVisibleAttribute' con un valore di 'False' al costruttore condiviso, almeno a permettergli di compilazione. Ma questo non aiuterebbe in questo caso comunque ...

Il tentativo di registrare il componente aggiuntivo di automazione tramite il componente aggiuntivo di automazione di per sé potrebbe rivelarsi difficile. Mi rendo conto che questo è auspicabile al fine di tenerlo come un singolo componente, stand-alone, ma potrebbe non essere possibile. O almeno questo non sarà facile.

Il problema è che l'automazione componenti aggiuntivi sono caricati domanda. Cioè, in realtà non sono lì fino a quando Excel tenta di accedere alla prima funzione del foglio di lavoro dal proprio componente aggiuntivo di automazione. Ci sono due questioni legate a questo:

(1) Se si mette il codice di registrazione all'interno del costruttore per la classe, quindi, per definizione, le informazioni di funzione guidata non può esistere fino a quando la funzione è stata chiamata per la prima volta.

(2) Il suo costruttore potrebbe essere in esecuzione quando Excel non è pronto ad accettare i comandi di automazione. Ad esempio, un componente aggiuntivo di automazione è tipicamente caricati su richiesta quando l'utente inizia a digitare il nome di una delle funzioni definite dall'utente (UDF) definite nel automazione aggiuntivo. Il risultato è che la cellula è in edit-mode quando il componente aggiuntivo di automazione primi carichi. Se si dispone di codice di automazione all'interno del vostro costruttore durante la modalità di modifica, molti comandi non riuscirà. Non so se i 'Excel.Application.MacroOptions' o metodi 'Excel.Application.Excel4Macro' hanno un problema con questo, ma molti commands saranno soffocare quando si cerca di eseguire mentre la cella è in modalità di modifica. E se il componente aggiuntivo di automazione viene caricata per la prima volta perché viene chiamato mentre la Creazione guidata funzione è aperto, non ho idea se questi metodi possono funzionare a destra.

Non esiste una soluzione facile a questo, se si desidera avere il tuo componente aggiuntivo di automazione per essere completamente stand-alone senza alcun altro supporto. È possibile, tuttavia, creare un gestita componente aggiuntivo COM che registrare il componente aggiuntivo di automazione per voi via 'Excel.Application.MacroOptions' o l'approccio della 'Excel.Application.Excel4Macro' quando Excel si avvia. Il gestito COM aggiuntivo in classe può essere nello stesso assembly come quella del tuo componente aggiuntivo di automazione, quindi è ancora solo bisogno di un assieme.

A proposito, si potrebbe anche utilizzare una cartella di lavoro VBA o .XLA aggiuntivo a fare lo stesso - utilizzare l'evento Workbook.Open in VBA per chiamare il codice di registrazione. Hai solo bisogno di qualcosa per chiamare il codice di registrazione quando Excel si avvia. Il vantaggio di utilizzare VBA in questo caso è che si potrebbe utilizzare il codice Registrazione una funzione definita dall'utente con l'articolo Excel così come sono, senza la necessità di tradurre in .NET.

  

Sul lato positivo, Mike   raccomandazione di creare un'interfaccia   per implementare ha uccidere il fastidioso   metodi aggiuntivi che sono stati esposti.

lol, io sono contento qualcosa ha funzionato!

  

In questo articolo Microsoft dai primi mesi del 2007   (Tramite collegamento di Mike) sembra piuttosto   risposta completa sul tema:

     

Automazione componenti aggiuntivi e la funzione   Wizard

     

Ogni Add-in Automation ha il suo   categoria nella Creazione guidata Funzione Excel.   Il nome della categoria è il ProgID per   l'Add-in; Non è possibile specificare un   diverso nome della categoria per l'automazione   Add-in funzioni. Inoltre, ci   c'è modo di specificare la funzione   le descrizioni, le descrizioni degli argomenti,   o aiuto per componente aggiuntivo di automazione   funzioni nella Creazione guidata funzione.

Questa è una limitazione per solo l'approccio 'Excel.Application.MacroOptions'. (Le mie scuse, mi ero dimenticato su questa limitazione del metodo 'Excel.Application.MacroOptions' rispetto alla automazione componenti aggiuntivi quando ho scritto la mia risposta originale, sopra.) Quanto più complesso 'Excel.Application. approccio ExecuteExcel4Macro ', tuttavia, assolutamente non funziona per l'automazione componenti aggiuntivi. Dovrebbe funzionare anche per .NET ( "gestito") Automazione componenti aggiuntivi così, perché Excel non ha idea se si sta caricando un'automazione COM aggiuntivo creato tramite VB 6.0 / C ++ rispetto ad una gestione di automazione COM aggiuntivo creata usando VB.NET/C#. I meccanici sono esattamente gli stessi dal lato COM della recinzione perché Excel non ha idea di quello che .NET è, o che quello .NET persino esiste.

Detto questo, l'approccio 'Excel.Application.Excel4Macro' sarebbe sicuramente un sacco di lavoro ...

Altri suggerimenti

Si potrebbe usare sia uno dei sistemi .Net Excel quali ExcelDNA o ADDIN Express o cercare di adattare una delle soluzioni VBA / VB6: guardare FunCustomise di Laurent Longre http://xcell05.free.fr/english/index.html o un articolo di Jan Karel Pieterse a http://www.jkp-ads.com/Articles/ RegisterUDF00.asp che utilizza un hack sovraccarico di funzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top