R Project for Statistical Computing + .net + BI

Que pasa cuando tenemos que agregar lógica matemática a nuestros proyectos? especialmente de BI? pues muchas veces vamos por ayuda a MatLab, pero cuando a veces nos damos cuenta del costo preferimos ir por algún software libre, como es el caso de R (http://www.r-project.org/), éste un potente motor que nos puede ayudar a hacer muchas operaciones matemáticas financieras, el objetivo de este post no es explicar las formulas matemáticas expuestas en R, sino ver como podemos colocarlo en nuestra solución.

Para empezar debes descargar la versión de R de la pagina oficial. Luego debemos descargar un conector R COM+ (RSrv250_pl1.exe –> http://sunsite.univie.ac.at/rcom/download/current/RSrv250_pl1.exe), que expone a R como un conjunto de objetos para poder programarlo (y acá va todo el floro de lo que es COM+ y como se puede utilizar en .net).

He tenido mucho pasado en .net y eso me ha ayudado a poder extender funcionalidades en Reporting Services, Integration Services y etcs…. y eso me ha ayudado a agregar R en el proyecto de BI.

Bueno ahora si a código!!!, si eres primerizo en esto primero debes entrar a este link –> http://www.codeproject.com/KB/cs/RtoCSharp.aspx, se puede ver como se utiliza R con un ejemplo sencillo en .net

Si ya estas en algo con todo esto debes entrar a ejemplos mas avanzado -> http://joachimvandenbogaert.wordpress.com/2009/03/26/r-and-c-on-windows/ ;http://joachimvandenbogaert.wordpress.com/2009/02/20/rcom-and-c-safearraytypemismatchexception/

Ya una vez que estas con ese nivel pues llegas a este párrafo :p jejejeje, la realidad te dice que no tienes tiempo de programar dos veces, una en R y otro en .net para que se acople, entonces la idea seria tener un generador que lee archivos en R sea cual fuera lo que hace y te devuelva un resultado y finalmente eso es lo que es:

public object EjecutarR(DataTable datos, string rutaR)
{
  object o1 = null;
  if (datos.Rows.Count > 1)
   {
    try
     {
      StatConnector sc1 = new StatConnectorClass();
       sc1.Init(«R»);

        StringBuilder valoresFilas;
        StringBuilder valoresColumnas = new StringBuilder();
        //Llenar Datos
        int i, j;
        for (i = 0; i < datos.Columns.Count; i++)
        {
         valoresFilas = new StringBuilder();

         for (j = 0; j < datos.Rows.Count; j++)
         {
          if (datos.Columns[i].DataType.Name == «String»)
           valoresFilas.Append(«»»);
          if (datos.Rows[j][i].GetType() == Type.GetType(«System.DBNull»))
           valoresFilas.Append(«0»);
          else
           valoresFilas.Append(datos.Rows[j][i].ToString());
          if (datos.Columns[i].DataType.Name == «String»)
           valoresFilas.Append(«»»);
           valoresFilas.Append(«,»);
          }

          sc1.EvaluateNoReturn(datos.Columns[i].ColumnName + » <- c(» +
          valoresFilas.ToString().Substring(0, valoresFilas.ToString().Length – 1) + «)»);

          valoresColumnas.Append(datos.Columns[i].ColumnName);
          valoresColumnas.Append(«,»);
         }

         sc1.EvaluateNoReturn(«dat <- data.frame(» +
         valoresColumnas.ToString().Substring(0, valoresColumnas.ToString().Length – 1) + «)»);

         sc1.SetSymbol(«archivo», rutaR);

         sc1.EvaluateNoReturn(«source(archivo)»);
         o1 = sc1.GetSymbol(«Resultados»);
         sc1.Close();
         Utilitarios.Funciones.NAR(sc1);
         GC.Collect();
         GC.WaitForPendingFinalizers();
         }
         catch (Exception ex)
         {
          if (ExceptionPolicy.HandleException(ex, ErrPolicy.Business))
           throw;
          }
         }

 

El código que se encuentra en otro color indica lo que utilizamos de R. Para explicarlo un poco, les cuento que este código me permite en base a un datatable meter cualquier valor a R, y que lo lea como una matriz (en realidad lleno vectores y creo un dataframe con esos), con ese input llamo a R y leo un archivo (que lo paso por parámetro) en ese archivo se tiene el algoritmo de R y dicho algoritmo debe asignar a la variable Resultado lo que necesito traer a .net

Este script me permite leer cualquier archivo de R sin necesidad de cambiar una línea de código, me permite meter cualquier valor de .net (siempre y cuando este en un datatable) y leerlo en R.

Otra solución seria llamar por ODBC a SQL desde R pero no esa opción desde el punto de vista de arquitectura no me agrada. Es mejor que pase por tu capa de datos (Entity Framework)

Este codigo lo colocamos en un servicio .net y lo podemos llamar desde Integration Services 2008 (que ya permite tener referencias web) y con esto podemos poblar cubos, o transformar datos.

Espero lo hayan entendido 🙂

SQL 2005 –> SQL 2008: Lo que debo tener en cuenta en mi próxima migración

Una semana muy entretenida que termino con una cereza en el pastel… una migración que no fue tan sencillo como me fue de SQL 200 a 2005. A veces sentimos que planificamos todo realmente bien (técnicamente hablando), pero no siempre tenemos buenos resultados, a raíz de esto, con los temas ya solucionados, decidí escribir mi experiencia en esta migración.

La migración que lleve a cabo incluía a las Base de Datos que estaban en SQL 2005, paquetes de Integration Services 2005 y reportes en Reporting Services 2005, en cuanto a Analisys Services ya no tuve que hacerlo porque el proyecto ya lo tengo en la nueva versión (ya no tan nueva que digamos).

1.- Base de Datos

Como ya lo hemos visto en versiones anteriores SQL2008 también tiene una herramienta que da un “check” a nuestra configuración y componentes necesarios (tanto hardware como software)

check Upgrade

 

El System Configuration Checker identifica los componentes instalados y el hardware que tenemos.

El install Upgrade Advisor te instala un programita que te ayudara a verificar las compatibilidades de tu BD para ser el upgrade a 2008

image

 

y con un sencillo wizard te ayuda a identificar los posibles problemas en tu migración, lo bueno de esta herramienta es que te analiza todos los componentes de SQL no solo la BD sino también reportes, paquetes de SSIS, hasta DTS de la versión 2000 y por supuesto proyectos de Analisys Services de versiones anteriores. FInalmente me manda un reporte como este:

image

Y como buen apurado que soy no me di cuenta de un warning muy importa del cambio de la versión del SQLClient, que en la parte de SSIS les explicare el gran problema que tuve. (por cierto también me recomendó el usar las nuevas capacidad de SSIS en cuanto a lookup que seguro en otro post lo explicaré.), también me menciona casos del full text index, de los cambios realizados, pero como deje de usar esa característica, lo deje 🙂

si desean mas datos (realmente es sencillo el uso) aca les dejo unos links:

Bueno una vez que vemos que en la BD no hay mas problemas, entonces vamos al siguiente paso que es un poco mas interesante SSIS.

2.- Integration Services

En esta parte realmente el problema no fue en la instalación, sino en hacer que mis paquetes hechos en SQL2005 funcionen. Como vimos en el Upgrade Advisor ya debí de haberme dado cuenta que tenia un problema con la versión del SQLCliente para mis conexiones OLEDB de mis paquetes, pero no fue el único problema.

Una vez hecho el upgrade y queriendo ejecutar un paquete (ya convertido a SSIS 2008) me mostró el siguiente error: (la ejecución fue “dtexec.exe /f D:JOGASyncPrices.dtsx /CONFIGFILE D:JOGAnewConfigBase.dtsConfig”)

Error: 2009-07-12 16:33:11.44
Code: 0xC001700A
Source:  
Description: The version number in the package is not valid. The version number cannot be greater than current version number.
End Error

Busque solucionar este error de muchas formas, pensando que era el paquete el problema, analizando el xml, los archivos de configuración etc etc etc… y gracias a este foro –> http://social.msdn.microsoft.com/Forums/en-US/sqlintegrationservices/thread/744957ad-038a-46ba-aa70-0adab03a5f4d/ me indica que el problema es el DTEXEC, como deseo que se ejecute con el DTEXEC de SSIS 2008 debo colocar su ruta completa es decir: “C:Program FilesMicrosoft SQL Server100DTSBinndtexec.exe /f D:JOGASyncPrices.dtsx /CONFIGFILE D:JOGAnewConfigBase.dtsConfig”. Con ese pequeño cambio las cosas mejoraron pero no se solucionaron por completo, porque a la siguiente ejecucion me salio un warning que al inicio no le hacia caso pero era el culpable de que nos e ejecutara mis paquetes este fue:

Warning: 2009-07-12 16:30:29.55
Code: 0x80012011
Source: SynPrices 
Description: Cannot load the XML configuration file. The XML configuration file may be malformed or not valid.
End Warning

Como verán se ejecutaba mi paquete pero no se leía mi archivo de configuración, en el cual tengo mis conexiones a servidores de producción, entonces se ejecutaba el paquete y se cargaba todo en mi ambiente de pruebas. Esto si fue un poco mas tardado encontrar la solución, aplique la filosofía de mi master: “divide y vencerás” :p .. es decir deshice mi paquete, para que no se vea tan complejo y probar parte por parte y encontré el problema, era el archivo de configuración.

Resulta que en la versión anterior yo tenia un archivo de configuración para todos mis paquetes, en este archivo de configuración colocaba todas mis conexiones, y aunque no lo usara en el paquete funcionaba, pues en SSIS 2008 ya no funciona igual, si hay alguna conexión que no estas utilizando en el paquete (es decir que no este en el connection managers del paquete) te sale muestra ese warning. Entonces empecé a crear archivos de configuración para cada paquete (realmente generalice unos cuantos, ya que varios paquetes usaban las mismas conexiones) y con eso lo solucione.

Finalmente lo ultimo es cambiar el provider de SQL Native Client a SQL Server Native Client 10.0, con estos cambios ya empieza a funcionar todo normalmente, seguro esta semana estaré viendo algunas consecuencias de mi migración de SSIS y les estaré comentando. (con mi cnx de .net Providers no tuve ningún problema :p)

aca unos links de interes:

3.- Reporting Services

Con el upgrade a 2008, realmente no tuve grandes problemas, mis reportes funcionaron a no ser que tuve que hacer algunos arreglos en mi IIS.

Como sabrán con SQL2008 ya no es necesario tener IIS instalado en el server para utilizar SSRS, y en el upgrade lo que hizo automáticamente es habilitar el puerto 8081 para mis reportes (antes se encontraban en el puerto por defecto del IIS 8080).

Debes agregar los permisos necesarios y las credenciales necesarios, para no repetir todo esto seguimos el Upgrade WorkFlow que nos proporciona la documentación de Microsoft –> http://technet.microsoft.com/en-us/library/ms143747.aspx 

Fuera de esto el problema viene con los reportes que desarrollamos en SSRS2005, que es motivo para un post completo. En una próxima edición :p

Y con todo esto hoy día puedo decir que por fin funciono lo que tenia que funcionar :p

Espero les ayude en algo la experiencia que tuve 🙂 .. hasta la próxima

Programatic access to the Microsoft Office Visual…

Bueno, el post de hoy no es necesariamente de los temas que quisiera hablar, pero dada las circunstancias y el tiempo que me tomo encontrar la solución, quería compartir con uds. esto por si tienen el mismo problema.

Como saben estoy tratando de combinar tecnologías de Microsoft en mis soluciones, y ahora me toco meter a VSTO con vs2008 (porque recién tuve un requerimiento que tenia que ver con Excel directamente) y me tope con mi primer problema:

“Programatic access to the Microsoft Office Visual Basic for Applications project System could not be enabled”.

como bien lo dice el titulo (lo puse agrede para quienes lo busquen :p)
error1

Como sabrán también no me gusta mucho solucionar el tema por solucionar, siempre me gusta saber el porque.. y esa es la razón de este post…

Para empezar debemos tener en cuenta que Office esta construido en base a las tecnologías que Microsoft saco con COM+, es decir no es administrado (no .net), para que funcione VSTO el framework se comunica con los componentes de Office (en mi caso con el Excel Object Model 2007, si desean aprender mas de eso –> http://www.packtpub.com/article/microsoft-office-excel-programming-using-vsto) y así interactuar bajo .net (el tema es un poco mas complicado que esto pero no es el objetivo de este post).

Y como Uds. sabrán han habido muchos problemas para sus aplicaciones com+, yo lo tuve especialmente con el tema de compatibilidad (la bendita compatibilidad binaria!!!!), entonces por ahi fui con este tema.

Primero busque en la red y existen algunas soluciones como esta –> http://blogs.msdn.com/charles_sterling/archive/2007/02/21/programmatic-access-to-the-microsoft-office-visual-basic-for-applications-project-system-could-not-be-enabled.aspx , y no me funciono, luego instale service packs, reinstale visual studio, reinstale office y nada de nada….

Entonces busque algunos limpiadores (luego de instalar y desinstalar mucho en mi maquina) y encontré uno muy bueno que me sirvió para otras cosas :p pero igual les paso el dato: Windows Installer CleanUp Utility –> http://support.microsoft.com/default.aspx?scid=kb;en-us;290301

Bueno después de todo esto y verificar realmente mis ensamblados, me di cuenta que tenia ensamblados de office 2003!!!!, eso quiere decir que realmente había un problema de compatibilidad entre 2003 y 2007 con vsto de vs2008 (PIAs de Office)

Microsoft does not guarantee that the Office PIAs will be backwardly compatible or that the various versions of the Office PIAs can be run side-by-side in the same instance of an Office application. Office XP managed code add-ins must be built against the Office XP PIAs. The Office 2003 managed code add-ins must be built against the Office 2003 PIAs. The Office 2007 managed code add-ins must be built against the Office 2007 PIAs. Therefore, if you build an add-in solution that you intend to use with several versions of Office, Microsoft recommends that you build a version of your add-in for each version of Office that you intend to support.”

mas explicaciones y mejores que la mia :p –>

Conclusión –> Instale office 2003 y le hice upgrade a 2007, con ello se soluciono mi problema y ya estoy apunto de terminar otra parte de la solución 🙂 que seguro mas adelante les estaré comentando…

Hasta la próxima…