Sin
Sin

Reputation: 1864

Reading TCURR table with RFC_READ_TABLE truncates the rate value

I'm trying to read data from SAP ECC using Microsoft .NET. For this, I am using the SAP Connector for Microsoft .NET 3.0 Following is the code to retrieve the data, I'm getting the results too. However, I found that the exchange rate value is having a * if it exceeds 7 characters.

        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);

Values are as follows:

enter image description here

How to get the full value without any truncation?

Upvotes: 1

Views: 2636

Answers (4)

AecorSoft
AecorSoft

Reputation: 494

Use BBP_RFC_READ_TABLE. It is still not the best but it does one thing right which RFC_READ_TABLE did not: one additional byte for the decimal sign.

No need to go through all the ordeal if you only look for patching the decimal issue.

Upvotes: 1

Sin
Sin

Reputation: 1864

This is the sample code used with SAP connector for .NET, let it be helpful for someone who looks for the same. Thanks for all those who helped.

        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);

Upvotes: 0

Suncatcher
Suncatcher

Reputation: 10621

Just an addition to Sandra perfect explanation about this issue. Yes, the only solution here would be writing a custom module for fetching remote records.

If you don't want to rewrite it from scratch the simplest solution would be to copy RFC_READ_TABLE into Z module and change line 137

FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-LENG.

to

FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-OUTPUTLEN.

This solves the problem.

UPDATE: try BAPI_EXCHANGERATE_GETDETAIL BAPI, it is RFC-enabled and reads rates correctly. The interface is quite self-explanatory, the only difference is that date should be in native format, not in inverted:

CALL FUNCTION 'BAPI_EXCHANGERATE_GETDETAIL'
  EXPORTING
    rate_type  = 'EURO'
    from_curr  = 'USD'
    to_currncy = 'EUR'
    date       = '20190101'
  IMPORTING
    exch_rate  = rates
    return     = return.

Upvotes: 3

Sandra Rossi
Sandra Rossi

Reputation: 13656

You just ran into the worst limitation of RFC_READ_TABLE.

Its error is to return field values based on internal length and truncating the rest, rather than using the output length. TCURR-UKURS is a BCD decimal packed field of length 9,5 (9 bytes = 17 digits, including 5 digits after the decimal point) and an output length of 12. Unfortunately, RFC_READ_TABLE outputs the result on 9 characters, so a value of 105.48000- takes 10 characters is too long, so ABAP default logic is to set the * overflow character on the leftmost character (*5.48000-).

Either you create another RFC-enabled function module at SAP/ABAP side, or you access directly the SAP database (classic RDBMS connected to SAP server).

Upvotes: 3

Related Questions