2012-04-02 3 views
4

Я написал сборку в C#, который возвращает массив строк, то # код C ниже:Как обрабатывать строку возвращаемый массив из C# метод в VBA

[ComVisible(true)] 
public class PostcodeFinder 
{ 
    public string[] SearchPostcodes(string postCode) 
    { 
     var searchService = new QuickAddress("http://x.x.x.x:xxxx/") 
           {Engine = QuickAddress.EngineTypes.Singleline, Flatten = true}; 

     var mPicklist = searchService.Search("GBR", postCode, PromptSet.Types.OneLine); 
     var x = mPicklist.Picklist.Items.Count(); 

     var resultsToReturn = new string[x]; 

     for (var i = 0; i < x; i++) 
     { 
      resultsToReturn[i] = mPicklist.Picklist.Items[i].PartialAddress; 
     } 

     return resultsToReturn; 
    } 
} 

Я потом построили эту сборку, обязательно отметьте поле Register for COM interop в свойствах. Затем в Microsoft Access я добавил файл .tlb в ссылки и создал форму с несколькими элементами управления (одним из которых является элемент управления Listbox с именем lstResults). Под основной кнопкой управления, у меня есть следующий VBA код:

Private Sub btnSearch_Click() 

    Dim postcodeToSearch As String 
    postcodeToSearch = Me.txtPostcode 

    Dim c As New PostcodeFinder 
    Dim results 

    results = c.SearchPostcodes(postcodeToSearch) 

End Sub 

Edit: Это выполняется без ошибок, однако, когда я запрашиваю окно интерпретации с ?results после ввода фиктивного кода, приведенного ниже, чтобы позволить мне поставить точку останова, Я получаю следующее сообщение об ошибке:

Run-time error '13' - Type mismatch

Эффективно я хочу переписать следующие C# код в VBA:

var results = c.SearchPostcodes(postcodeToSearch); 

foreach(var x in results) 
{ 
    lstResults.Items.Add(x); 
} 

спасибо заранее

ответ

3

Обновлено Ответ: Вместо возвращения string[], попробуйте возвращение object вместо:

[ComVisible(true)] 
public class PostcodeFinder 
{ 
    public object SearchPostcodes(string postCode) 
    { 
     //Unchanged code 

     return (object)resultsToReturn; 
    } 
} 

Вы еще получите ошибку несоответствия типов в немедленном окне при выполнении ?results (необходимо указать индекс, такие как ?results(0)), однако вы можете перебирать массив как:

results = c.SearchPostcodes(postcodeToSearch) 
Dim result As Variant 
For Each result In results 
    MsgBox result 
Next result 

Оригинальный ответ: Вам необходимо создать экземпляр класса PostcodeFinder. В вашей подпрограмме btnSearch_Click, попробуйте:

Dim c As New PostcodeFinder 
Dim results 

results = c.SearchPostcodes(postcodeToSearch) 

В качестве альтернативы, можно отделить декларацию от конкретизации, как:

Dim c As PostcodeFinder 
Dim results 
Set c = New PostcodeFinder 

results = c.SearchPostcodes(postcodeToSearch) 
+0

Ah thankyou. Теперь это выполняется без ошибок, однако я до сих пор не понимаю, как обращаться с результирующим массивом строк. Кроме того, если я помещаю некоторый фиктивный код ниже, чтобы позволить мне разместить точку останова, используйте окно Immediate для ввода «результатов». Я получаю «Ошибка времени выполнения» 13, «Тип несоответствия». – JMK

+1

Проблема в том, что вы возвращаете массив строк из метода SearchPostcodes, когда вам нужно вернуть COM-объект. Вот еще один поток SO, подробно описывающий эту проблему с помощью решения: http://stackoverflow.com/questions/948712/how-to-pass-an-array-from-c-sharp-function-to-vba. – countfromzero

+0

Обновлен мой ответ решением другого вопроса. Хотя я не уверен, что это лучшее решение, оно обеспечивает ожидаемую функциональность. – countfromzero

2

В VBA элемент в для каждого цикла должен быть вариантом, когда цикл через массив.

Dim v As Variant 
For Each v In Array("value 1", "value 2", "value 3") 
    ' do something with v 
Next v 

Typing ?results в окне Immediate дает ошибку, потому что VBA не может автоматически преобразовать массив в строку. Вам нужно либо сказать, какую часть массива вы хотите, ?results(2), либо использовать Join(sourcearray, delimiter), чтобы рассказать об этом, как преобразовать массив, ?Join(results, ",").

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