1
votes

La lecture de la table TCURR avec RFC_READ_TABLE tronque la valeur du taux

J'essaie de lire les données de SAP ECC à l'aide de Microsoft .NET. Pour cela, j'utilise le Connecteur SAP pour Microsoft .NET 3.0 Voici le code pour récupérer les données, j'obtiens aussi les résultats. Cependant, j'ai trouvé que la valeur du taux de change a un * si elle dépasse 7 caractères.

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

Les valeurs sont les suivantes:

 entrez la description de l'image ici

Comment obtenir la valeur totale sans aucune troncature?


0 commentaires

4 Réponses :


3
votes

Vous venez de rencontrer la pire limitation de RFC_READ_TABLE .

Son erreur est de renvoyer des valeurs de champ basées sur la longueur interne et de tronquer le reste, plutôt que d'utiliser la longueur de sortie. TCURR-UKURS est un champ BCD décimal compressé de longueur 9,5 (9 octets = 17 chiffres, dont 5 chiffres après la virgule décimale) et une longueur de sortie de 12. Malheureusement, RFC_READ_TABLE affiche le résultat sur 9 caractères, donc une valeur de 105.48000- prend 10 caractères est trop longue, donc la logique par défaut ABAP est de définir le * < / code> caractère de débordement sur le caractère le plus à gauche ( * 5.48000- ).

Soit vous créez un autre module fonction RFC côté SAP / ABAP, soit vous accédez directement à la base de données SAP (SGBDR classique connecté au serveur SAP).


1 commentaires

d'autres fonctions pour lire ces taux de change? Je n'ai pas accès à la fonction SAP / ABAP, je programme à partir de .NET pour les utiliser en utilisant le connecteur comme mentionné dans la question. Franckly parlant, je suis nouveau dans ces domaines. Merci d'avance!



2
votes

Juste un ajout à l'explication parfaite de Sandra sur ce problème. Oui, la seule solution ici serait d'écrire un module personnalisé pour récupérer les enregistrements distants.

Si vous ne voulez pas le réécrire à partir de zéro, la solution la plus simple serait de copier RFC_READ_TABLE dans le module Z et remplacez la ligne 137

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

par

FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-OUTPUTLEN.

Cela résout le problème.

MISE À JOUR : essayez BAPI_EXCHANGERATE_GETDETAIL BAPI, il est compatible RFC et lit correctement les taux. L'interface est assez explicite, la seule différence est que la date doit être au format natif et non inversé:

FIELDS_INT-LENGTH_DST = TABLE_STRUCTURE-LENG.


5 commentaires

Merci pour votre réponse, mais je n'ai pas accès aux fonctions SAP. J'utilise .NET pour les consommer. Avez-vous un autre moyen d'accéder aux taux de change pour des dates spécifiées?


L'exposition des taux de change via les services Web est un moyen très courant, mais cela nécessite également accès au système SAP


Ce BAPI doit être appelé pour chaque devise? y a-t-il un moyen d'obtenir la liste complète pour une date?


Pour célibataire. La date est un paramètre obligatoire qui n'accepte que des valeurs uniques, vous ne pouvez donc pas récupérer un lot de taux de change pour différentes dates, un par un.


y a-t-il un moyen d'obtenir la liste complète pour une date? Je suppose que non. Sans configurations supplémentaires du côté SAP, la réponse est non.



0
votes

Voici l'exemple de code utilisé avec le connecteur SAP pour .NET, que ce soit utile pour quelqu'un qui recherche le même. Merci à tous ceux qui ont aidé.

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


0 commentaires

1
votes

Utilisez BBP_RFC_READ_TABLE. Ce n'est toujours pas le meilleur, mais il fait une chose que RFC_READ_TABLE n'a pas fait: un octet supplémentaire pour le signe décimal.

Pas besoin de passer par toutes les épreuves si vous ne cherchez qu'à corriger le problème décimal.


0 commentaires