Существует ли перевод PSafeArray To Variant?

Игорь_UUS
Дата: 10.09.2019 15:34:10
Добрый день

Приходится делать интеграцию с кассой от производителя Атол (приходится)) потому как они сворачивают поддержку "старого" драйвера, где всё работает как часики)) эххх).

Вопрос такой, я получаю массив в виде "PSafeArray" из драйвера ККТ Атол и этот массив нужно передать в этот же драйвер в виде OleVariant.

var
    date                   : TDateTime;
    SafeArrayCorrectionInfo: PSafeArray;
    CorrectionInfo         : Variant;
begin

    date := StrToDate('02.01.2018');
    FDriverATOL.setParam(1177, 'Согласованная коррекция');
    FDriverATOL.setParam(1178, date);
    FDriverATOL.setParam(1179, '<без номера>');
    FDriverATOL.utilFormTlv;
    SafeArrayCorrectionInfo := FDriverATOL.getParamByteArray(FDriverATOL.LIBFPTR_PARAM_TAG_VALUE);

// Могу сказать одно, нужно передать собранный Tlv одним параметром, видимо
// в драйвере предусмотрели функцию, которая это всё дело облегчает "FDriverATOL.getParamByteArray"
// т.е. 3 разных параметра собираем в один Tlv
// Возвращается в PSafeArray

// Далее необходимо собранный параметр передать в драйвер

    FDriverATOL.setParam(1174, SafeArrayCorrectionInfo);

// Но тут проблема, в FDriverATOL.setParam передаются только как OleVariant.. не совпадение типов((


Получается мне необходимо PSafeArray как то преобразовать в Variant.

Такое возможно?
В тех. поддержке Атол похоже не могут ответить на данный вопрос (жду пол дня у моря погоды), возможно тут ответ найдётся?!

Заранее спасибо!
_Vasilisk_
Дата: 10.09.2019 16:04:00
OleVariant они разные бывают. Какой VarType нужен?
wadman
Дата: 10.09.2019 16:08:39
Игорь_UUS
OleVariant

Может быть и массивом, содержащим в себе другие OleVariant.
Игорь_UUS
Дата: 10.09.2019 16:16:15
_Vasilisk_,

подозреваю ByteArray т.к. Tlv сборку получаю из getParamByteArray, в документации по интеграции на этот счёт ничего не сказано, приведён нерабочий пример:

var
    date: TDateTime;
    correctionInfo: Variant;
begin
    date := StrToDate('02.01.2018');
    fptr.setParam(1177, 'Документ основания коррекции');
    fptr.setParam(1178, date);
    fptr.setParam(1179, '№1234');
    fptr.utilFormTlv;
    correctionInfo := fptr.getParamByteArray(fptr.LIBFPTR_PARAM_TAG_VALUE);

    fptr.setParam(fptr.LIBFPTR_PARAM_RECEIPT_TYPE, fptr.LIBFPTR_RT_SELL_CORRECTION);
    fptr.setParam(1173, 1);
    fptr.setParam(1174, correctionInfo);
    fptr.openReceipt;


компилятор ругается:
[dcc32 Error] igUKKTDriverATOL.pas(1531): E2010 Incompatible types: 'Variant' and 'PSafeArray'
Игорь_UUS
Дата: 10.09.2019 16:17:25
компилятор ругается именно на

correctionInfo := fptr.getParamByteArray(fptr.LIBFPTR_PARAM_TAG_VALUE);
_Vasilisk_
Дата: 10.09.2019 16:34:53
Игорь_UUS,

Курите

function GetVarDataArrayInfo(const AVarData: TVarData; out AVarType: TVarType;
  out AVarArray: PVarArray): Boolean;
begin
  // variant that points to another variant?  lets go spelunking
  if AVarData.VType = varByRef or varVariant then
    Result := GetVarDataArrayInfo(PVarData(AVarData.VPointer)^, AVarType, AVarArray)
  else
  begin

    // make sure we are pointing to an array then
    AVarType := AVarData.VType;
    Result := (AVarType and varArray) <> 0;

    // figure out the array data pointer
    if Result then
      if (AVarType and varByRef) <> 0 then
        AVarArray := PVarArray(AVarData.VPointer^)
      else
        AVarArray := AVarData.VArray
    else
      AVarArray := nil;
  end;
end;
X-Cite
Дата: 10.09.2019 20:36:26
http://docwiki.embarcadero.com/Libraries/Rio/en/System.Variants.VarArrayAsPSafeArray

Есть вот такое. Посмотрите исходник, может обратным счетом получится сделать
X-Cite
Дата: 10.09.2019 21:36:48
var
  sa: PSafeArray;
  v: Variant;
  ov: OleVariant;
begin
  sa := SafeArrayCreateVector(VT_I4, 0, 9);
  TVarData(v).VType := varArray or varInteger;
  TVarData(v).VArray := PVarArray(sa);
  ov := v;
end;

Так будет работать?
_Vasilisk_
Дата: 11.09.2019 15:29:41
X-Cite
Так будет работать?
Тогда уже VarArrayCreate()
Cobalt747
Дата: 13.09.2019 09:33:47