Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.08.2011, 15:29   #1
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
Восклицание Как обработать тип Variant ?

Использование протокола SOAP импортирую (http://api.a1agregator.ru/api.wsdl)

делаю аpi.pas прикручиваю к основной программе и все гуд кроме вот чего у некоторых функциях возвращаемое значение типа Variant
и я не знаю как с ним бороться уже неоднократно гуглил этот тип но все никак не пойму как вытащить ответ с функции в текст !
мне кажется что я неправильно что то делаю может импорт неправильно провожу у меня delphi 2007 если кто знает подскажите заранее большое спасибо!
маленький пример того как я все реализовую:
Код:
ListBox1.Items.Add(ShowBasicVariantType((HTTPRIO1 as ApiPortType).getCountries));
по идеи getCountries() возвращает массив строк мне так кажется судя с некого описания тут!
а в ответ функции ShowBasicVariantType() я получаю varVariant или varNull.

сама функция ShowBasicVariantType() приведена ниже:

Код:
function ShowBasicVariantType(varVar: Variant): string;
var
  typeString : string;
  basicType  : Integer;
begin
  basicType := VarType(varVar) and VarTypeMask;
  case basicType of
    varEmpty     : typeString := 'varEmpty';
    varNull      : typeString := 'varNull';
    varSmallInt  : typeString := 'varSmallInt';
    varInteger   : typeString := 'varInteger';
    varSingle    : typeString := 'varSingle';
    varDouble    : typeString := 'varDouble';
    varCurrency  : typeString := 'varCurrency';
    varDate      : typeString := 'varDate';
    varOleStr    : typeString := 'varOleStr';
    varDispatch  : typeString := 'varDispatch';
    varError     : typeString := 'varError';
    varBoolean   : typeString := 'varBoolean';
    varVariant   : typeString := 'varVariant';
    varUnknown   : typeString := 'varUnknown';
    varByte      : typeString := 'varByte';
    varWord      : typeString := 'varWord';
    varLongWord  : typeString := 'varLongWord';
    varInt64     : typeString := 'varInt64';
    varStrArg    : typeString := 'varStrArg';
    varString    : typeString := 'varString';
    varAny       : typeString := 'varAny';
    varTypeMask  : typeString := 'varTypeMask';
  end;
  result:=typeString
end;

Последний раз редактировалось Stilet; 29.08.2011 в 17:12. Причина: неполное описание
fucil вне форума Ответить с цитированием
Старый 29.08.2011, 15:30   #2
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию

листинг аpi.pas
___________________________________ ___________________________________ _________________
Код:
unit api;
interface
uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;
type
  ApiPortType = interface(IInvokable)
  ['{EA64BB6F-7AEE-EDF4-236A-59DD0AD63D49}']
    function  addIvrForwardService(const name: WideString; const forwardNumber: WideString; const num: integer; const url: WideString; const secondaryUrl: WideString): Variant; stdcall;
    function  addIvrLockService(const name: WideString; const time: integer; const num: integer; const url: WideString; const secondaryUrl: WideString): Variant; stdcall;
    function  addPrefix(const serviceId: integer; const prefixFirst: WideString; const prefixSecond: WideString): Variant; stdcall;
    function  addService(const name: WideString; const url: WideString; const secondaryUrl: WideString; const skey: WideString): Variant; stdcall;
    function  addSmsService(const name: WideString; const url: WideString; const secondaryUrl: WideString; const skey: WideString): Variant; stdcall;
    function  checkBlacklist(const phone: integer): integer; stdcall;
    function  checkConnect: Variant; stdcall;
    function  checkPartner(const partnerId: integer; const encryptedPass: WideString): Boolean; stdcall;
    function  checkPrefix(const prefixFirst: WideString; const prefixSecond: WideString): Boolean; stdcall;
    function  deleteIvrService(const serviceId: integer): Boolean; stdcall;
    function  deletePrefix(const prefixId: integer): Boolean; stdcall;
    function  deletePrefixesForService(const serviceId: integer): Boolean; stdcall;
    function  deleteService(const serviceId: integer): Boolean; stdcall;
    function  editService(const serviceId: integer; const name: WideString; const url: WideString; const secondaryUrl: WideString; const skey: WideString): Variant; stdcall;
    function  editSmsService(const serviceId: integer; const name: WideString; const url: WideString; const secondaryUrl: WideString; const skey: WideString): Variant; stdcall;
    function  getCountries: Variant; stdcall;
    function  getFreePrefixes: Variant; stdcall;
    function  getIvrCode(const service: integer): Variant; stdcall;
    function  getIvrServiceById(const serviceId: integer): Variant; stdcall;
    function  getIvrServices: Variant; stdcall;
    function  getOperators: Variant; stdcall;
    function  getPrefixById(const prefixId: integer): Variant; stdcall;
    function  getPrefixesForService(const serviceId: integer): Variant; stdcall;
    function  getPrefixesIdsForService(const serviceId: integer): Variant; stdcall;
    function  getServiceById(const serviceId: integer): Variant; stdcall;
    function  getServices: Variant; stdcall;
    function  getSharpStatDate(const date: WideString): Variant; stdcall;
    function  getStatDate(const date: WideString): Variant; stdcall;
    function  getStatTail: Variant; stdcall;
    function  getTariffs(const serviceId: integer): Variant; stdcall;
    function  setPhoneToCode(const code: WideString; const phone: WideString): Variant; stdcall;
    function  sharpPartner(const partnerId: integer): Variant; stdcall;
    function  sharpPartners: Variant; stdcall;
    function  sharpServices(const partnerId: integer): Variant; stdcall;
    function  smsStatus(const id: integer): Variant; stdcall;
  end;

function GetApiPortType(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): ApiPortType;

implementation

function GetApiPortType(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): ApiPortType;
const
  defWSDL = 'http://api.a1agregator.ru/api.wsdl';
  defURL  = 'http://api.a1agregator.ru/index.php';
  defSvc  = 'apiService';
  defPrt  = 'ApiPort';
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as ApiPortType);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;
initialization

  InvRegistry.RegisterInterface(TypeInfo(ApiPortType), 'urn:api', 'UTF-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ApiPortType), 'urn:ApiAction');
end.

Последний раз редактировалось Stilet; 29.08.2011 в 17:13.
fucil вне форума Ответить с цитированием
Старый 29.08.2011, 16:37   #3
mss
Заблокирован
 
Регистрация: 27.05.2010
Сообщений: 1,099
По умолчанию

getCountries, судя по множ.числу в названии ф-ции, возвращает список значений. Этот список вполне вероятно представлен динамическим или вариантным массивом (второе более вероятно).
Отсюда видно направление куда копать - в сторону VarArrayDimCount, VarArrayLowBound, VarArrayHighBound.
mss вне форума Ответить с цитированием
Старый 29.08.2011, 17:05   #4
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию спасибо за ответ коллега

mss если не затруднит можно привести пример такой реализации !
я реализовал так:

var
I: Byte;
begin
I:= VarArrayDimCount((HTTPRIO1 as ApiPortType).getCountries);
If I<>0 then
MessageDlg( 'размерность массива:'+ IntToStr(I), mtInformation, [mbOk], 0)
else
MessageDlg( 'переменная не являеться Variant-масивом', mtInformation, [mbOk], 0);

получаю 1 то-есть одномерный массив но как из него строки вытащить ?

Последний раз редактировалось fucil; 29.08.2011 в 17:31.
fucil вне форума Ответить с цитированием
Старый 29.08.2011, 17:21   #5
mss
Заблокирован
 
Регистрация: 27.05.2010
Сообщений: 1,099
По умолчанию

Код:
var
 i : Integer;
 Countries: Variant;
 VarArrayItem: Variant;
..
Countries := (HTTPRIO1 as ApiPortType).getCountries;
for i := VarArrayLowBound(Countries, 1) to VarArrayHighBound(Countries, 1) do
  begin
    VarArrayItem := Countries[i];
...
  end;
mss вне форума Ответить с цитированием
Старый 29.08.2011, 18:00   #6
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию Да я тоже так написал

да я точно так же сделал но только хотел сразу вывод в мемо сделать а он мне ясен пень ошибку ! Проблема сообственно в том как перевести в строку.
код:
____________________
Код:
var
 i : Integer;
 Countries: Variant;
 VarArrayItem: Variant;
begin
Countries := (HTTPRIO1 as ApiPortType).getCountries;
for i := VarArrayLowBound(Countries, 1) to VarArrayHighBound(Countries, 1) do
  begin
     ListBox1.Items.Add(VarToStr(Countries[i]));
Но тут ошибка:

raised exception class EVariantTypeCastError with message 'Could not convert variant of type (ArrayVariant) into type (String)'. Process stopped. Use step or Run to continue

Последний раз редактировалось fucil; 29.08.2011 в 18:11.
fucil вне форума Ответить с цитированием
Старый 29.08.2011, 18:02   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

ListBox1.Items.Add(VarToStr(Countri es[i]);
Скобки то посчитай
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 29.08.2011, 18:28   #8
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию Смысл не в скойбках а в типах

он не может конвертнуть ArrayVariant в string ПОМОГИТЕ ПОЖАЛУЙСТА !
fucil вне форума Ответить с цитированием
Старый 29.08.2011, 19:36   #9
mss
Заблокирован
 
Регистрация: 27.05.2010
Сообщений: 1,099
По умолчанию

Ну так выясни не является ли Countries[i] таким же вариантным массивом как и Countries !
mss вне форума Ответить с цитированием
Старый 30.08.2011, 00:32   #10
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
Восклицание mss чет я не пойму что и как !

mss помоги реализовать вывод c этого вариантного массива а TListBox или Memo. А то я чет я все никак не пойму что к чему я ещё не особо силен в программировании заранее спасибо !

Я пока погуглю если будит минутка ответь !

Последний раз редактировалось fucil; 30.08.2011 в 10:36.
fucil вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Variant как параметр по умолчанию Gregor Общие вопросы Delphi 4 06.05.2011 11:15
Тип Variant Дэкан1 Помощь студентам 1 21.05.2010 20:31
тип Variant Михаил Юрьевич Общие вопросы Delphi 3 31.01.2008 09:05
как variant из текста преобразовать в булин? Deceased Общие вопросы Delphi 10 18.12.2007 10:24