Это долго - извинения ....
Существует ли надежный способ возврата списков из C # в VBA через веб-сервис?
У меня есть веб-сервис, который возвращает «результат», который состоит из нескольких значений типа double, строк и т. Д. (Это инженерный расчет). Я также возвращаю список «Ошибки» и «Сообщения», которые содержат информацию о калькуляторе и дают вам некоторое представление о том, что, если что-то пошло не так. Так что эти списки потенциально пусты.
Вот мой класс C # 'NoteList', и оба типа 'Errors' и 'Messages' этого типа.
public class Note
{
public int ID;
public string Message;
public Note()
{
ID = 0;
Message = "";
}
public Note(int aID, string aMessage)
{
ID = aID;
Message = aMessage;
}
}
public class NoteList : List<Note>
{
}
Все довольно просто.
Мой класс 'Result' содержит два списка, таким образом:
public class Result
{
// Lists
public NoteList ErrorList = new NoteList();
public NoteList MessageList = new NoteList();
// Lots of other stuff...
}
Пока все хорошо ...
Я использовал VBA Web References Toolkit для создания некоторого прокси-сервера VBA «struct» для хранения результата. Сгенерированный код выглядит следующим образом ...
A struct_note:
Public ID As Long
Public Message As String
A struct_Result:
'"ErrorList" is an array with elements defined as struct_Note
'See Complex Types: Arrays in Microsoft Office 2003 Web Services Toolkit Help
'for details on implementing arrays.
Public ErrorList As Variant
'"MessageList" is an array with elements defined as struct_Note
'See Complex Types: Arrays in Microsoft Office 2003 Web Services Toolkit Help
'for details on implementing arrays.
Public MessageList As Variant
' plus the other stuff....
Я включил комментарии в приведенный выше список, сгенерированные инструментарием.
В моем VBA я создаю свой результат и использую его следующим образом:
Dim r as struct_Result
Dim ws As clsws_MyWebService ' This is another generated proxy class
и я наполняю это так:
Set r = ws.wsm_SomeMethod()
делать что-то, а потом «ничего», когда я закончу
Set r = nothing
Правильно - к моей проблеме ...
Я хочу запустить этот веб-метод несколько раз на листе Excel и отметить ошибки и сообщения, которые возвращаются. Так что я положил выше в цикле
for i = 1 to 10000
Set r = ws.wsm_SomeMethod()
' do some analysis and write back to the spreadsheet
Set r = nothing
next i
Это работает нормально, пока я не получу результат, в котором нет ошибок, т.е. ErrorList пуст. Я тогда получаю ошибку VB, говорящую
![Screen shot of VB error](https://i.stack.imgur.com/wa7R4.jpg)
(источник: bigsmoke.com )
Я подозреваю, что VB создает что-то, что требует ErrorList с чем-то в нем, и жалуется, что массив имеет нулевой размер.
Кто-нибудь в стране стека overflow получил идеи о том, как решить эту проблему?
Спасибо
сал
-------- [РЕДАКТИРОВАТЬ] НИЖЕ ДОБАВЛЕНО ПОСЛЕ ОТВЕТА ОТ НИТЗМАХОНА -------------------
Я изменил свой код, чтобы разрешить пустой список следующим образом
public class Result
{
// Lists
[XmlElement(IsNullable = true)]
public NoteList ErrorList = new NoteList();
[XmlElement(IsNullable = true)]
public NoteList MessageList = new NoteList();
// Lots of other stuff...
}
Это изменяет WSDL так, как я не ожидал. До добавления атрибутов IsNullable WSDL, сгенерированный для «Результата», выглядел следующим образом:
<s:complexType name="Result">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="ErrorList" type="tns:ArrayOfNote" />
<s:element minOccurs="0" maxOccurs="1" name="MessageList" type="tns:ArrayOfNote"/>
// Stuff deleted for clarity...
</s:sequence>
</s:complexType>
<s:complexType name="ArrayOfNote">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="Note" nillable="true" type="tns:Note" />
</s:sequence>
У нас есть «Результат», содержащий «ArrayOfNote», содержащий обнуляемые «Заметки».
После добавления [XmlElement (IsNullable = true)] в списки я получаю этот WSDL:
<s:complexType name="Result">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="ErrorList" nillable="true" type="tns:Note" />
<s:element minOccurs="0" maxOccurs="unbounded" name="MessageList" nillable="true" type="tns:Note" />
// Stuff deleted for clarity...
</s:sequence>
</s:complexType>
Я потерял «ArrayOfNote», и у меня остался один (т.е. не массив) «ErrorList», который является «Note». Я запустил несколько примеров и даже добавил [XmlElement (IsNullable = true)] в списки, которые я получаю (в VB) одно значение, которое всегда является последним элементом списков C # на стороне сервера.
Должен ли я поместить [XmlElement (IsNullable = true)] куда-нибудь еще? Где ??
Спасибо!
Steve