Excel 2007 UDF: come aggiungere descrizione della funzione, argomento di aiuto?
-
22-09-2019 - |
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
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()
.
- Nessun Sub New ()
Semi-accettabili:. Funzione è elencato nella categoria ProgID - Shared Sub New ()
Non accettabile:. Errore di generazione in tempoCannot register assembly "...\Foo.dll". Exception has been thrown by the target of an invocation.
- 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?
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.