Question

La description

Je suis en train d'écrire quelques Excel dans les serveurs UDFs COM. Je voudrais obtenir l'aide standard ( Insérer une fonction boîte de dialogue) que vous obtenez lorsque vous appuyez sur fx . Oui, je peux voir mon serveur COM listé dans la catégorie parmi menu déroulant, mais

  • Je vois aussi, Equals GetHashCode, getType, et ToString (qui sont assez indésirables pour exposer à l'utilisateur Excel),
  • sélectionner mon serveur COM apporte les arguments * Fonction * dialogue [1] aucune information d'argument et aucune description de la fonction.

Voici la boiterie que je reçois:

Insérer dialogue Fonction http://www.iwebthereforeiam.com/files/ Insérer% 20function% 20dialog.gif

Excel Arguments de la fonction de dialogue http://www.iwebthereforeiam.com/files /Function%20Arguments%20dialog.gif

La question

Y at-il des attributs .NET je pourrais mettre sur les méthodes pour passer cela par Excel?

  • Puis-je fournir une description de la fonction?
  • Puis-je fournir une description des paramètres?
  • Puis-je donner un nom de catégorie pour mes fonctions, de sorte que je reçois quelque chose de mieux que juste le ProgID?

(je vois qu'il semble malheureusement facile à faire dans ExcelDNA, mais je ne vais pas cette route. Emulation code de govert [attributs personnalisés, un chargeur de quelque sorte, etc.] semble que ce serait assez difficile.)


fond supplémentaire

Si vous ne l'avez pas fait le travail avec Excel + COM serveurs avant, voici quelques ressources utiles pour se mettre à jour:

Questions précédentes stackoverflow:
Comment obtenir COM Server pour Excel écrit en VB.NET installé et enregistré dans la liste des serveurs d'automatisation
Comment ajouter un COM -Exposed projet .NET au VB6 (ou VBA) Références Boîte de dialogue

Autres ressources:
Ecriture de fonctions définies par l'utilisateur pour Excel dans .NET < br> construire et déployer un Assemblée .NET COM de
écriture personnalisée Fonctions de feuille de calcul Excel en C #


Modifier 2009-10-20 14:10

J'ai essayé d'appeler Application.MacroOptions dans un Sub New().

  1. Non Sub New ()
    Semi acceptable. Fonction apparaît dans la catégorie ProgID
  2. Shared Sub New ()
    Inacceptable. Erreur accumulation de temps
    Cannot register assembly "...\Foo.dll".
    Exception has been thrown by the target of an invocation.
  3. Sub New ()
    Inacceptable. Catégorie ne figure pas dans Insérer dialogue Fonction

Je soupçonne que c'est un problème à la fois pour MacroOptions et pour la route plus impliqué recommandé par Charles.


Modifier 2009-10-20 14:55

Du côté positif, la recommandation de Mike pour créer une interface pour mettre en œuvre ne tuer les méthodes supplémentaires ennuyeuses qui ont été exposés.


Modifier 2009-10-20 15:00

Cet article Microsoft à partir du début 2007 (via 1 Huh, un bug Stackoverflow. Il semble que vous ne pouvez pas une chaîne dans italiques explicite HTML ul-liste?

Était-ce utile?

La solution

Une partie de c'est facile à corriger, d'autres parties de celui-ci est assez difficile. Tout cela est faisable, cependant, si vous êtes prêt à mettre le temps.

Vous avez écrit:

  

Je vois aussi Equals, GetHashCode,   GetType et ToString (qui sont   assez indésirable d'exposer à la   utilisateur Excel)

Oui, d'accord, cela certainement indésirable, mais il peut être évité. Cela se produit parce que votre classe héritant de « System.Object », comme toutes les classes .NET font, et votre interface par défaut qui est exposé à COM est compris ces membres. Cela se produit, par exemple, si vous utilisez le « ClassInterfaceAttribute », en utilisant le paramètre « ClassInterfaceType.AutoDual ».

par exemple. en C #:

[ClassInterface(ClassInterfaceType.AutoDual)]

En VB.NET:

<ClassInterface(ClassInterfaceType.AutoDual)>

L'utilisation de « ClassInterfaceType.AutoDual » devrait être évité, cependant, afin d'éviter que les membres hérités du « System.Object » d'être exposé (ainsi que pour éviter les problèmes potentiels de versioning dans l'avenir). Au lieu de cela, définir votre propre interface, implémenter l'interface de votre classe, et puis marquez votre classe avec l'attribut « ClassInterface » avec une valeur de « ClassInterfaceType.None ».

par exemple, en utilisant 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;
    }
}

Utilisation 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

En utilisant la « ClassInterfaceAtribute » avec une valeur de « ClassInterfaceType.None », les « héritées System.Object » memebers sont exclus, car l'interface de la classe ne se fait pas COM visible. Au lieu de cela, seule l'interface implémentée (dans cet exemple 'iClassName') est exportée vers COM.

Ce qui précède est également faire usage de la « ComDefaultInterfaceAttribute ». Ce n'est pas très important, et ne fait rien si vous implémentez une seule interface - comme dans cet exemple -. Mais il est une bonne idée dans le cas où vous ajoutez une interface plus tard, comme IDTExtensibility2

Pour plus de détails à ce sujet, voir:

(1) Managed Ajouter Automatisation -ins par Andrew Whitechapel.

(2) Excel écriture personnalisée Fonctions de feuille de calcul en C # par Gabhan Berry.

Ok, maintenant à la partie la plus difficile. Vous avez écrit:

  

La sélection de mon serveur COM apporte la    Arguments de fonction [1] dialogue sans informations d'argument et non   Description de la fonction.

     

Puis-je fournir une description de la   fonction?

     

Puis-je fournir une description de la   paramètres?

     

Puis-je fournir un nom de catégorie pour mon   fonctions, de sorte que je reçois quelque chose   mieux que tout le ProgID?

L'approche la plus simple est ici d'utiliser le Application.MacroOptions . Cette méthode vous permet de fournir une description de la fonction et spécifier la catégorie dans laquelle vous voulez qu'il soit affiché. Cette approche ne permet pas de spécifier des informations pour les paramètres des fonctions, malheureusement, mais les techniques qui vous permettent de le faire sont très compliquées, que je vais plus tard. [Correction: La méthode « Application.MacroOptions » ne fonctionne que pour des FDU créés via VBA et ne peut pas être utilisé pour les compléments d'automatisation. Lire la suite pour des approches plus complexes pour gérer l'enregistrement des UDFs chario dans une automatisation des add-ins - Mike Rosenblum 2009.10.20]

Notez que le href="http://msdn.microsoft.com/en-us/library/aa195786(office.11).aspx" fichiers d'aide pour Excel 2003 et pour l'état d'Excel 2007 qu'une chaîne peut être fournie à l'argument de la catégorie afin de fournir un nom de catégorie personnalisée de votre choix. Attention toutefois, que le fichiers d'aide pour Excel 2002 ne le font pas. Je ne sais pas si cela est une omission dans les fichiers d'aide Excel 2002 ou si cela est une nouvelle fonctionnalité que d'Excel 2003. Je devine que ce dernier, mais vous devez tester pour être sûr.

La seule façon d'obtenir vos informations de paramètres dans l'Assistant fonction est d'utiliser une technique assez complexe impliquant la méthode « Excel.Application.ExecuteExcel4Macro ». Attention cependant: de nombreux MVPs Excel ont lutté avec cette approche et a échoué à produire un résultat fiable. Plus récemment, cependant, il semble que Jan Karel Pieterse (JKP) a obtenu ça a marché et a publié les détails ici: Enregistrement d'une fonction définie par l'utilisateur avec Excel .

En feuilletant cet article, vous verrez que ce n'est pas pour les faibles de cœur. Une partie du problème est qu'il a écrit pour VBA / VB 6.0 et donc tout ce que le code devrait être traduit en VB.NET ou C #. La commande clé, cependant, est la méthode « Excel.Application.ExecuteExcel4Macro », qui est exposé à .NET, donc tout devrait fonctionner correctement.

En pratique, cependant, je préfère largement utiliser l'approche « Excel.Application.MacroOptions » parce qu'il est simple et fiable. Il ne fournit pas les paramètres, mais je n'ai pas encore eu un fort besoin de me motiver à l'approche « ExecuteExcel4Macro ».

Alors, bonne chance, mais mon conseil serait d'utiliser les « MacroOptions », à moins que vous êtes payé à l'heure. ; -)

- Mike

Suivi des réponses de Hugh

  

J'ai essayé d'appeler   Application.MacroOptions dans un sous   Nouveau ().

     

n Sub New () semi-acceptable: Fonction   est listé dans la catégorie ProgID.

     

Shared Sub New () Non acceptable:   construire Erreur. Impossible d'enregistrer   assemblage "... \ Foo.dll". exception a   été levée par la cible d'un   invocation.

     

Sub New () Inacceptable: catégorie est   ne figure pas dans boîte de dialogue Insérer une fonction.   Je soupçonne que c'est un problème à la fois pour   MacroOptions et pour les plus impliqués   itinéraire recommandé par Charles.

Vous ne pouvez pas commun (alias « statiques ») des classes ou des constructeurs lors de l'exposition à vos classes COM car COM n'a pas connaissance de ce concept et il ne peut donc pas compiler - que vous avez trouvé! Vous pourriez être en mesure d'appliquer une « ComVisibleAttribute » avec une valeur de « Faux » au constructeur partagé, au moins permettre de compiler. Mais cela ne vous aidera pas dans ce cas, de toute façon ...

Essayer d'enregistrer votre macro complémentaire d'automation via l'automatisation elle-même complément pourrait se révéler délicate. Je me rends compte que cela est souhaitable afin de le garder comme un composant unique, autonome, mais il pourrait ne pas être possible. Ou du moins ce ne sera pas facile.

Le problème est que les compléments d'automatisation sont chargées a la demande. Autrement dit, ils ne sont pas vraiment là jusqu'à ce que Excel tente d'accéder à la première fonction de feuille de calcul de votre macro complémentaire d'automation. Il y a deux liés à cette questions:

(1) Si vous mettez votre code d'enregistrement dans le constructeur de votre classe, puis, par définition, les informations de l'assistant de fonction ne peut exister jusqu'à ce que la fonction a été appelée pour la première fois.

(2) Votre constructeur peut être en cours d'exécution lorsque Excel est pas prêt à accepter des commandes d'automatisation. Par exemple, une macro complémentaire d'automation est généralement chargée de la demande lorsque l'utilisateur commence à taper le nom de l'une des fonctions définies par l'utilisateur (FDU) définies dans l'automatisation add-in. Le résultat est que la cellule est en mode édition lorsque votre macro complémentaire d'automation premières charges. Si vous avez du code d'automatisation au sein de votre constructeur en mode d'édition, de nombreuses commandes échouera. Je ne sais pas si les méthodes « Excel.Application.MacroOptions » ou « Excel.Application.Excel4Macro » ont un problème avec cela, mais beaucoup commands étoufferont en essayant d'exécuter alors que la cellule est en mode édition. Et si le complément d'automatisation est chargée pour la première fois car il est appelé alors que l'Assistant Fonction est ouverte, je ne sais pas si ces méthodes peuvent travailler droit.

Il n'y a pas de solution facile à cela si vous souhaitez que votre macro complémentaire d'automation pour être complètement autonome sans autre soutien. Vous pouvez toutefois créer un complément qui enregistrera votre automatisation add-in pour COM géré vous par « Excel.Application.MacroOptions » ou l'approche « Excel.Application.Excel4Macro » lorsque Excel démarre. Le complément COM en classe peut être gérée dans le même ensemble que celui de votre macro complémentaire d'automation, de sorte que vous encore besoin d'un seul assemblage.

Par ailleurs, vous pouvez même utiliser un classeur VBA ou .XLA add-in pour faire la même chose - utiliser l'événement Workbook.Open en VBA pour appeler le code d'enregistrement. Vous avez juste besoin quelque chose pour appeler votre code d'enregistrement lorsque Excel démarre. L'avantage d'utiliser VBA dans ce cas est que vous pouvez utiliser le code de la Enregistrement une fonction utilisateur avec Excel article en l'état, sans avoir à traduire en .NET.

  

Du côté positif, Mike   recommandation de créer une interface   à mettre en œuvre ne tuer l'ennuyeux   méthodes supplémentaires qui ont été exposés.

lol, je suis heureux quelque chose a marché!

  

Cet article Microsoft à partir du début 2007   (Via un lien Mike) semble plutôt   réponse complète sur le sujet:

     

Automatisation et compléments de la fonction   Assistant

     

Chaque automatisation Add-in a sa propre   catégorie dans l'Assistant Fonction Excel.   Le nom de la catégorie est le ProgID pour   le Add-in; vous ne pouvez pas spécifier   autre nom de catégorie pour l'automatisation   Add-fonctions. En outre, il   est pas possible de préciser la fonction   descriptions, descriptions des arguments,   ou de l'aide pour l'automatisation Add-in   fonctions dans l'Assistant Fonction.

Ceci est une limitation de l'approche « Excel.Application.MacroOptions » seulement. (Mes excuses, j'avais oublié cette limitation de la méthode « Excel.Application.MacroOptions » par rapport à l'automatisation des compléments quand j'ai écrit ma première réponse, ci-dessus.) Le « Excel.Application plus complexe. approche ExecuteExcel4Macro, cependant, ne fonctionne absolument pour l'automatisation des add-ins. Il devrait également fonctionner pour .NET ( « géré ») automatisation des add-ins, parce que Excel n'a aucune idée si elle charge une automatisation COM add-in créé via VB 6.0 / C ++ par rapport à une automatisation COM géré complément créé à l'aide VB.NET/C#. Les mécaniciens sont exactement les mêmes du côté COM de la clôture parce que Excel n'a aucune idée de ce que .NET est, ou que .NET existe.

Cela dit, l'approche « Excel.Application.Excel4Macro » serait certainement beaucoup de travail ...

Autres conseils

Vous pouvez soit utiliser l'un des systèmes Excel .Net tels que ExcelDNA ou ADDIN Express, ou essayer d'adapter l'une des solutions VBA / VB6: regardez le FunCustomise de Laurent Longre http://xcell05.free.fr/english/index.html ou l'article de Jan Karel Pieterse http://www.jkp-ads.com/Articles/ RegisterUDF00.asp qui utilise un hack de surcharge de fonction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top