viernes, 24 de enero de 2014

Consumir servicio web TRM para Colombia - Banco de la República

En la página http://www.banrep.gov.co/es/trm se encuentra diariamente la TRM, referencia para diferentes movimientos comerciales en moneda USD. A continuación, un ejemplo de como consumir el servicio web público del Banco para obtener la TRM desde un programa, en este caso en C#.

El primer paso es agregar la referencia web al proyecto en Visual. En este caso específico es: http://obiee.banrep.gov.co/analytics/saw.dll?wsdl

Luego viene el código para leer el reporte específico:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Data.SqlClient;
using System.Configuration;
using TRM_BanRep.banrep;
using System.Data;

namespace TRM_BanRep
{
 class Program
    {
        /// 
        /// Based on Obiee Web Services – Using .net and C# post on http://tipsonobiee.blogspot.com/2009/07/obiee-web-services-using-net-and-c.html
        /// 
        /// 
        static void Main(string[] args)
        {
   //Open SAW session in OracleBI - Banco de la Republica
   SAWSessionServiceSoapClient sawSession = new SAWSessionServiceSoapClient();
   string sessionID = sawSession.logon("publico", "publico");
   
   //Set report parameters
   ReportRef repRef = new ReportRef();
   //path: get from report http url
   repRef.reportPath = @"/shared/Consulta Series Estadisticas desde Excel/1. Tasa de Cambio Peso Colombiano"
    + "/1.1 TRM - Disponible desde el 27 de noviembre de 1991/TRM para un dia";
   //xml: get from report http url + &format=xml
   repRef.reportXml = ""
    + ""
    + ""
    + "";

   //Create xml view, set xml options
   XmlViewServiceSoapClient xmlView = new XmlViewServiceSoapClient();
   XMLQueryExecutionOptions xmlOpts = new XMLQueryExecutionOptions();
   xmlOpts.maxRowsPerPage = 100;
   xmlOpts.refresh = true;

   //Pass report parameters
   ReportParams repParams = new ReportParams();

   //Execute XML Query
   QueryResults qResults = xmlView.executeXMLQuery(repRef, XMLQueryOutputFormat.SAWRowsetData, xmlOpts, repParams, sessionID);

   //Print rowset
   sawSession.logoff(sessionID);

   //Get rate value from result XML
   XmlDocument results = new XmlDocument();
   results.LoadXml(qResults.rowset);

   DateTime trmDate = DateTime.Today.AddDays(-5);
   XmlNodeList xnlDate = results.GetElementsByTagName("Column0");
   foreach (XmlNode xn in xnlDate)
    trmDate = DateTime.ParseExact(xn.InnerText, "dddd d 'de' MMMM 'de' yyyy", CultureInfo.CreateSpecificCulture("es-CO"));

   decimal trm = decimal.Zero;
   XmlNodeList xnlRate = results.GetElementsByTagName("Column2");
   foreach (XmlNode xn in xnlRate)
    trm = Convert.ToDecimal(xn.InnerText, CultureInfo.InvariantCulture);

        }
    }
}


Nota: La URL del reporte mencionada en los comentarios se obtiene del código fuente de la página.

40 comentarios:

  1. Buenas tardes, muchas gracias por este aporte, precisamente andaba buscando la forma de obtener este dato. Tengo una duda, no sé si puedas ayudarme: necesito obtener la TRM e insertarla en una tabla; esto lo hago con un servicio windows que se debe ejecutar en las noches, pero cuando intento agregar la referencia web que indicas obtengo el sgte error: "Operación no válida dado el estado actual del objeto"; la URL en el navegador no muestra los métodos que ofrece el servicio... no sé si me puedas guiar ya que es la primera vez que intento usar servicios web desde mis aplicaciones. De antemano muchas gracias!

    ResponderEliminar
    Respuestas
    1. Hola, ¿qué URL estás usando? Esta: http://obiee.banrep.gov.co/analytics/saw.dll?wsdl si muestra los métodos.

      Eliminar
    2. Alquien ha hecho esta implentación en PHP? Agradezco si tienen información al respecto.

      Eliminar
    3. Puedes descargar mi código de GitHub:

      https://github.com/garrapato/TRM

      Espero les sirva, y si gustan pueden dejar su donativo en: http://Garrapato.com

      Eliminar
  2. Hola David, en java no has hecho la implementacion?.

    ResponderEliminar
    Respuestas
    1. mmm, para la implementación, debes usar un comando, wsimport, el cual está en la jdk. luego de eso, te aparecerán las clases java que te facilitarán el trabajo.
      link: http://tiny.cc/k3nq4x

      Eliminar
  3. Si están interesados en la implementación en PHP, envíenme un mensaje a mi correo:

    garrapato @ gmail . com

    ResponderEliminar
  4. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  5. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  6. buen día, tienes algun ejemplo de como implementarlo en Java, o de como consumir el servicio desde programas como SoapUI

    ResponderEliminar
  7. Buenas tardes, requiero un WS que me retorne la TRM de colombia , todo esto sobre una aplicacion winform.. tendrian algun ejemplo ? . agradezco su colaboración

    ResponderEliminar
  8. Buenas tardes, requiero un WS que me retorne la TRM de colombia , todo esto sobre una aplicacion winform.. tendrian algun ejemplo ? . agradezco su colaboración

    ResponderEliminar
  9. Para los que necesiten en java la implementación...
    En eclipse escogen la opción File->New->Web Service Client
    agregan la ruta del wsdl, si les aparece un mensaje de error no importa, solo lo cierran y si revisan las clases que les crearon solo deben cambiar las rutas de los import, en donde encuentren un (/) cambiarlo por (.). Esto se puede hacer facil con la herramienta de eclipse find & replace.
    Después crean una clase nueva y agregan el siguiente código, y vualá la tasa de cambio TRM...

    package test.tasacambio;

    import java.io.StringReader;
    import java.text.ParseException;

    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;

    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.InputSource;

    import web.soap.v5.analytics.siebel.com.QueryResults;
    import web.soap.v5.analytics.siebel.com.ReportParams;
    import web.soap.v5.analytics.siebel.com.ReportRef;
    import web.soap.v5.analytics.siebel.com.SAWSessionService;
    import web.soap.v5.analytics.siebel.com.SAWSessionServiceLocator;
    import web.soap.v5.analytics.siebel.com.SAWSessionServiceSoap;
    import web.soap.v5.analytics.siebel.com.XMLQueryExecutionOptions;
    import web.soap.v5.analytics.siebel.com.XMLQueryOutputFormat;
    import web.soap.v5.analytics.siebel.com.XmlViewService;
    import web.soap.v5.analytics.siebel.com.XmlViewServiceLocator;
    import web.soap.v5.analytics.siebel.com.XmlViewServiceSoap;

    public class trmBancoRepublica {

    public static void main(String[] args) throws ParseException {
    getTrmFromBanRep();
    }

    public static void getTrmFromBanRep() {
    try {
    SAWSessionService sawSessionService = new SAWSessionServiceLocator();
    SAWSessionServiceSoap serviceLogon = sawSessionService.getSAWSessionServiceSoap();
    String sessionID = serviceLogon.logon("publico", "publico");

    ReportRef repRef = new ReportRef();
    repRef.setReportPath("/shared/Consulta Series Estadisticas desde Excel/1. Tasa de Cambio Peso Colombiano/1.1 TRM - Disponible desde el 27 de noviembre de 1991/TRM para un dia");
    repRef.setReportXml("");

    XmlViewService xmlViewService = new XmlViewServiceLocator();
    XmlViewServiceSoap serviceXMLQuery = xmlViewService.getXmlViewServiceSoap();
    XMLQueryExecutionOptions xmlOpts = new XMLQueryExecutionOptions();
    xmlOpts.setMaxRowsPerPage(100);
    xmlOpts.setRefresh(true);
    ReportParams repParams = new ReportParams();

    // Execute XML Query
    QueryResults qResults = serviceXMLQuery.executeXMLQuery(repRef, XMLQueryOutputFormat.SAWRowsetData,
    xmlOpts, repParams, sessionID);
    // Print rowset
    serviceLogon.logoff(sessionID);

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();

    InputSource archivo = new InputSource();
    archivo.setCharacterStream(new StringReader(qResults.getRowset()));

    Document documento = db.parse(archivo);
    documento.getDocumentElement().normalize();

    NodeList nodeLista = documento.getElementsByTagName("Column0");
    for (int s = 0; s < nodeLista.getLength(); s++) {
    Node primerNodo = nodeLista.item(s);
    System.out.println(primerNodo.toString());
    System.out.println(primerNodo.getTextContent());
    }
    nodeLista = documento.getElementsByTagName("Column2");
    for (int s = 0; s < nodeLista.getLength(); s++) {
    Node primerNodo = nodeLista.item(s);
    System.out.println(primerNodo.toString());
    System.out.println(primerNodo.getTextContent());
    }
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    }
    }

    ResponderEliminar
    Respuestas
    1. Hola,

      Tener ciudado al corregir los import/package por "com.siebel.analytics.web.soap.v5" y NO modificar los namespace.

      Los namespace definidos en las clases se debe mantener "com.siebel.analytics.web/soap/v5".

      Saludos

      Eliminar
    2. Amigos no tendran esta implemetacion correcta sin todos los errores que arroja al crear el web services client en java?

      Eliminar
  10. no me sirvió, me saca error de que no encontró el nombre remoto 'obiee.banrep.gov.co'

    ResponderEliminar
  11. Quienes trabaje con PHP a qui esta la respuesta en este Hilo http://www.forosdelweb.com/f18/como-traducir-este-consumo-php-1107099/

    ResponderEliminar
  12. Para quien lo necesite el mismo código pero en VB.net

    Imports System
    Imports System.Collections.Generic
    Imports System.Globalization
    Imports System.Linq
    Imports System.Text
    Imports System.Threading.Tasks
    Imports System.Xml
    Imports System.Data.SqlClient
    Imports System.Configuration
    Imports System.Data

    Public Class Form1



    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Dim sawSession As New TrmBancoRepublica.SAWSessionService
    Dim repRef As New TrmBancoRepublica.ReportRef
    Dim sessionID = sawSession.logon("publico", "publico")
    Try

    repRef.reportPath = "/shared/Consulta Series Estadisticas desde Excel/1. Tasa de Cambio Peso Colombiano"
    repRef.reportPath += "/1.1 TRM - Disponible desde el 27 de noviembre de 1991/TRM para un dia"
    'xml: get from report http url + &format=xml


    repRef.reportXml = ""
    repRef.reportXml = repRef.reportXml + ""
    repRef.reportXml = repRef.reportXml + ""
    repRef.reportXml = repRef.reportXml + ""


    'Create xml view, set xml options
    Dim xmlView As New TrmBancoRepublica.XmlViewService
    Dim xmlOpts As New TrmBancoRepublica.XMLQueryExecutionOptions
    Dim repParams As New TrmBancoRepublica.ReportParams
    Dim qResults = xmlView.executeXMLQuery(repRef, TrmBancoRepublica.XMLQueryOutputFormat.SAWRowsetData, xmlOpts, repParams, sessionID)
    sawSession.logoff(sessionID)
    Dim results As New XmlDocument
    results.LoadXml(qResults.rowset)
    Dim trmDate As DateTime = DateTime.Today.AddDays(-5)
    Dim xnlDate As XmlNodeList = results.GetElementsByTagName("Column0")
    For Each xn As XmlNode In xnlDate
    trmDate = DateTime.ParseExact(xn.InnerText, "dddd d 'de' MMMM 'de' yyyy", CultureInfo.CreateSpecificCulture("es-CO"))
    Next
    Dim trm As Decimal = Decimal.Zero
    Dim xnlRate As XmlNodeList = results.GetElementsByTagName("Column2")
    For Each xn As XmlNode In xnlRate
    trm = Convert.ToDecimal(xn.InnerText, CultureInfo.InvariantCulture)
    Next
    MsgBox(trm)
    Catch ex As Exception
    MsgBox(ex.Message)
    End Try

    End Sub
    End Class

    ResponderEliminar
  13. Como puedo ver el catalogo de paths disponibles para descargar información? ya obtuve la TRM del path "/shared/Consulta Series Estadisticas desde Excel/1. Tasa de Cambio Peso Colombiano/1.1 TRM - Disponible desde el 27 de noviembre de 1991/TRM para un dia", pero me gustaría traer información de otras monedas y esta esta en http://obieebr.banrep.gov.co/analytics/saw.dll?PortalGo&Action=prompt&path=%2Fshared%2FSeries%20Estad%C3%ADsticas%2F1.%20Monedas%20disponibles%2F1.1.TCM_Datos%20diarios, traté con el Path "/shared/Consulta Series Estadisticas desde Excel/1. Monedas disponibles/1.1.TCM_Datos diarios" pero no esta dispnible.

    ResponderEliminar
    Respuestas
    1. También intenté con "/shared/Series Estadísticas/1. Monedas disponibles/1.1.TCM_Datos diarios" que es la que se utiliza para cargar la página en el banco de la república http://obieebr.banrep.gov.co/analytics/saw.dll?Go&path=/shared/Series Estad%c3%adsticas/1. Tasa de Cambio Peso Colombiano/1.1 TRM - Disponible desde el 27 de noviembre de 1991/1.1.6.TCM_TRM para un d%C3%ADa&lang=es&options=rdf&NQUser=publico&NQPassword=publico, pero sigue sin establecer conexión

      Eliminar
  14. Gracias por compartir el codigo, sin embargo tengo un problema al agregar la referencia del servicio y con el using TRM_BanRep.banrep;, ya que al hacerlo me genera un error con repRef.reportPath ya que indica que hay una ambiguedad entre TRM_BanRep.banrep.repRef.reportPath y TRM_BanRep.banrep.repRef.reportPath. Al parecer son iguales pero no se que hacer. Te agradezco cualquier ayuda

    ResponderEliminar
    Respuestas
    1. A mi me ocurre eso mismo y no lo he podido solucionar... Gracias por sus aportes.

      Eliminar
  15. hola!
    ¿donde puedo ver yo las URL disponible para "reportPath"?
    intenté usar una de la página y no me sirvio...
    Gracias de antemano!

    ResponderEliminar
  16. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  17. Hola! acá pueden explorar los reportes disponibles: http://obieebr.banrep.gov.co/analytics/saw.dll?catalog#%7B%22location%22%3A%22%2Fshared%2FSeries%20Estad%C3%ADsticas%22%7D En cada reporte en la opción de "más" > "propiedades" pueden ver la ruta. Recuerden actualizar la url de obiee a obieebr

    ResponderEliminar
  18. Saludos, Gracias a david335, me funcionó perfecto.

    ResponderEliminar
  19. http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate?FromCurrency=COP&ToCurrency=USD

    ResponderEliminar
  20. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  21. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  22. El Banco de la República ha cambiado sus servicios, por lo cual me requirió cambiar el mecanismo para obtener la TRM diariamente.

    Dejo a su disposición nuestro servicio web gratuito para que obtenga la TRM del día en formato JSON.

    http://www.innovatecsa.com/page/servicios-gratuitos

    Cualquier duda o comentario nos pueden escribir al correo gerencia@innovatecsa.com

    ResponderEliminar
  23. hola muchos de los url de este blog no funcionan http://obiee.banrep.gov.co/analytics/saw.dll?wsdl ni http://www.innovatecsa.com/page/servicios-gratuitos

    ResponderEliminar
  24. Este ahora es el oficial y funciona
    https://www.superfinanciera.gov.co/SuperfinancieraWebServiceTRM/TCRMServicesWebService/TCRMServicesWebService?WSDL

    ResponderEliminar
    Respuestas
    1. Tampoco esta funcionando, yo lo venia consumiendo y ahora arroja error y no he tenido respuesta de la superfinanciera sobre los cambios para realizar el ajuste y poder obtener la trm

      Eliminar
    2. Buenas tardes, sabes si ya funciona el Web Service de la super?, la verdad yo hace mucho lo usaba y a finales de septiembre dejo de funcionar.

      Eliminar
  25. El servicio web de Banrep sigue funcionando. Solo que el sitio web, el usuario/password, y la ruta (del reporte) y el namespace XML son diferentes. Hay que estar revisando esto y cambiarlo si es necesario.

    El último sitio web es: https://totoro.banrep.gov.co/analytics/saw.dll?wsdl

    Para que funcione este código en .NET 5:
    Namespace ServiceReference > next
    check Always Generate message contracts, Reuse types in referenced assemblies, Reuse types in all referenced assemblies > next
    check Access level for generated classes Public, Generate Synchronous Operations > Finish

    ResponderEliminar
  26. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  27. using System;
    using System.Linq;
    using System.Xml.Linq;
    using System.Collections.Generic;
    using ServiceReference;

    namespace TestSVBanrep
    {
    class Program
    {
    ///
    /// Based on Obiee Web Services – Using .net and C# post on http://tipsonobiee.blogspot.com/2009/07/obiee-web-services-using-net-and-c.html
    ///
    static void Main(string[] args)
    {

    //Open SAW session in OracleBI - Banco de la Republica
    SAWSessionServiceSoapClient sawSession = new SAWSessionServiceSoapClient();
    logonRequest r = new logonRequest("publico", "publico123");
    logonResponse sessionID = sawSession.logon(r);

    //Set report parameters
    ReportRef repRef = new ReportRef();

    //path: get from report http url
    // / shared / Series Estadísticas_T / 1.Tasa de Cambio Peso Colombiano/ 1.1 TRM - Disponible desde el 27 de noviembre de 1991 / 1.1.2.TCM_Para rango de fechas dado
    repRef.reportPath = @"/shared/Series Estadísticas_T/1. Tasa de Cambio Peso Colombiano"
    + "/1.1 TRM - Disponible desde el 27 de noviembre de 1991/1.1.2.TCM_Para rango de fechas dado";

    //xml: get from report http url + &format=xml
    repRef.reportXml = ""
    + ""
    + ""
    + "";

    //Create xml view, set xml options
    XmlViewServiceSoapClient xmlView = new XmlViewServiceSoapClient();
    XMLQueryExecutionOptions xmlOpts = new XMLQueryExecutionOptions();
    xmlOpts.maxRowsPerPage = 100;
    xmlOpts.refresh = true;

    //Pass report parameters
    ReportParams repParams = new ReportParams();

    //Execute XML Query
    executeXMLQueryRequest rq = new executeXMLQueryRequest(repRef, XMLQueryOutputFormat.SAWRowsetData, xmlOpts, repParams, sessionID.sessionID);
    executeXMLQueryResponse qResults = xmlView.executeXMLQuery(rq);

    //Logoff
    logoffRequest lreq = new logoffRequest(sessionID.sessionID);
    sawSession.logoff(lreq);

    //Set the XML doc in an XElement
    XElement root = XElement.Parse(qResults.@return.rowset);

    //Without the Namespace this query is not possible
    XNamespace ns = "urn:schemas-microsoft-com:xml-analysis:rowset";

    //Use LINQ to find the rate for the date
    string trmDate = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd");
    IEnumerable rt =
    from el in root.Descendants(ns + "Row")
    where (string)el.Element(ns + "Column1") == trmDate
    select el;

    //Print rate
    foreach (XElement el in rt)
    Console.WriteLine("Fecha: " + trmDate + " TRM: " + (string)el.Element(ns + "Column2"));
    }
    }
    }

    ResponderEliminar
  28. repRef.reportXml no se deja pegar, lo toman del código original y cambian doble comilla slash por doble comilla doble comilla.

    Saludos!

    ResponderEliminar
  29. buena tarde alguien tiene el consumo de este servicio para SOAPUI

    ResponderEliminar