PDA

Ver la versión completa : Un poco de GeneXus...



Arielo
10/03/2008, 15:22
Bien... Para cambiar un poco el foro de programación, hoy les traigo una pequeña rutina en el lenguaje con el que trabajo todos los días: GeneXus

Esta rutina hace un append de una DBF.

Para esto, habrá que declarar las siguientes variables:
dbfFile - C(80)
DataView - C(80)
Linea - N(6)
&Msg - C(80)
Ok - C(1)
Tipo - C(3)

NOTA: C(80) significa que es una variable de tipo "Character", con una longitud de 80 bytes. Del mismo modo, N(6) significa que es una variable "Numeric" de 6 dígitos.

Esta rutina debe recibir los parms:
&dbfFile - &DataView - &Tipo

y devolverá un valor en &Ok

El código es el siguiente:



&Ok = 'S'

DBase CLOSE DATA

&Msg = 'Importando ' + &ArchivoDBF
Msg(&Msg, NoWait)

DBase ARCHIVO = '"'+[!&DataView!]+'.DBF"'

DBase IF .NOT. FILE(&Archivo)
&Ok = 'N'
&Msg = 'Archivo no encontrado: ' + &DataView
Msg(&msg)
Return
DBase ENDIF

DBase USE &ARCHIVO EXCL
DBase ZAP
DBase PACK

DBase ARCHIVO = '"'+[!&dbfFile!]+'"'

DBase IF .NOT. FILE(&Archivo)
&Ok = 'N'
&Msg = 'Archivo no encontrado ' + &dbfFile
Msg(&Msg)
Return
DBase ENDIF

If &Tipo = 'DBF'
DBase APPEND FROM &ARCHIVO
DBase CLOSE DATA
Else
DBase APPEND FROM &ARCHIVO SDF
DBase CLOSE DATA
EndIf


En el parámetro de salida &Ok, se encuentra el resultado de la operación.
Si fué exitosa, contendrá "S", de lo contrario, contendrá "N"

josell
10/03/2008, 15:27
INTERESANTE... no sabía que este lenguaje existiera... para que te es de utilidad? saludos.

Arielo
11/03/2008, 06:23
A mí, me sirve para ganarme la vida.
A la empresa para la cual programo, para cubrir todas sus necesidades de software.

jak_uy
23/06/2009, 10:14
Bien... Para cambiar un poco el foro de programación, hoy les traigo una pequeña rutina en el lenguaje con el que trabajo todos los días: GeneXus

Esta rutina hace un append de una DBF.

Para esto, habrá que declarar las siguientes variables:
dbfFile - C(80)
DataView - C(80)
Linea - N(6)
&Msg - C(80)
Ok - C(1)
Tipo - C(3)

NOTA: C(80) significa que es una variable de tipo "Character", con una longitud de 80 bytes. Del mismo modo, N(6) significa que es una variable "Numeric" de 6 dígitos.

Esta rutina debe recibir los parms:
&dbfFile - &DataView - &Tipo

y devolverá un valor en &Ok

El código es el siguiente:



&Ok = 'S'

DBase CLOSE DATA

&Msg = 'Importando ' + &ArchivoDBF
Msg(&Msg, NoWait)

DBase ARCHIVO = '"'+[!&DataView!]+'.DBF"'

DBase IF .NOT. FILE(&Archivo)
&Ok = 'N'
&Msg = 'Archivo no encontrado: ' + &DataView
Msg(&msg)
Return
DBase ENDIF

DBase USE &ARCHIVO EXCL
DBase ZAP
DBase PACK

DBase ARCHIVO = '"'+[!&dbfFile!]+'"'

DBase IF .NOT. FILE(&Archivo)
&Ok = 'N'
&Msg = 'Archivo no encontrado ' + &dbfFile
Msg(&Msg)
Return
DBase ENDIF

If &Tipo = 'DBF'
DBase APPEND FROM &ARCHIVO
DBase CLOSE DATA
Else
DBase APPEND FROM &ARCHIVO SDF
DBase CLOSE DATA
EndIf


En el parámetro de salida &Ok, se encuentra el resultado de la operación.
Si fué exitosa, contendrá "S", de lo contrario, contendrá "N"

Como estas Arielo??

Muy bueno el aporte, y estoy intentando usar esto para leer un DBF y volcar los datos en MySQL con gen java. Y tengo un par de dudas conlas variables que utilizas en el código. Me mareo un poco con las variables &dbfFile, &ArchivoDBF, &DataView.
Me podrías dar un ejemplo concreto de uso con esas variables??

Y en la sentencia DBase... DBase If .NOT. File(ARCHIVO) (no sería sin el &) ?

Muchas gracias.
Te agradezco si me pudieras ayudar pronto!!
Saludos.

Arielo
23/06/2009, 11:24
Hola, jak_uy, bienvenido... Qué bueno que se haya inscrito alguien que conozca GeneXus...

Las variables que mencionás, en concreto son:

&ArchivoDBF y &Dataview, son ambas Character(80). Contienen los nombres de las DBF original, y del DataView destino de los datos.

&Archivo está utilizado de esa manera, para que la macrosustitución sea soportada. Para esto se debe utilizar: [!(variable)!] junto con instrucción DBase al definirla.

Ejemplo:

&Formula = '1+1'
&Resultado = 0
dBase dBaseFormula = [!&Formula!]
dBase [!&Resultado!] = dBaseFormula
Al final del código, &Resultado contendrá el valor 2...
Esto sirve con los generadores Fox, no sabría decirte si con otros funciona...

Lo que no especifiqué, fueron los parámetros para el call a este prc:

Call(rAppend, &ArchivoDBF, &DataView, 'DBF', &Ok)El tercer parámetro, con valor en este caso = 'DBF', especifica cuál será el formato de salida. En base a esto, se agrega o no la sentencia SDF al final del comando APPEND...


Ahora, si lo que necesitas es pasar los datos de una DBF a una base MySQL, podrías usar el SQLCopy, y te ahorrás el estar codificando ...

Por ejemplo, yo estoy utilizando generador Java con PostgreSQL. Para importar datos desde una DBF, uso el SQLCopy junto a PGAdmin III, y anda perfecto. Y este código, lo uso sólo para importación de datos desde una DBF suelta, desde una opción del menú del sistema...



.

jak_uy
23/06/2009, 15:07
Hola, jak_uy, bienvenido... Qué bueno que se haya inscrito alguien que conozca GeneXus...

Las variables que mencionás, en concreto son:

&ArchivoDBF y &Dataview, son ambas Character(80). Contienen los nombres de las DBF original, y del DataView destino de los datos.

&Archivo está utilizado de esa manera, para que la macrosustitución sea soportada. Para esto se debe utilizar: [!(variable)!] junto con instrucción DBase al definirla.

Ejemplo:

&Formula = '1+1'
&Resultado = 0
dBase dBaseFormula = [!&Formula!]
dBase [!&Resultado!] = dBaseFormula
Al final del código, &Resultado contendrá el valor 2...
Esto sirve con los generadores Fox, no sabría decirte si con otros funciona...

Lo que no especifiqué, fueron los parámetros para el call a este prc:

Call(rAppend, &ArchivoDBF, &DataView, 'DBF', &Ok)El tercer parámetro, con valor en este caso = 'DBF', especifica cuál será el formato de salida. En base a esto, se agrega o no la sentencia SDF al final del comando APPEND...


Ahora, si lo que necesitas es pasar los datos de una DBF a una base MySQL, podrías usar el SQLCopy, y te ahorrás el estar codificando ...

Por ejemplo, yo estoy utilizando generador Java con PostgreSQL. Para importar datos desde una DBF, uso el SQLCopy junto a PGAdmin III, y anda perfecto. Y este código, lo uso sólo para importación de datos desde una DBF suelta, desde una opción del menú del sistema...



.

Muchísimas gracias por la pronta respuesta!! Y la verdad que apoyo mucho a GX, porque también me gano la vida con ello (o al menos trato) jeje.

De todas formas si no te jode, te voy a seguir molestando un poco más :-?

Te cuento lo que necesito hacer, porque capaz que en realidad no necesito hacer esto y se pueda hacer con sqlcopy (que en realidad tampoco lo conozco).
Estoy generando java también para MySQL, y lo que necesito hacer es un proc que se corra en forma batch al final del día para leer unas tablas DBF y tirar unos resultados procesados en MySQL. Por ello es que me gustaría no tener que hacer un prog en fox (por ejemplo) aparte para esta lectura y volcado de datos.
Decís que esto es más sencillo hacerlo por sqlcopy? Me podrías guiar un poco con ello?. O de lo contrario, me podrías ayudar a ajustar tu ejemplo para lo que estoy buscando (lectura DBF, grabación mySQL) ?.

Peerdona la molestia en serio, pero es muy importante.
Mientras tanto vengo probando con la librería javaDBF.

Mil Gracias!!
Saludos.

Arielo
23/06/2009, 15:35
Ah, pero si es un proceso diario no sé si te va a ser útil el Sqlcopy. Yo lo uso para convertir bases de un formato a otro, por ejemplo, para migrar de una versión a otra del mismo sistema.
Tengo un sistema programado en Gx 7.5 y generador FoxPro, y lo estoy migrando a Gx 9.0 con generador Java y motor PostgreSQL para las bases. Entonces, para volcar todos los datos de las DBF a Postgre, utilizo el SqlCopy.
Pero esto, para hacerlo unas pocas veces, sino es algo engorroso.
Si tenés que hacer el proceso todos los días, conviene hacer una rutina de importación/exportación...

El tema es que hasta donde yo sé, no tenemos acceso a bases .DBF si usas generador Java.

Tengo un caso parecido al tuyo, en el que tengo que pasar datos desde una DBF a Postgre importándolos desde dentro del sistema.
La rutina de Append con que inicié el tema no va a servir, porque graba en DBF o archivo texto...

Lo que hice, fue:
- En el sistema generado con FoxPro, un PRC que me genere un archivo .XML con los datos que tengo que importar. (O puede ser un .EXE aparte del sistema principal, que sólo realice la exportación al .XML)
- En el sistema generado con Java, un PRC que me importe los datos desde el .XML, y los vaya grabando en la tabla Postgre...

Si te sirve, avisame, y subo el cómo hacerlo. No es ninguna molestia...

Saludos!

jak_uy
23/06/2009, 15:59
Por supuesto que me sirve sí. Podría correr ese prc como externo dentro del generado en java.

De todas formas sigo investigando el javaDBF y sí llego a buen puerto te aviso por si también te sirve a tí.

Saludos, y gracias!

Arielo
23/06/2009, 16:43
Ok. Supongamos que queremos exportar las ventas realizadas mediante factura tipo ‘A’, entre dos fechas determinadas.
Para esto contamos con una tabla DBF llamada “VENTAS” con la siguiente estructura:
VtaFecha --> D(8) --> Fecha en que se realizó la venta.
VtaCliente --> N(10) --> Código del cliente al que se le vendió.
VtaTipoComp --> C(3) --> Tipo de comprobante emitido.
VtaNroComp --> N(8) --> Número de comprobante emitido.
VtaImporte --> N(12.2) --> Importe total de la factura por la venta.

Dentro de la base de datos de MySQL, tenemos una tabla llamada “Ventas” con la misma estructura que la DBF.

Exportación:
Utilizaremos las siguientes variables:
&Archivo --> C(80) --> Debe contener el path y el nombre del archivo .XML donde se exportarán los datos
&FileXML --> o(XMLWriter) --> Variable de tipo XMLWriter
&DdeFecha --> D(8) --> Contiene la fecha desde la que se exportarán los datos
&HtaFecha --> D(8) --> Contiene la fecha hasta la que se exportarán los datos
&Cliente --> C(10) --> Código del cliente
&Fecha --> C(8) --> Fecha en que se realizó la venta
&Importe --> C(12) --> Importe total de la factura
&Registro --> C(8) --> Identificación única de la venta (= número de comprobante)

Ya estamos listos para tipear el código. Todo esto puede ser hecho en el mismo WorkPanel donde el usuario ingrese el nombre del archivo, y las fechas desde/hasta. Si a este Workpanel lo definimos como Main, al compilarlo obtendremos un .EXE autónomo, que el usuario podrá ejecutar sin necesidad de estar dentro del sistema principal. O, se lo puede agregar como opción, colgándolo de algún menú, claro...

El código para exportar los datos:


&FileXML.Open(&Archivo) // Abrimos el archivo .XML
&FileXML.WriteStartDocument() // Comenzamos escritura del archivo
&FileXML.WriteStartElement(‘VENTAS’) // Se inicia el elemento ‘Ventas’

For Each
Where VtaFecha >= &DdeFecha // Fecha menor para exportación
Where VtaFecha <= &HtaFecha // Fecha mayor para exportación
Where VtaTipoComp = ‘FCA’ // Código (ejemplo) para facturas ‘A’
&Fecha = DToc(VtaFecha) // Convertimos la fecha a texto
&Cliente = Str(VtaCliente, 10, 0) // Convertimos el código de cliente a texto
&Importe = Str(VtaImporte, 12, 2) // Convertimos el importe a texto con dos decimales
&Registro = 'FCA' + Str(VtaNroComp, 8, 0) // Convertimos el número de comprobante a texto, y le anteponemos 'FCA'

&FileXML.WriteStartElement(&Registro) // Comenzamos a exportar un comprobante
&FileXML.WriteElement('Fecha', &Fecha) // Escribimos la fecha en el .XML
&FileXML.WriteElement('Cliente', &Cliente) // Escribimos el código del cliente en el .XML
&FileXML.WriteElement('Importe', &Importe) // Escribimos el importe de la venta en el .XML
&FileXML.WriteEndElement() // Terminamos de exportar un comprobante
EndFor

&FileXML.WriteEndElement() // Cerramos elemento ‘Ventas’
&FileXML.Close () // Cerramos el archivo



Y con esto, ya tenemos el archivo .XML generado. El que, al abrirlo, debería verse (con valores de ejemplo) así:


<?xml version="1.0" encoding="ISO-8859-1"?>
<VENTAS>
<FCA00014528>
<Fecha>03/06/08</Fecha>
<Cliente>01210</Cliente>
<Importe>185.65</Importe>
</FCA00014528>
</VENTAS>

Eso sí, lamentablemente, me tengo que ir hasta mañana... Así que, mañana subo el código para importar estos datos...


.

Macuy
24/06/2009, 00:41
No recordaba este post, pero esta muy bueno...
Segun entiendo, tiene la logica de desarrollo muy parecida a ruby on rails que habia comentado anteriormente (por cierto, ya no encuentro ese post)...

La curva de aprendizage que tan grande es Arielo?? cambia mucho la logica versus a la programacion en java o asp.net???

Xaludos

Arielo
24/06/2009, 07:40
Hola, Jorge...

En cuanto al aprendizaje, a mí no se me hizo tan complicado el entenderlo al principio. Yo encuentro la lógica y la sintaxis similares a las de VBasic, y por eso en este aspecto no tuve tantos problemas. Lo que puede llevar un poco más de tiempo, es la adaptación a un nuevo enfoque: en lugar de orientado a objetos, GeneXus está orientado al conocimiento. Por esto, se le da mucha importancia a lo que sepas acerca del problema que estás tratando, y ocupás mucho más tiempo en análisis y modelado que en otros lenguajes.
Pero una vez que tenes la KB (Knowledge Base) bien armada, podés construir un sistema grande y sólido en poco tiempo...

Una vez que le tomás la mano, se hace bastante rápido el construir sistemas potentes. No sencillo, pero sí mucho más que si tuvieras que hacer todas las bases desde cero.

Además, tiene la ventaja de que programás en GeneXus, pero el código nativo generado, puede ser de varias plataformas: VBasic, FoxProx, C/SQL, RPG, Cobol, .NET, .NET Mobile, Java.
Esto hace que el sistema sea muy portable, y adaptable a cualquier situación. Te ahorrás mucho tiempo de programación, ya que GeneXus te genera automáticamente el código en el lenguaje que hayas elegido...

Esto (http://www.genexus.es/documentos/pub/GenexusFilosofia.pdf) te puede ayudar a saber un poco más....
Este (http://www.genexus.com/portal/hgxpp001.aspx?2) es el sitio oficial...

Saludos!!!

jak_uy
24/06/2009, 12:16
Ok. Supongamos que queremos exportar las ventas realizadas mediante factura tipo ‘A’, entre dos fechas determinadas.
Para esto contamos con una tabla DBF llamada “VENTAS” con la siguiente estructura:
VtaFecha --> D(8) --> Fecha en que se realizó la venta.
VtaCliente --> N(10) --> Código del cliente al que se le vendió.
VtaTipoComp --> C(3) --> Tipo de comprobante emitido.
VtaNroComp --> N(8) --> Número de comprobante emitido.
VtaImporte --> N(12.2) --> Importe total de la factura por la venta.

Dentro de la base de datos de MySQL, tenemos una tabla llamada “Ventas” con la misma estructura que la DBF.

Exportación:
Utilizaremos las siguientes variables:
&Archivo --> C(80) --> Debe contener el path y el nombre del archivo .XML donde se exportarán los datos
&FileXML --> o(XMLWriter) --> Variable de tipo XMLWriter
&DdeFecha --> D(8) --> Contiene la fecha desde la que se exportarán los datos
&HtaFecha --> D(8) --> Contiene la fecha hasta la que se exportarán los datos
&Cliente --> C(10) --> Código del cliente
&Fecha --> C(8) --> Fecha en que se realizó la venta
&Importe --> C(12) --> Importe total de la factura
&Registro --> C(8) --> Identificación única de la venta (= número de comprobante)

Ya estamos listos para tipear el código. Todo esto puede ser hecho en el mismo WorkPanel donde el usuario ingrese el nombre del archivo, y las fechas desde/hasta. Si a este Workpanel lo definimos como Main, al compilarlo obtendremos un .EXE autónomo, que el usuario podrá ejecutar sin necesidad de estar dentro del sistema principal. O, se lo puede agregar como opción, colgándolo de algún menú, claro...

El código para exportar los datos:


&FileXML.Open(&Archivo) // Abrimos el archivo .XML
&FileXML.WriteStartDocument() // Comenzamos escritura del archivo
&FileXML.WriteStartElement(‘VENTAS’) // Se inicia el elemento ‘Ventas’

For Each
Where VtaFecha >= &DdeFecha // Fecha menor para exportación
Where VtaFecha <= &HtaFecha // Fecha mayor para exportación
Where VtaTipoComp = ‘FCA’ // Código (ejemplo) para facturas ‘A’
&Fecha = DToc(VtaFecha) // Convertimos la fecha a texto
&Cliente = Str(VtaCliente, 10, 0) // Convertimos el código de cliente a texto
&Importe = Str(VtaImporte, 12, 2) // Convertimos el importe a texto con dos decimales
&Registro = 'FCA' + Str(VtaNroComp, 8, 0) // Convertimos el número de comprobante a texto, y le anteponemos 'FCA'

&FileXML.WriteStartElement(&Registro) // Comenzamos a exportar un comprobante
&FileXML.WriteElement('Fecha', &Fecha) // Escribimos la fecha en el .XML
&FileXML.WriteElement('Cliente', &Cliente) // Escribimos el código del cliente en el .XML
&FileXML.WriteElement('Importe', &Importe) // Escribimos el importe de la venta en el .XML
&FileXML.WriteEndElement() // Terminamos de exportar un comprobante
EndFor

&FileXML.WriteEndElement() // Cerramos elemento ‘Ventas’
&FileXML.Close () // Cerramos el archivo



Y con esto, ya tenemos el archivo .XML generado. El que, al abrirlo, debería verse (con valores de ejemplo) así:


<?xml version="1.0" encoding="ISO-8859-1"?>
<VENTAS>
<FCA00014528>
<Fecha>03/06/08</Fecha>
<Cliente>01210</Cliente>
<Importe>185.65</Importe>
</FCA00014528>
</VENTAS>

Eso sí, lamentablemente, me tengo que ir hasta mañana... Así que, mañana subo el código para importar estos datos...


.


Impecable Arielo, sos un fenómeno.
Este código lo pondría en un modelo generando para vfox. Y les accedería a los dbf por data views sin problemas entonces me imagino.
Y luego desde el modelo java leo el xml directamente... convirtiendo nuevamente el tipo de dato según corresponda, y almacenando en MySQL.

Simplemente llamo el prc en fox como prog externo desde el java y es´taría pronto supongo.

Gracias Arielo!
Si por las dudas me podes dejar el source para la lectura no te jodo más, aunque es trivial, para no andar probando y trancarme de vuelta.

Mil gracias!
Un abrazo.

Arielo
24/06/2009, 14:40
No puedo encontrar el código que tengo listo.... :confused:

Pero, en realidad, la lectura no tiene grandes secretos...

Habrá que usar solamente una variable de tipo XMLReader, y las que necesitemos para leer los valores, mientras vamos recorriendo el XML completo...

Voy a seguir buscando, cuando la encuentre la subo...

Gracias...
Saludos!


.

jak_uy
25/06/2009, 16:39
No puedo encontrar el código que tengo listo.... :confused:

Pero, en realidad, la lectura no tiene grandes secretos...

Habrá que usar solamente una variable de tipo XMLReader, y las que necesitemos para leer los valores, mientras vamos recorriendo el XML completo...

Voy a seguir buscando, cuando la encuentre la subo...

Gracias...
Saludos!


.

Muchas gracias Arielo por la ayuda.

Mientras tanto yo venía haciendo pruebas con la libreria JavaDBF, y las pruebas por el momento vienen bien. A modo de ejemplo simplemente estoy leyendo unas tablas con muy poco registros, pero al parecer funciona sin problemas.

Si alguien quiere vichar que tal, la url es: http://sarovar.org/docman/view.php/32/23/javadbf-tutorial.html


Gracias.
Saludos.

Jota E
12/05/2010, 13:39
Gracias de nuevo Arielo, este post estaba perdido y es bueno rescatarlo.