Page 1 of 1

Acceder a Excel sin tener Excel instalado...

Posted: Fri Apr 10, 2020 5:47 pm
by xmanuel
Hace un par de días mi gran amigo Félix me hizo esa pregunta...
Mi respuesta fue: Con HDO claro, lo voy a probar.
Y efectivamente se puede acceder a Excel con HDO sin tener el Excel instalado.
Un fichero XLS es una base de datos y cada hoja una tabla.

:D

Re: Acceder a Excel sin tener Excel instalado...

Posted: Fri Apr 10, 2020 5:59 pm
by cnavarro
Muy bien Manu
Pero si es un xlsx, al fin y al cabo es un fichero comprimido ( como si fuese un zip ) y dentro contiene todos las hojas en formatos xml, por lo que se puede acceder a ellas con las funciones que harbour nos ofrece para el uso de este tipo de ficheros.

Re: Acceder a Excel sin tener Excel instalado...

Posted: Fri Apr 10, 2020 9:16 pm
by xmanuel
Seguro.

Esta es una manera más :D

HDO soporta *.xls, *.xlsx, *.xlsm, *.xlsb que es lo que soporta el ODBC de MS para su drive.

Re: Acceder a Excel sin tener Excel instalado...

Posted: Sat Apr 11, 2020 7:15 am
by joseluispalma
¿Tiene ya el RDD acabado?

Re: Acceder a Excel sin tener Excel instalado...

Posted: Sat Apr 11, 2020 3:03 pm
by xmanuel
La RDD esta al 78 %

Re: Acceder a Excel sin tener Excel instalado...

Posted: Sat Apr 11, 2020 3:44 pm
by joseluispalma
Nosotros usamos con éxito desde hace más de 10 años TDolphin.

Pero el RDD sería estupendo para poder rescatar algunos programas que usan ADS, pero que no compensa reescribirlos con TDolphin o tu clase.

A ver si te animas a completarlo.

Re: Acceder a Excel sin tener Excel instalado...

Posted: Sun Apr 12, 2020 1:53 pm
by xmanuel
Ejemplo de como recorrer una hoja de cálculos rescatando los valores.
En este caso tiene dos columnas con nombres de ficheros, la primera el actual y la segunda al que hay que renombrar.

Code: Select all

//------------------------------------------------------------------------------

#include "hdo.ch"

REQUEST RDLODBCN

//------------------------------------------------------------------------------
// Programa principal

procedure main

    local oApp

    oApp := TApp():new( "Cambio nombres.xlsx", "Hoja1" )

    oApp:run()
    oApp:end()

return

//------------------------------------------------------------------------------
// Clase aplicacion

CLASS TApp

    DATA oXLS
    DATA oSheet

    METHOD new( cXLS, cSheet ) CONSTRUCTOR
    METHOD run()
    METHOD end()
    METHOD imprime( cTxt )

ENDCLASS

//------------------------------------------------------------------------------
// Constructor de la clase

METHOD new( cXLS, cSheet ) CLASS TApp

    local e

    if ValType( cXLS ) == 'C' .and. File( cXLS )
        cXLS := AllTrim( cXLS )
        // Creamos el objeto XLS
        ::oXLS := THDO():new( "odbcn" )
        // Uso de try catch
        try
            // Intenta crear los objetos XLS y hoja
            ::oXLS:connect( "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=./" + cXLS + ";" )
            ::oSheet := ::oXLS:query( "SELECT * FROM " + "[" + AllTrim( cSheet ) + "$]" )
        catch e
            // Gestion del error aqui uso el estandar de harbour
            eval( errorBlock(), e )
            // Cierre automatico en caso de error
            ::end()
        end
    else
        msg( "No se ha pasado un fichero excel" )
    endif

return Self

//------------------------------------------------------------------------------
// Corre la aplicacion. Proceso principal

PROCEDURE run() CLASS TApp

    local cOldFile, cNewFile, cResult

    if ValType( ::oSheet ) == 'O'
        while ::oSheet:fetchDirect()
            cOldFile := ::oSheet:fetchColumn( 1 )
            cNewFile := ::oSheet:fetchColumn( 2 )
            cResult :=  "Renombrando: " + cOldFile + " -> " + cNewFile + " ### "
            if File( cOldFile )
                cResult += IF( FRename( cOldFile, cNewFile ) == 0, "OK", "ERROR: No se pudo renombrar" )
            else
                cResult += "ERROR: Fichero no encontrado"
            endif
            ::imprime( cResult )
        end
    endif

    ::imprime( Replicate( "-", MaxCol() ) )
    ::imprime( "Preceso terminado" )
    espera()

return

//------------------------------------------------------------------------------
// Imprime en pantalla algo
// Adaptalo para FWH o  escribe un fichero log para saber como ha ido el tema

PROCEDURE imprime( cTxt ) CLASS TApp

    ? cTxt

return

//------------------------------------------------------------------------------
// Libera recursos

PROCEDURE end() CLASS TApp

    //libera los objetos en orden inverso a su creacion

    if ValType( ::oSheet ) == 'O'
        ::oSheet:free()
    endif

    if ValType( ::oXLS ) == 'O'
        ::oXLS:free()
    endif

return

//------------------------------------------------------------------------------

 

Re: Acceder a Excel sin tener Excel instalado...

Posted: Sun Apr 12, 2020 1:58 pm
by xmanuel
José Luis me encantaría que pudieras usar HDO.
Podrías hacer comparativas.
Por otro lado, con HDO tendrías la posibilidad de usar cualquier gestor de bases de datos prácticamente sin cambiar tu PRG.
Además de la seguridad, velocidad con las sentencias preparadas en el lado del servidor tendrías la posibilidad no sólo de usar MySQL.
También tendrías a tu disposición SQLite, SQLServer, Postgres, etc ese es gran matiz que diferencia a HDO de Eagle1 o TDolphin por ejemplo...

Re: Acceder a Excel sin tener Excel instalado...

Posted: Sun Apr 12, 2020 2:35 pm
by joseluispalma
Muchas gracias Manuel. Te agradezco el ofrecimiento, pero no le veo ninguna utilidad. Como prueba de concepto, es interesante lo que has desarrollado, pero al cliente no le interesa elegir entre MySQL, SQLite o Postgres. Hipotéticamente sí con MSQServer de Microsoft, pero en Azure también soportan MySQL. Al cliente le interesan nuevas opciones en el producto, y nota mucho _ estéticos.

Y hoy en día, con el hardware disponible, los eventuales segundos de rapidez frente a TDolphin son insignificantes. La clase de Daniel es muy estable, tiene todo su código fuente disponible y es usada por miles de usuarios en todo el mundo. Ese ahorro no justifica comercialmente para nada lo que supone invertir horas en modificar el código y testear un producto usado por un grupo reducido de usuarios.

En cambio, como te decía, si completaras el SQLRDD sería interesante para rescatar las aplicaciones que tenemos bajo ADS, e incluso las que tienen otros colegas en el foro en dbf pero que no les compensa la inversión de cambios en el código fuente.