Hola a todos, solicito vuestra ayuda con un problema que tengo que resolver y que os traslado por si podéis echarme una mano.
Intentaré ser claro y conciso.
A partir de dos tablas de datos, necesito crear un archivo de texto plano en formato “.CSV”, para que otra aplicación pueda leerlo.
Con el siguiente código que pego al final de este mensaje he conseguido crear el archivo correctamente, con todos los datos de la tabla, pero lo que realmente necesito es formar la cadena de texto compuesta por los siguientes campos de de dos tablas de este modo:
codigo;fecha;numAsiento;Fra.A-XXXX;descripcion;debe;importe;canal
Como ayuda para una mejor comprensión aporto los siguientes datos:
códigocontable= un campo de la tabla clientes
fecha= campo tipo date de la tabla facturas
numAsiento= este campo tiene que ir sin datos pero tengo que incluirlo.
codcliente=este me viene de tabla facturas
descripción: este campo está formado por texto y campos de esta forma:“Fra. A-XXXX” es = “Fra” + serie + “-” + numfactura
Donde “Fra”= es un texto.
Serie = es un campo de la tabla.
“-” = es texto.
Numfactura = es un campo de la tabla facturas.
Por ahora lo que tengo es esto: pero veréis que falta por completar bastante.
Select tabla
*Abre la tabla cuyos datos quieres generar a txt
*_cadena = str(tabla.numero,8)+" "+dtoc(tabla.fecha)+" "+tabla.nomcli+" "+transform(tabla.importe,_importmask)
COPY TO C:\texto1.txt FIELDS codigo,fecha, numAsiento,importe TYPE CSV
*Copia el contenido de tutabla en formato txt (con los nombres de los campos como primera línea).
CREATE TABLE AUXILIAR ( CAMPOMEMO m(20) )
*Crea una tabla de nombre auxiliar con un único campo llamado CAMPOMEMO de tipo MEMO). Este comando deja abierta la tabla auxiliar.dbf
APPEND BLANK
*Agrega un registro en blanco en la tabla auxiliar.dbf
APPEND MEMO CAMPOMEMO FROM C:\texto1.txt OVERWRITE
*Guarda en el campo de tipo memo llamado CAMPOMEMO, el contenido del archivo de texto de nombre texto1.txt, credo con COPY TO texto1.txt TYPE CSV
cTempo = STRTRAN( CAMPOMEMO , '"', '' )
* El campo COMPOMEMO ya tiene el contenido de texto1.txt . La función strtran toma el valor del CAMPOMEMO , "elimina" las comillas de ese valor contenido y los guarda ya "convertido" en la variabla cTempo. Es decir strtran "devuelve", en cTempo, el contenido del campo memo sin las comillas.
REPLACE CAMPOMEMO WITH cTempo
* Se reemplaza el valor de CAMPOMEMO con el valor de cTempo
COPY MEMO CAMPOMEMO TO C:\texto2.txt
* Copia el valor de CAMPOMEMO en un archivo de texto (texto2.txt)
Agradecería si alguien me ayuda a formar el código para que me cree los archivos con los datos separados por “;”, para que los pueda leer la otra aplicación.
Muchas gracias.
Lo primero que debes hacer, es crear un solo cursor con todos los datos.
Luego, puedes usar la función que sigue.
PROCEDURE Export_Cursor_to_Text
LPARAMETERS tcCursor,;
tcFileName,;
tcFieldsSeparator,;
tcSetPoint,;
tlInclude_Header,;
tlNotQualifer,;
tcEof_Line
*!* --------------------------------------------------------------------------
*!* Finalidad Exportar el cursor a formato texto plano Incluyendo campos MEMO
*!*
*!* tcCursor: Nombre del Cursor que se exporta
*!* tcFileName: Path + Nombre + extensión del archivo de salida
*!* tcFieldsSeparator Caracter de separador de campos ("," (Default))
*!* tcSetPoint: Caracter de separador de decimales ("." (Default) ",")
*!* tlInclude_Header Si se incluye el encabezado
*!* tlNotQualifer Evita que los campos texto tenga calificador ("")
*!* tcEof_Line Separador de Líneas [CHR(13)+CHR(10) Default ]
*!* --------------------------------------------------------------------------
#DEFINE _DCOM_ CHR(34)
#DEFINE _SCOM_ CHR(39)
#DEFINE _TAB_ CHR(9)
#DEFINE _CR_ CHR(13)
#DEFINE _CL_ CHR(10)
#DEFINE _STAB_ CHR(32)+CHR(45)+CHR(32)
TRY
LOCAL I,;
lnfields,;
lcString,;
lChangePoint,;
lcSetPoint_Default,;
lcSetPoint_Stuff,;
lcSetPoint_Reemp,;
lcQualifer,;
lnDecim,;
lReturn,;
loEx as Exception
LOCAL ARRAY laFields(1)
lcSetPoint_Default = SET("Point")
tcSetPoint = EVL(m.tcSetPoint, m.lcSetPoint_Default )
tcFieldsSeparator = EVL(m.tcFieldsSeparator,",")
tcEof_Line = EVL(m.tcEof_Line,CHR(13)+CHR(10))
lcQualifer = IIF(m.tlNotQualifer,"",_DCOM_)
IF EMPTY(m.tcFileName)
tcFileName = FORCEEXT(tcCursor,IIF(tcFieldsSeparator=CHR(59),"csv","txt"))
ENDIF
lChangePoint = m.tcSetPoint # m.lcSetPoint_Default
IF m.lChangePoint
lcSetPoint_Stuff = m.lcSetPoint_Default
lcSetPoint_Reemp = m.tcSetPoint
ENDIF
lnFields = AFIELDS(laFields,m.tcCursor)
lcString = ""
IF m.tlInclude_Header
FOR i = 1 TO m.lnFields
lcString = m.lcString ;
+ PROPER(laFields[m.i,1]);
+ IIF(m.i < m.lnFields, m.tcFieldsSeparator,"")
NEXT
lcSTring = m.lcString + m.tcEof_Line
ENDIF
SELECT (m.tcCursor)
SCAN
FOR i=1 TO m.lnFields
DO CASE
CASE laFields[m.i,2] = "C"
lcText = m.lcQualifer ;
+ CHRTRAN(ALLTRIM(EVALUATE(laFields[m.i,1])),_DCOM_ + _SCOM_ , "") ;
+ m.lcQualifer
CASE lafields[m.i,2] = "M"
lcTExt = m.lcQualifer ;
+ CHRTRAN(CHRTRAN(STRTRAN(STRTRAN(ALLTRIM(EVALUATE(laFields[m.i,1])),_TAB_,_STAB_),_CR_,_STAB_),_DCOM_,_SCOM_),_CL_,"") ;
+ m.lcQualifer
CASE laFields[m.i,2] = "N"
lcText = ALLTRIM(STR(EVALUATE(laFields[m.i,1]),14,laFields[i,4]))
IF m.lChangePoint
lcText = CHRTRAN(m.lcText,m.lcSetPoint_Stuff,m.lcSetPoint_Reemp)
ENDIF
OTHERWISE
lcText = TRANSFORM(EVALUATE(laFields[m.i,1]))
ENDCASE
lcString = m.lcString ;
+ m.lcText ;
+ IIF(m.i < m.lnFields, m.tcFieldsSeparator,"")
NEXT
lcSTring = m.lcString + m.tcEof_Line
ENDSCAN
STRTOFILE(m.lcstring,m.tcFileName)
lREturn = .t.
CATCH TO loex
loex.UserValue = PROGRAM()
* ShowError(loex) (rutina que muestra y graba errores
FINALLY
#UNDEFINE _DCOM_
#UNDEFINE _SCOM_
#UNDEFINE _TAB_
#UNDEFINE _CR_
#UNDEFINE _CL_
#UNDEFINE _STAB_
ENDTRY
RETURN m.lREturn
ENDPROC
Un ejemplo de llamada a la función:
*!* Juntar datos de dos tablas (Movim y Clientes) en un cursor
*!* Generar un archivo de texto plano tipo CSV
*!* Si el destino es Microsoft Excel ® puede necesitarse que lcSetPoint = ","
*!* Si se necesitan los encabezados, lInclude_header = .t.
*!*
LOCAL ldDia1,;
ldDia2,;
lcFileName,;
lnTally,;
lcFieldsSeparator,;
lInclude_Header,;
lcSetPoint
lcFieldsSeparator = CHR(59)
lcSetPoint = CHR(44)
lInclude_Header = .t.
ldDia1 = DATE(2016,1,1)
ldDia2 = GOMONTH(ldDia1,1)-1
lcFileName = "Ventas_por_Clientes_"+LEFT(DTOS(ldDia2),6)+".csv"
SET ENGINEBEHAVIOR 70
SELECT mv.idclien,;
cli.nombre,;
SUM(mv.gravado) as gravado,;
SUM(mv.impiva) as impiva,;
SUM(mv.total) as total,;
cli.memorias ;
FROM movim as mv, clientes as cli ;
WHERE mv.fecha between m.lddia1 AND m.ldDia2 ;
AND mv.idclien == cli.idclien ;
GROUP BY mv.idclien ;
ORDER BY cli.nombre ;
INTO CURSOR curVentas READWRITE
lnTally = _tally
*BROWSE
SET ENGINEBEHAVIOR 90
IF lnTally > 0
IF Export_Cursor_to_Text("curVentas",;
m.lcFileName,;
m.lcFieldsSeparator,;
m.lcSetPoint,;
m.lInclude_Header )
MESSAGEBOX("End")
ENDIF
ELSE
MESSAGEBOX("No hay datos")
ENDIF