Чтение данных из таблицы TCURR с использованием RFC_READ_TABLE усекает значение скорости - PullRequest
1 голос
/ 06 ноября 2019

Я пытаюсь прочитать данные из SAP ECC, используя Microsoft .NET. Для этого я использую SAP Connector для Microsoft .NET 3.0 . Ниже приведен код для извлечения данных, и я тоже получаю результаты. Однако я обнаружил, что значение обменного курса имеет *, если оно превышает 7 символов.

        ECCDestinationConfig cfg = new ECCDestinationConfig();

        RfcDestinationManager.RegisterDestinationConfiguration(cfg);

        RfcDestination dest = RfcDestinationManager.GetDestination("mySAPdestination");

        RfcRepository repo = dest.Repository;


        IRfcFunction testfn = repo.CreateFunction("RFC_READ_TABLE");
        testfn.SetValue("QUERY_TABLE", "TCURR");

        // fields will be separated by semicolon
        testfn.SetValue("DELIMITER", ";");

        // Parameter table FIELDS contains the columns you want to receive
        // here we query 3 fields, FCURR, TCURR and UKURS
        IRfcTable fieldsTable = testfn.GetTable("FIELDS");
        fieldsTable.Append();
        fieldsTable.SetValue("FIELDNAME", "FCURR");
        fieldsTable.Append();
        fieldsTable.SetValue("FIELDNAME", "TCURR");
        fieldsTable.Append();
        fieldsTable.SetValue("FIELDNAME", "UKURS");
        fieldsTable.Append();
        fieldsTable.SetValue("FIELDNAME", "GDATU");

        // the table OPTIONS contains the WHERE condition(s) of your query           
        // several conditions have to be concatenated in ABAP syntax, for instance with AND or OR
        IRfcTable optsTable = testfn.GetTable("OPTIONS");

        var dateVal = 99999999 - 20190701;
        optsTable.Append();
        optsTable.SetValue("TEXT", "gdatu = '" + dateVal + "' and KURST = 'EURX'");


        testfn.Invoke(dest);

Значения следующие:

enter image description here

Как получить полное значение без усечения?

Ответы [ 4 ]

3 голосов
/ 06 ноября 2019

Вы только что столкнулись с наихудшим ограничением RFC_READ_TABLE.

Его ошибка - возвращать значения полей на основе внутренней длины и обрезать оставшиеся, а не использовать выходную длину. TCURR-UKURS - это десятичное упакованное поле BCD длиной 9,5 (9 байтов = 17 цифр, включая 5 цифр после десятичной точки) и длиной вывода 12. К сожалению, RFC_READ_TABLE выводит результат на 9 символов, поэтомузначение 105.48000- принимает 10 символов слишком долго, поэтому логика ABAP по умолчанию - установить символ переполнения * для крайнего левого символа (*5.48000-).

Либо вы создаете другой функциональный модуль с поддержкой RFCна стороне SAP / ABAP, или вы получаете прямой доступ к базе данных SAP (классическая СУБД, подключенная к серверу SAP).

2 голосов
/ 07 ноября 2019

Просто дополнение к Сандре прекрасное объяснение этой проблемы. Да, единственным решением здесь будет написание собственного модуля для извлечения удаленных записей.

Если вы не хотите переписывать его с нуля, самое простое решение - скопировать RFC_READ_TABLE в модуль Z и изменить строку137

FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-LENG.

до

FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-OUTPUTLEN.

Это решает проблему.

ОБНОВЛЕНИЕ : попробуйте BAPI_EXCHANGERATE_GETDETAIL BAPI, с поддержкой RFCи читает ставки правильно. Интерфейс довольно понятен, единственное отличие состоит в том, что дата должна быть в собственном формате, а не в перевернутом:

CALL FUNCTION 'BAPI_EXCHANGERATE_GETDETAIL'
  EXPORTING
    rate_type  = 'EURO'
    from_curr  = 'USD'
    to_currncy = 'EUR'
    date       = '20190101'
  IMPORTING
    exch_rate  = rates
    return     = return.
0 голосов
/ 09 ноября 2019

Использовать BBP_RFC_READ_TABLE. Это все еще не лучший вариант, но он делает одну вещь, которую не сделал RFC_READ_TABLE: один дополнительный байт для десятичного знака.

Нет необходимости проходить все испытания, если вы ищете только исправление десятичной проблемы.

0 голосов
/ 08 ноября 2019

Это пример кода, используемого с коннектором SAP для .NET, пусть он будет полезен для тех, кто ищет то же самое. Спасибо всем, кто помог.

        var RateForDate = 20190701;

        ECCDestinationConfig cfg = new ECCDestinationConfig();
        RfcDestinationManager.RegisterDestinationConfiguration(cfg);
        RfcDestination dest = RfcDestinationManager.GetDestination("mySAPdestination");
        RfcRepository repo = dest.Repository;


        IRfcFunction sapFunction = repo.CreateFunction("RFC_READ_TABLE");
        sapFunction.SetValue("QUERY_TABLE", "TCURR");
        // fields will be separated by semicolon
        sapFunction.SetValue("DELIMITER", ";");

        // Parameter table FIELDS contains the columns you want to receive
        // here we query 3 fields, FCURR, TCURR and UKURS
        IRfcTable fieldsTable = sapFunction.GetTable("FIELDS");
        fieldsTable.Append();
        fieldsTable.SetValue("FIELDNAME", "FCURR");
        //fieldsTable.Append();
        //fieldsTable.SetValue("FIELDNAME", "TCURR");
        //fieldsTable.Append();
        //fieldsTable.SetValue("FIELDNAME", "UKURS");


        // the table OPTIONS contains the WHERE condition(s) of your query
        // here a single condition, KUNNR is to be 0012345600
        // several conditions have to be concatenated in ABAP syntax, for instance with AND or OR
        IRfcTable optsTable = sapFunction.GetTable("OPTIONS");

        var dateVal = 99999999 - RateForDate;
        optsTable.Append();
        optsTable.SetValue("TEXT", "gdatu = '" + dateVal + "' and KURST = 'EURX'");

        sapFunction.Invoke(dest);

        var companyCodeList = sapFunction.GetTable("DATA");
        DataTable Currencies = companyCodeList.ToDataTable("DATA");

        //Add additional column for rates
        Currencies.Columns.Add("Rate", typeof(double));

        //------------------
        sapFunction = repo.CreateFunction("BAPI_EXCHANGERATE_GETDETAIL");
        //rate type of your system
        sapFunction.SetValue("rate_type", "EURX");
        sapFunction.SetValue("date", RateForDate.ToString());
        //Main currency of your system
        sapFunction.SetValue("to_currncy", "EUR");

        foreach (DataRow item in Currencies.Rows)
        {
            sapFunction.SetValue("from_curr", item[0].ToString());
            sapFunction.Invoke(dest);
            IRfcStructure impStruct = sapFunction.GetStructure("EXCH_RATE");
            item["Rate"] = impStruct.GetDouble("EXCH_RATE_V");
        }


        dtCompanies.DataContext = Currencies;     
        RfcDestinationManager.UnregisterDestinationConfiguration(cfg);
...