2016-05-03 2 views
0

Я относительно новый кодер и никогда раньше не работал с C# или VBA. В настоящее время я пытаюсь открыть свой код C# для VBA. Я слежу за MSDN guide о том, как это сделать.Предоставление кода C# для VBA GetAutomationMethod Error

Я бегу в ошибку, когда речь идет о перекрывая мой метод:

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

Ошибка является:

'AsynchronousClient.GetAutomationObject()': нет подходящего способа найденную переопределить.

Я смог извлечь интерфейс и добавил COMVisibleAttributes к моему интерфейсу.

Любая помощь или дополнительное руководство по изменению кода будет оценено по достоинству.

+1

Где происходит от IAsynchronousClient? ошибка указывает, что интерфейс не имеет функции с именем GetAutomationObject с теми же параметрами, которые будут переопределены. – Gusman

+2

Эта справочная страница относится к VSTO «проектам уровня документа».Довольно сомнительно, это то, что вы на самом деле пытаетесь сделать. Вы должны переопределить GetAutomationObject() в своем объекте хоста, а не в классе, который вам нужно открыть свойство элемента хоста. –

ответ

0

Как уже упоминалось, шаги, которые вы выполняете, относятся только к технологии VSTO, а не к созданию DLL для использования с VBA. Честно говоря, если вы никогда не кодировали на любом языке раньше, это, вероятно, не лучшее, что можно начать с ...

Начать с проекта класса. Вам нужны GUID. Вам нужен интерфейс, который должен реализовать ваш класс. И вам нужно указать, как класс должен работать с интерфейсом. Для работы должен быть установлен тип «Нет» для Intellisense и т. Д. DLL также должна быть зарегистрирована в COM.

Вот некоторые тестового кода я использую, чтобы дать вам представление о том, как часть кода выглядит

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"; 
     } 

    } 
} 

Для получения дополнительной информации вы можете ссылаться на https://msdn.microsoft.com/en-us/library/c3fd4a20.aspx и https://msdn.microsoft.com/en-us/library/ms973802.aspx

+0

Спасибо, что поделились своим кодом. Я думаю, что я добавил соответствующие атрибуты (ProgId, Guid), и я думаю, что удаление защищенного объекта метода переопределения - лучший способ продолжения. – Saba

0

Ваш AsynchronousClient класс реализует интерфейс IAsynchronousClient, который я полагаю, выглядит следующим образом:

public interface IAsynchronousClient 
{ 
    object GetAutomationObject(); 
} 

Вы бы реализовать это следующим образом:

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

Сообщение об ошибке говорит, что именно эта проблема : ничего не стоит override. Вы используете метод override, когда вы используете методы abstract или virtual, а не элементы интерфейса.

Измените ключевое слово override, и все будет хорошо. Ниже фрагменты показывают ситуации, когда override будет применяться:

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(); 
    } 
} 

В статье MSDN вы связаны говорит «Переопределить метод GetAutomationObject класса ведущего элемента в проекте» - это означает тип должен быть производным от базовый класс, который определяет виртуальный или абстрактный метод GetAutomationObject.

Смежные вопросы