Excel 2007 UDF: كيفية إضافة وصف الوظيفة ، مساعدة الوسيطة؟

StackOverflow https://stackoverflow.com/questions/1592440

  •  22-09-2019
  •  | 
  •  

سؤال

الوصف

أنا أكتب اثنين من excel udfs في خوادم com. أود الحصول على مساعدة قياسية (أدخل وظيفة مربع الحوار) التي تحصل عليها عند الضغط FX. نعم ، يمكنني رؤية خادم com الخاص بي المدرج في الفئة المنسدلة ، ولكن

  • أرى أيضًا متساويًا ، gethashcode ، gettype ، و toString (والتي لا تترافق إلى حد ما لفضح مستخدم Excel) ،
  • يحدد تحديد خادم COM الخاص بي حوار وسيطات *الوظيفة *[1] بدون معلومات الوسيطة ولا وصف للوظيفة.

إليكم العرج الذي أحصل عليه:

إدراج دالة الحوار http://www.iwebthereiam.com/files/insert٪20function٪20Dialog.gif

حوار وسيطات دالة excel http://www.iwebthereiam.com/files/function٪20Arguments٪20Dialog.gif

السؤال

هل هناك سمات .NET يمكنني وضعها على طرق تمرير هذا الأمر إلى Excel؟

  • هل يمكنني تقديم وصف للوظيفة؟
  • هل يمكنني تقديم وصف للمعلمات؟
  • هل يمكنني تقديم اسم فئة لوظائفي ، بحيث أحصل على شيء أفضل من مجرد progid؟

(أرى أنه يبدو من السهل للأسف القيام به في exceldna ، لكنني لا أسير في هذا الطريق. يبدو أن رمز Govert [سمات مخصصة ، محمل من نوع ما ، وما إلى ذلك] يبدو أنه سيكون صعبًا للغاية.)


خلفية إضافية

إذا لم تكن قد انتهيت من العمل مع خوادم Excel + com من قبل ، فإليك بعض الموارد المفيدة للوصول إلى السرعة:

أسئلة Stackoverflow السابقة:
كيفية الحصول على COM Server لـ Excel المكتوب في قائمة VB.NET مثبتة وتسجيل في قائمة خوادم الأتمتة؟
كيف إضافة مشروع .NET معرض COM إلى مرجع مراجع VB6 (أو VBA)؟

مصادر أخرى:
كتابة الوظائف المحددة للمستخدم لـ Excel في .NET
بناء ونشر مجموعة .NET COM
كتابة وظائف ورقة عمل Excel المخصصة في C#


تحرير 2009-10-20 14:10

حاولت الاتصال Application.MacroOptions في Sub New().

  1. لا يوجد جديد ()
    شبه مقبول: يتم سرد الوظيفة ضمن فئة ProgID.
  2. مشترك جديد () جديد ()
    غير مقبول: خطأ في وقت البناء.
    Cannot register assembly "...\Foo.dll".
    Exception has been thrown by the target of an invocation.
  3. Sub New ()
    غير مقبول: فئة غير مدرجة في مربع الحوار INSERT Function.

أظن أن هذه مشكلة بالنسبة للعبارات المائية والطريق الأكثر مشاركة الذي أوصى به تشارلز.


تحرير 2009-10-20 14:55

على الجانب الإيجابي ، توصية مايك بإنشاء واجهة لتنفيذها لم تقتل الأساليب الإضافية المزعجة التي تعرضت.


تحرير 2009-10-20 15:00

هذه المقالة Microsoft من أوائل عام 2007 (عبر رابط مايك) يبدو إجابة كاملة حول الموضوع:

الوظائف الإضافية للأتمتة ومعالج الوظيفة

لكل وظيفة أتمتة فئة خاصة بها في معالج دالة Excel. اسم الفئة هو progid للإضافات ؛ لا يمكنك تحديد اسم فئة مختلف لوظائف الإضافات الأتمتة. بالإضافة إلى ذلك ، لا توجد طريقة لتحديد أوصاف الوظائف أو أوصاف الوسيطة أو مساعدة وظائف الوظيفة الإضافية في أتمتة المعالج.


1 هاه ، علة stackoverflow. يبدو أنك لا تستطيع أن تضعف سلسلة داخل قائمة HTML UL صريحة؟

هل كانت مفيدة؟

المحلول

من السهل تصحيح بعض هذا ، والأجزاء الأخرى منه صعبة إلى حد ما. كل هذا قادر على القيام به ، إذا كنت على استعداد لوضع الوقت في.

انت كتبت:

أرى أيضًا متساوًا ، Gethashcode ، Gettype ، و ToString (والتي لا تترافق إلى حد ما لفضح مستخدم Excel)

نعم ، وافق ، هذا بالتأكيد غير مرغوب فيه ، ولكن يمكن منعه. هذا يحدث لأن فصلك يرث من "System.Object" ، كما تفعل جميع فئات .NET ، وواجهةك الافتراضية التي تتعرض لـ COM تشمل هؤلاء الأعضاء. يحدث هذا ، على سبيل المثال ، إذا كنت تستخدم "ClassInterFaceAttribute" ، باستخدام الإعداد "ClassInterFaceType.Autodual".

على سبيل المثال في C#:

[ClassInterface(ClassInterfaceType.AutoDual)]

في VB.NET:

<ClassInterface(ClassInterfaceType.AutoDual)>

ومع ذلك ، يجب تجنب استخدام "classInterFaceType.Autodual" ، من أجل منع الأعضاء الموروثة من "System.Object" من التعرض (وكذلك لمنع مشكلات الإصدار المحتملة في المستقبل). بدلاً من ذلك ، حدد الواجهة الخاصة بك ، وقم بتنفيذ الواجهة في فصلك ، ثم حدد فصولك مع سمة "ClassInterface" مع قيمة "ClassInterFaceType.none".

على سبيل المثال ، باستخدام 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;
    }
}

باستخدام 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

من خلال الاستفادة من "classinterfaceatribute" مع قيمة "classInterFaceType.none" ، يتم استبعاد memebers الموروثة. بدلاً من ذلك ، يتم تصدير الواجهة المنفذة فقط ("iClassName" في هذا المثال) إلى COM.

ما سبق يستخدم أيضًا "comDefaultInterFaceAttribute". هذا ليس مهمًا جدًا ، ولا يفعل شيئًا إذا قمت بتطبيق واجهة واحدة فقط - كما في هذا المثال - ولكنها فكرة جيدة في حالة إضافة واجهة لاحقًا ، مثل idtextensibility2.

لمزيد من التفاصيل حول هذا ، راجع:

(1) الإضافات الأتمتة المدارة بقلم أندرو ويتشابيل.

(2) كتابة وظائف ورقة عمل Excel المخصصة في C# بقلم غابان بيري.

حسنًا ، الآن إلى الجزء الصعب. انت كتبت:

اختيار خادم COM الخاص بي يجلب الحجج وظيفة1] مربع حوار بدون معلومات وسيطة ولا وصف للوظيفة.

هل يمكنني تقديم وصف للوظيفة؟

هل يمكنني تقديم وصف للمعلمات؟

هل يمكنني تقديم اسم فئة لوظائفي ، بحيث أحصل على شيء أفضل من مجرد progid؟

أسهل نهج هنا هو الاستفادة من application.macroptions طريقة. تمكنك هذه الطريقة من تقديم وصف للوظيفة وتحديد الفئة التي تريد عرضها بموجبها. لا يسمح لك هذا النهج بتحديد أي معلومات لمعلمات الوظائف ، للأسف ، ولكن التقنيات التي تسمح لك بذلك معقدة للغاية ، والتي سأصل إليها لاحقًا. تصحيح: طريقة "Application.MacroPtions" تعمل فقط على UDFs التي تم إنشاؤها عبر VBA ولا يمكن استخدامها للإضافات الإضافية للأتمتة. تابع القراءة للحصول على أساليب أكثر تعقيدًا للتعامل مع تسجيل UDFs يحتوي على الإضافات الأتمتة-Mike Rosenblum 2009.10.20

نلاحظ أن مساعدة ملفات Excel 2003 و مساعدة ملفات Excel 2007 اذكر أنه يمكن توفير سلسلة إلى وسيطة الفئة من أجل توفير اسم فئة مخصص من اختيارك. احذر ، مع ذلك ، مساعدة ملفات Excel 2002 لاتفعل. لا أعرف ما إذا كان هذا إغفالًا في ملفات مساعدة Excel 2002 ، أو إذا كانت هذه قدرة جديدة اعتبارًا من Excel 2003. أنا أظن أن الأخير ، لكن يجب عليك الاختبار للتأكد.

الطريقة الوحيدة للحصول على معلومات المعلمة الخاصة بك في معالج الوظيفة هي استخدام تقنية معقدة إلى حد ما تتضمن طريقة "excel.application.executeexcel4macro". كن حذرًا: لقد كافح العديد من MVPs Excel مع هذا النهج وفشلوا في إنتاج نتيجة موثوقة. في الآونة الأخيرة ، يبدو أن Jan Karel Pieterse (JKP) قد نجحت في تنفيذها ونشرت التفاصيل هنا: تسجيل وظيفة محددة المستخدم مع Excel.

قشط هذا المقال سترى أنه ليس من أجل إغماء القلب. جزء من المشكلة هو أنه كتبها لـ VBA / VB 6.0 ، وبالتالي يجب ترجمة كل هذا الرمز إلى VB.NET أو C#. ومع ذلك ، فإن الأمر الرئيسي هو طريقة "excel.application.executeexcel4macro" ، والتي تتعرض لـ .NET ، لذلك يجب أن يعمل كل شيء بشكل جيد.

ومع ذلك ، كمسألة عملية ، أفضّل إلى حد كبير استخدام نهج "excel.application.macrooptions" لأنه بسيط وموثوق. إنه لا يوفر معلومات معلمة ، لكنني لم أحتاج بعد إلى حاجة إلى تحفيزني على اتخاذ نهج "ExecuteExcel4Macro".

لذا ، حظًا سعيدًا في هذا ، لكن نصيحتي هي الاستفادة من "Macrooptions" ، ما لم يتم الدفع لك بالساعة. ؛-)

- مايك

متابعة ردود هيو

حاولت الاتصال بالتطبيق.

لا يوجد Sub New () شبه مقبول: يتم سرد الوظيفة ضمن فئة ProgID.

مشترك جديد () غير مقبول: خطأ في وقت البناء. لا يمكن تسجيل التجميع "... foo.dll". تم طرح استثناء من قبل هدف الاحتجاج.

Sub New () غير مقبول: الفئة غير مدرجة في مربع الحوار Insert Function. أظن أن هذه مشكلة بالنسبة للعبارات المائية والطريق الأكثر مشاركة الذي أوصى به تشارلز.

لا يمكنك استخدام فصول أو منشئات مشتركة (تُعرف أيضًا باسم "Static") عند تعريض فصولك إلى COM لأن COM ليس لديه أي معرفة بهذا المفهوم وبالتالي لا يمكن تجميعها - كما اكتشفت! قد تكون قادرًا على تطبيق "comvisibleattribute" بقيمة "خاطئة" على المُنشئ المشترك ، على الأقل السماح لها بالتجميع. لكن هذا لن يساعدك في هذه الحالة على أي حال ...

قد تكون محاولة تسجيل الوظيفة الإضافية للأتمتة عبر الوظيفة الإضافية الأتمتة نفسها أمرًا صعبًا. أدرك أن هذا أمر مرغوب فيه من أجل الحفاظ عليه كمكون واحد مستقل ، ولكن قد لا يكون ذلك ممكنًا. أو على الأقل لن يكون هذا سهلاً.

المشكلة هي أن الوظائف الإضافية للأتمتة يتم تحميلها. أي أنها ليست موجودة حقًا حتى يحاول Excel الوصول إلى وظيفة ورقة العمل الأولى من الوظيفة الإضافية للأتمتة. هناك قضيتان تتعلقان بهذا:

(1) إذا وضعت رمز التسجيل الخاص بك داخل مُنشئ الفصل الخاص بك ، فلا يمكن أن توجد معلومات معالج الوظيفة الخاصة بك حتى يتم استدعاء الوظيفة لأول مرة.

(2) قد يتم تنفيذ مُنشئك عندما لا يكون Excel جاهزًا لقبول أوامر التشغيل الآلي. على سبيل المثال ، يتم عادةً تحميل الوظيفة الإضافية للأتمتة عندما يبدأ المستخدم في كتابة اسم إحدى الوظائف المعرفة من قبل المستخدم (UDFs) المحددة في الوظيفة الإضافية الأتمتة. والنتيجة هي أن الخلية موجودة في وضع التحرير عند تحميل الوظيفة الإضافية الأولى للأتمتة. إذا كان لديك رمز أتمتة داخل مُنشئك أثناء وضع التحرير ، فستفشل العديد من الأوامر. لا أعرف ما إذا كانت أساليب "excel.application.macroptions" أو "excel.application.excel4macro" لها مشكلة في هذا ، ولكن العديد من الأوامر ستختنق عند محاولة التنفيذ أثناء وجود الخلية في وضع التحرير. وإذا تم تحميل الوظيفة الإضافية الأتمتة لأول مرة لأنه يتم استدعاؤه بينما يكون معالج الوظيفة مفتوحًا ، فليس لدي أي فكرة عما إذا كانت هذه الأساليب يمكن أن تعمل بشكل صحيح.

لا يوجد حل سهل لهذا إذا كنت ترغب في الحصول على الوظيفة الإضافية الأتمتة الخاصة بك لتكون قائمة بذاتها تمامًا دون أي دعم آخر. ومع ذلك ، يمكنك إنشاء إضافة COM مُدارة من خلال تسجيل الوظيفة الإضافية لأتمتة الخاص بك عبر "excel.application.macrooptions" أو نهج "excel.application.excel4macro" عند بدء تشغيل Excel. يمكن أن تكون فئة الوظائف الإضافية المدارة في نفس المجموعة مثل مجموعة الوظائف الإضافية للأتمتة ، لذلك لا تزال تحتاج فقط إلى مجموعة واحدة.

بالمناسبة ، يمكنك حتى استخدام VBA Workbook أو .xla الوظيفة الإضافية للقيام بنفس الشيء-استخدم حدث Workbook.Open في VBA للاتصال برمز التسجيل. تحتاج فقط شيئا ما للاتصال برمز التسجيل الخاص بك عند بدء تشغيل Excel. ميزة استخدام VBA في هذه الحالة هي أنه يمكنك استخدام الكود من Jan Karel Pieterse's تسجيل وظيفة محددة المستخدم مع Excel المادة كما هي ، دون الحاجة إلى ترجمتها إلى .NET.

على الجانب الإيجابي ، توصية مايك بإنشاء واجهة لتنفيذها لم تقتل الأساليب الإضافية المزعجة التي تعرضت.

لول ، أنا سعيد لشيء عمل!

يبدو أن مقالة Microsoft هذه من أوائل عام 2007 (عبر رابط مايك) تبدو إجابة كاملة حول الموضوع:

الوظائف الإضافية للأتمتة ومعالج الوظيفة

لكل وظيفة أتمتة فئة خاصة بها في معالج دالة Excel. اسم الفئة هو progid للإضافات ؛ لا يمكنك تحديد اسم فئة مختلف لوظائف الإضافات الأتمتة. بالإضافة إلى ذلك ، لا توجد طريقة لتحديد أوصاف الوظائف أو أوصاف الوسيطة أو مساعدة وظائف الوظيفة الإضافية في أتمتة المعالج.

هذا هو قيود على نهج "excel.application.macrooptions" فقط. (اعتذاري ، لقد نسيت هذا القيد لطريقة "excel.application.macroptions" فيما يتعلق بالإضافات الآلية عندما كتبت إجابتي الأصلية أعلاه.) نهج ExecuteExcel4Macro ، ومع ذلك ، يعمل على الإطلاق من أجل الإضافات الإضافية الآلية. يجب أن تعمل أيضًا مع الإضافات الأتمتة .NET ("Managed") أيضًا ، لأن Excel ليس لديه أي فكرة عما إذا كانت تقوم بتحميل الوظيفة الإضافية Automation Com vb.net/c#. الميكانيكا هي نفسها بالضبط من جانب COM من السياج لأن Excel ليس لديه فكرة عن .NET ، أو حتى .NET موجود.

ومع ذلك ، فإن نهج "excel.application.excel4macro" سيكون بالتأكيد الكثير من العمل ...

نصائح أخرى

يمكنك إما استخدام أحد أنظمة .NET Excel مثل Exceldna أو Addin Express ، أو محاولة تكييف أحد حلول VBA/VB6: انظر إلى Laurent Longre's Funcustomisehttp://xcell05.free.fr/english/index.htmlأو مقال Jan Karel Pieterse في http://www.jkp-ads.com/articles/registerudf00.aspالذي يستخدم دالة الزائد الاختراق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top