2016-05-03 15 views
0

Ich bin ein relativ neuer Coder und habe noch nie zuvor mit C# oder VBA gearbeitet. Ich versuche derzeit, meinen C# -Code für VBA verfügbar zu machen. Ich habe die MSDN guide auf, wie man das macht.Verfügbarmachen von C# -Code zu VBA GetAutomationMethod Error

ich in einen Fehler laufen lasse, wenn es darum geht, meine Methode zu überschreiben:

public class AsynchronousClient : IAsynchronousClient { 
    protected override object GetAutomationObject(){ 
     return this; 
    } 
} 

Der Fehler ist:

'AsynchronousClient.GetAutomationObject()': keine geeignete Methode außer Kraft zu setzen gefunden.

Ich konnte die Schnittstelle extrahieren und die COMVisibleAttributes zu meiner Schnittstelle hinzugefügt.

Jede Hilfe oder zusätzliche Anleitung zur Änderung des Codes wäre willkommen.

+1

Wo kommt von IAsynchronousClient? Der Fehler besagt, dass die Schnittstelle keine Funktion namens GetAutomationObject mit den gleichen zu überschreibenden Parametern hat. – Gusman

+2

Diese How-to-Seite ist spezifisch für VSTO-Projekte auf Dokumentebene.Ziemlich zweifelhaft, das ist es, was Sie tatsächlich versuchen. Sie müssen GetAutomationObject() für Ihr Hostelement überschreiben, nicht für eine Klasse, die eine Eigenschaft des Hostelements verfügbar machen soll. –

Antwort

0

Wie bereits erwähnt, beziehen sich die Schritte, die Sie verfolgen, auf die VSTO-Technologie und nicht auf das Erstellen einer DLL zur Verwendung mit VBA. Ganz ehrlich, wenn Sie noch nie in einer der beiden Sprachen codiert haben, ist dies wahrscheinlich nicht das beste, um damit zu beginnen ...

Beginnen Sie mit einem Klassenprojekt. Sie benötigen GUIDs. Sie benötigen eine Schnittstelle, die Ihre Klasse implementieren muss. Und Sie müssen angeben, wie die Klasse mit der Schnittstelle arbeiten soll. Es muss auf den Typ "None" eingestellt sein, damit Intellisense usw. funktioniert. Die DLL muss ebenfalls COM-registriert sein.

Hier einige Test-Code verwende ich, um Ihnen eine Vorstellung davon, wie der Code Teil

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 
using vbForm = Microsoft.Vbe.Interop.Forms; 
using office = Microsoft.Office.Core; 

//[assembly: Guid("B5C4D7F5-C9B2-491e-91BA-63C208959190")] 

namespace COM_ClassLib_CS 
{ 

    [Guid("BF78EB64-F59B-4086-9FC5-B87AA2002F4F")] 
    [ComVisible(true)] 
    public interface IVBAExtensions 
    { 
     string getTest(object app); 
     void formData(object formControl); 
     void passWordDoc(object doc); 
     object[,] returnArray(); 
     string returnString(); 
    } 

    [Guid("EC0B623E-E8A0-4564-84FB-2D8D149C8BA7")] 
    [ClassInterface(ClassInterfaceType.None)] 
    [ComVisible(true)] 
    public class VBAExtensions : IVBAExtensions 
    { 
     public VBAExtensions() 
     { 
     } 

     //test using late-binding 
     public string getTest(object app) 
     { 
      object xlApp = app.GetType().InvokeMember("Application", System.Reflection.BindingFlags.GetProperty, null, 
       app, null); 
      object nm = xlApp.GetType().InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, 
       xlApp, null); 
      string appName = nm.ToString(); 
      object isReady = xlApp.GetType().InvokeMember("Ready", System.Reflection.BindingFlags.GetProperty, null, 
       xlApp, null); 
      string sReady = isReady.ToString(); 
      return sReady; 
     } 

     //test calling from a UserForm, passing control as argument 
     public void formData(object formControl) 
     { 
      //string data = ""; 
      vbForm.TextBox t = formControl as vbForm.TextBox; 
      t.Text = "test"; 
      //return data; 
     } 

     //test passing doc object and accessing its Window 
     public void passWordDoc(object doc) 
     { 
      Microsoft.Office.Interop.Word.Document WordDoc = doc as Microsoft.Office.Interop.Word.Document; 
      WordDoc.ActiveWindow.Caption = "Tested!"; 
     } 

     //test returning an array to VBA calling procedure 
     public object[,] returnArray() 
     { 

      //object[] array = new object[2] {"a", "b"}; 
      object[,] array = new object[2, 2]; 
      array[0, 0] = "a"; 
      array[0, 1] = "1"; 
      array[1, 0] = "b"; 
      array[1, 1] = "2"; 
      return array; 
     } 

     //test returning a string to VBA calling procedure 
     public string returnString() 
     { 
      return "AbC"; 
     } 

    } 
} 

Für weitere Informationen können Sie sieht https://msdn.microsoft.com/en-us/library/c3fd4a20.aspx Referenz und https://msdn.microsoft.com/en-us/library/ms973802.aspx

+0

Vielen Dank für die Freigabe Ihres Codes. Ich denke, ich habe die entsprechenden Attribute (die ProgId, Guid) hinzugefügt und ich denke, das Entfernen der geschützten überschreiben Methode Objekt ist der beste Weg, um fortzufahren. – Saba

0

Ihre AsynchronousClient Klasse ist die IAsynchronousClient Schnittstelle implementiert, die ich wie folgt aussieht vermuten:

public interface IAsynchronousClient 
{ 
    object GetAutomationObject(); 
} 

Sie würde es so implementieren:

public class AsynchronousClient : IAsynchronousClient 
{ 
    public object GetAutomationObject() 
    { 
     return this; 
    } 
} 

Die Fehlermeldung sagt genau das, was das Problem ist, : da ist nichts zu override da. Sie verwenden die Methode override, wenn Sie abstract oder virtual Methoden implementieren, keine Schnittstellenelemente.

Entfernen Sie das override Stichwort, und Sie werden gut sein. Im Folgenden Schnipsel Situationen zeigen, wo override anwendbar wäre:

public abstract class AsynchronousClientBase 
{ 
    public abstract object GetAutomationObject(); 

    public virtual object GetFoo() 
    { 
     return null; 
    } 
} 


public class AsynchronousClient : AsynchronousClientBase 
{ 
    public override object GetAutomationObject() 
    { 
     return this; 
    } 

    public override object GetFoo() 
    { 
     return new Foo(); 
    } 
} 

Der MSDN-Artikel Du verknüpft sagt, „die Methode GetAutomationObject außer Kraft setzt eine Host-Element-Klasse im Projekt“ - das Ihre Art impliziert abgeleitet sein sollte eine Basisklasse, die eine virtuelle oder abstrakte Methode GetAutomationObject definiert.