[RESUELTO] Leer un archivo de texto carácter por carácter

Desarrollo de Macros y programación en UNO, usar las API, llamar programas externos...
Responder
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

[RESUELTO] Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

Saludos a todos,

Estoy buscando como importar un archivo de texto a Calc leyendo carácter por carácter (o stream), algo como "fgets".
Tengo un archivo de texto en el cual se han dispuesto registros de 500 caracteres, sin carácter de separación alguno. El primer carácter siempre indica el tipo de registro. Según el tipo de registro los campos (dentro de ese registro) tienen una longitud determinada, pero los campos no tienen porque tener la misma longitud.

¿Cual sería el código para apuntar hacia el archivo? y luego ir leyendo cadenas de 500 en 500 caracteres?
Última edición por mauricio el Jue Nov 05, 2015 5:12 pm, editado 2 veces en total.
Razón: Marcar icono de resuelto
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Leer un archivo de texto carácter por carácter

Mensaje por mauricio »

Hola...

Dependiendo del lenguaje que uses hay varias técnicas disponibles, la siguiente macro usa OOo Basic y un método sencillo para leer el archivo...

Código: Seleccionar todo

Option Explicit

Sub LeerArchivo() 
Dim oAA As Object
Dim sRuta As String
Dim oArchivo As Object
Dim oTexto As Object
Dim sContenido As String
Dim co1 As Long

	'La ruta del archivo
	sRuta = ConvertToUrl( "/home/mau/Desktop/archivo.txt" )
	'Servicio para acceso a archivos
	oAA = createUnoService("com.sun.star.ucb.SimpleFileAccess")
	'Servicio para manipular archivos
	oTexto = createUnoService("com.sun.star.io.TextInputStream")
	'Verificamos que exista el archivo
	If oAA.exists( sRuta ) Then
		'Abrimos el archivo para lectura/escritura
		oArchivo = oAA.openFileReadWrite( sRuta )
		'El archivo puede ser más grande pero no cabe en una variable String
		If oArchivo.getLength < 65535 Then
			'Leemos el archivo de forma binaria
			oTexto.setInputStream( oArchivo.getInputStream )
			'Leemos el contenido completo como texto
			sContenido = oTexto.readString( Array(""), True )
			'Leemos cada 500 caracteres
			For co1 = 1 To Len(sContenido) Step 500
				'Cuidado, si tu archivo es muy grande este ciclo puede ser muy largo
				'solo te lo muestro como ejemplo, aquí se supone manipularias el archivo
				'a tus necesidades
				MsgBox Mid( sContenido, co1, 500 )
			Next
		Else
			MsgBox "Archivo demasiado grande"
		End If
	Else
		MsgBox "No se encontro el archivo: " & ConvertFromUrl(sRuta)
	End If
	
End Sub
Si esto responde tu pregunta, por favor edita el primer mensaje de este hilo y agrega al principio del título la etiqueta [RESUELTO], de esta forma conseguiremos un foro más ordenado.

Saludos
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

Re: Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

Gracias Mauricio,

Efectivamente el fichero es mayor de 65535 (desconocía este dato).
Esta fue mi primera apuesta, pero el archivo es algo mayor, puede contener entre 300 y 600 registros de 500 caracteres.
También estuve haciendo pruebas con este ejemplo de la ayuda:

Código: Seleccionar todo

        Sub EjemploAccesoAleatorio
        Dim iNumero As Integer
        Dim sTexto As Variant REM Debe ser una variante
        Dim aArchivo As String
        aArchivo = "/home/jj/prueba.txt"
        iNumero = Freefile
        Open aArchivo For Random As #iNumero Len=32
        Seek #iNumero,1 REM Posición al principio
        Put #iNumero,, "Esta es la primera línea de texto" REM Rellenar
        línea con texto
        Print #iNumero, "Esta es la segunda línea de texto"
        Print #iNumero, "Esta es la tercera línea de texto"
        Seek #iNumero,2
        Get #iNumero,,sTexto
        Print sTexto
        Close #iNumero
        iNumero = Freefile
        Open aArchivo For Random As #iNumero Len=500
        Get #iNumero,2,sTexto
        Put #iNumero,,"Esto es un texto nuevo"
        Get #iNumero,1,sTexto
        Get #iNumero,2,sTexto
        Put #iNumero,20,"Este es el texto del registro 20"
        Print Lof(#iNumero)
        Close #iNumero
        end sub
No guarda datos en formato texto (o al menos no en UTF-8,
ISO-8859-1, ...) y en el primer "Get" da error.
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Leer un archivo de texto carácter por carácter

Mensaje por mauricio »

Hola...

Te sugiero usar Python, la siguiente macro te guarda cada 500 caracteres en cada fila de una hoja de calculo, la probé con más de 700 registros de 500 cada uno y funciona bien.

Código: Seleccionar todo

def LeerArchivo():
	# Accedemos al modelo del documento actual 
	model = XSCRIPTCONTEXT.getDocument()
	# Accedemos a la primer hoja del documento
	hoja = model.getSheets().getByIndex(0)
	sRuta = "/home/mau/Desktop/archivo.txt"  
	archivo = open( sRuta, "r" )	
	sContenido = archivo.read()
	lineas = len(sContenido) / 500 + 1
	co1 = 0
	while co1 < lineas :
		# Accedemos a la celda A1 de la hoja
		celda = hoja.getCellByPosition( 0, co1)
		sTmp = sContenido[co1*500:co1*500+500]
		# Escribimos en la celda
		celda.setString( sTmp )
		co1 = co1 + 1
	return None	
Para usar esta macro sigue esta guía: http://wiki.services.openoffice.org/wik ... o/PyUNO_ES

Saludos
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

Re: Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

Ok, mañana la pruebo y te cuento.

Gracias Mauricio.
Un saludo.
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

Re: Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

Perfecto, una única pega, como sospechaba los caracteres especiales (ñ, Ñ y acentos) no se muestran correctamente. ¿Hay alguna forma de cambiar la página de códigos como en Basic mediante "setEncoding"?

Una dificultad añadida, además de mi poco conocimiento de python (lo que siempre es superable,... :D supongo...) es que en entornos Windows habrá que instalar python, que tampoco es algo insalvable.

Respecto a realizarlo con Java, aquí la imposibilidad es mía por desconocimiento.

Gracias Mauricio.
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Leer un archivo de texto carácter por carácter

Mensaje por mauricio »

Hola...

En mi equipo se muestran correctamente los caracteres especiales importados del archivo, ¿puedes subir un archivo de ejemplo para hacer unas pruebas?...

Para usar las macros desde dentro de OOo, este, ya trae todo lo necesario para trabajar con las macros como la que te mostré, si quieres hacer uso de funciones añadidas, tal vez si tengas que instalarlo, pero para empezare no lo requieres mientras OOo este instalado correctamente.

Java no me gusta, normalmente no uso lo que no me gusta, por ello nunca me he metido con Java más allá de hacer algunas pruebas de concepto, pero tal vez sea un buen momento para probar...

Saludos
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

Re: Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

Te he enviado un archivo de prueba, "prueba.out". Este archivo se genera en un entorno Windows y yo trabajo con Ubuntu. Mañana probaré la macro que me pasaste en el entorno donde se generó el archivo. A ver si hay diferencias.

Otra cosa, en la dirección que me pasaste sobre pyUNO es una pena que no este desarrollado la parte de diálogos con python. Conoces algún doc para iniciarse. Estoy repasando todo lo que hay en http://wiki.services.openoffice.org/wiki/Python_es.
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Leer un archivo de texto carácter por carácter

Mensaje por mauricio »

Hola...

¿A donde enviaste el archivo?, tienes que anexarlo a este tema como se muestra aquí: http://user.services.openoffice.org/es/ ... f=3&t=1335

Si, la verdad es que no he tenido tiempo de agregar más información al wiki, espero pronto retomarlo pero lo que me hace falta es tiempo para desarrollar todo los temas que quiero. Salvo los vínculos que muestro en el mismo wiki, no conozco más lugares (en español) para ello, hace falta escribir mucha documentación.

Saludos
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

Re: Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

El archivo te lo envié a ti mediante un mensaje privado, desde este foro.
Puede que el problema sea que excedía en 2kb el límite. Repito el envío mediante mensaje privado, esta vez comprimido.

Respecto a la documentación, lo que hay no será mucho pero 100% práctico. Te brindo mi ayuda para ir mejorando la documentación. Al fin y al cabo es lo menos que puedo hacer. Gracias a tu manual "Aprendiendo OOo Basic", he conseguido realizar todas las pequeñas macros que me ahorran trabajo en mi día a día y además disfrutar en el proceso.

Gracias y un cordial saludo,
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

Re: Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

Corrijo mi anterior mensaje:
Te lo envío a tu correo directamente, pues no he sido capaz de adjuntar el archivo en la página de mensaje privado.
Siempre me respondía, "extensión no permitida"...

Saludos,
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
Avatar de Usuario
mauricio
Mensajes: 6092
Registrado: Sab Nov 22, 2008 5:36 am
Ubicación: CDMX
Contactar:

Re: Leer un archivo de texto carácter por carácter

Mensaje por mauricio »

Hola...

Mi perfil en el foro no acepta el envío de correo, tienes que anexarlo a este hilo como se ve aquí: http://user.services.openoffice.org/es/ ... f=3&t=1335 tiene que comprimirlo primero para que te acepte el archivo. Acepto tu ofrecimiento para la documentación, de hecho dejo la invitación abierta para todos, te escribo un mensaje privado para platicarlo...

Saludos
______________________________________________
"Todo cuanto no podemos dar nos posee". - André Gide
LibreOffice 6.2 | ArchLinux | Gnome3
No respondo preguntas privadas, por favor, usa el foro
jjpalacios
Mensajes: 11
Registrado: Jue Feb 04, 2010 6:43 pm

Re: Leer un archivo de texto carácter por carácter

Mensaje por jjpalacios »

Tras unos días un poco liado, os haré un resumen final a modo de colofón sobre este tema.

La macro que me paso Mauricio en python ha funcionado a la perfección.
Tan solo unos detalles a tener en cuenta.
El primero que efectivamente se puede portar directamente a Windows sin tener que instalar nada, pero cuidado con la "ruta" del archivo. Si se incluye la ruta completa del archivo con los caracteres de separación de directorio "\", esto puede que no de errores si el nombre del archivo empieza por un carácter alfabético pero generará un error si el nombre del archivo comienza por un número. Parece que en este caso el interprete toma la secuencia "\'número'", por ejemplo "\0", ó "\2", etc... por un carácter de control y genera un error. Así pues en Windows es mejor poner la ruta al archivo como: "\\directorio1\\directorio2\\...", de este modo no hay riesgo de error.
Por otro lado, existe un problema con los caracteres especiales como la "ñ", "Ñ". Cuando existe un carácter de este tipo el resultado es que el carácter especial lo cuenta como doble y lee en realidad un carácter menos (499 en lugar de 500). Si es en los primeros 500 caracteres, es decir el primer registro, todos los registros siguientes aparecerán desplazados un carácter.
La solución a este problema la desconozco.

Habrá quien se pregunte, que o quien puede generar un fichero de datos tan "particular", bueno pues es un formato que aquí en España se emplea para transmisión de datos telemáticos fiscales con la administración. Existe una publicación oficial y pública del formato del fichero, por si alguien esta interesado. En la especificación oficial expresamente se cita el carácter "Ñ" como el decimal 209 ó D1 en Hexadecimal. Cuando envías el fichero un validador (parser) comprueba que el fichero este correctamente construido. Ahí es donde se generan los problemas y la necesidad de validar previamente el fichero. Prácticamente todos los programas actuales de contabilidad y gestión generan estos ficheros adecuadamente, pero en ocasiones te encuentras que alguien tiene un programa tan antiguo que no lo hace o que la empresa debe declarar a la agencia nacional pero también a la, o las autonómicas y así el desmadre es mayor.

En cualquier caso creo que es muy instructivo tener que lidiar con un caso así, desde el punto de vista docente. Yo al menos he aprendido bastante.

Sigo investigando,... si existe un método de leer bytes (que seguro que lo hay pero yo no he sido capaz de realizarlo) mediante OOo Basic y como arreglar lo de las eñes, además de no escribiéndolas.

Pongo es tema como solucionado, ¿si os parece?
Gracias a todos,
JJ

P.D. Mauricio: al final no te envíe el fichero de muestra, por problemas que no vienen al caso, creo que ya no es necesario, pero si te interesa puedo enviártelo directamente. En cuanto a la documentación, adelante, iremos sacando tiempo al tiempo.
Saludos,
JJ
LibreOffice 3.5.3
Ubuntu 12.04
Responder