Acciones sobre archivos de texto. [Batch]

Iniciado por leogtz, 24 Enero 2009, 00:30 AM

0 Miembros y 1 Visitante están viendo este tema.

ariel_fnx

Hola a todos. Soy nuevo en el foro como usuario, pero he estado leyéndolo y me ha gustado bastante la camaradería que existe.
Les comento mi problema que no logro resolver.
Tengo un programa de gestión comercial que no tiene soporte para impresoras fiscales. No obstante he encontrado un spooler para la impresora fiscal que me permite realizar facturas enviándole un archivo con los datos necesarios.
El programa de gestión me genera archivos con el ticket a imprimir, pero en otro formato no soportado por la impresora fiscal.
Lo que yo debo hacer es sacar los datos del archivo de ticket que me genera el programa de gestión (es un txt) y colocarlos en su correspondiente ubicación en el archivo de impresión de la impresora fiscal (es un txt también), para que de esa manera la impresora fiscal pueda imprimir correctamente la factura.

El archivo de la impresora fiscal (factura.txt) es el siguiente:
b Empresa Equis 30702383923 I C Domicilio...
@ A S
B Item Uno 30.0 1.0 21.0 M 0.0 0 b
B Item Dos 1.0 20.81 10.0 M 0.0 0 b
C P Subtotal 0
D Efectivo 100.00 T 0
E


Los datos a reemplazar son en este caso donde dice Item Uno por la descripción del primer producto, donde dice 30.0 la cantidad del mismo, y donde dice 1.0 el valor del mismo.
Donde dice Item Dos la descripción del segundo producto, donde dice 1.0 la cantidad del mismo, y donde dice 20.81 el valor del mismo.
Y así sucesivamente según la cantidad de artículos que haya en el archivo de ticket generado por el programa de gestión.

El archivo que me genera el programa de gestión (ticket.txt) es el siguiente:

Ticket Nro. 12
Fecha: 05/01/12 Hora: 02:20




  3  AMARILLO LEDERNIL E - EURO    $27,00
  1  AMARILLO LEDERNIL RP - EURO   $13,00
  1  AMARILLO LEDERNIL L - EURO    $10,40

                                  -------
TOTAL                              $50,40


La idea sería crear un archivo .bat para que realice dicho procedimiento, ya que el programa de gestión corre sobre windows.
Tengo conocimientos de principiante en el tema, ya que me encuentro aprendiendo desde hace poco tiempo, y no logro encontrar la manera de hacerlo funcionar.
Estaré muy agradecido de la ayuda que me puedan brindar, ya que necesitaría poder utilizar la impresora fiscal lo antes posible.
Desde ya, gracias a todos.-

leogtz

Bien, te podemos ayudar, solo necesito que pongas un ejemplo claro, si es posible real del archivo de entrada (el archivo que hay que convertir) y el archivo a como quieres que quede, exactamente. Porque veo que el último archivo no tiene mucho que ver con el primero.

Saludos.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

ariel_fnx

Hola Leo, gracias por tu rápida respuesta. Por todo lo que estuve leyendo en el foro no tengo más que felicitarte, porque la verdad es que tenés una facilidad para resolver lo que te plantean digna de sacarse el sombrero.
Bueno, te explico mejor lo que quiero hacer.
El programa de gestión del negocio me genera un archivo (ticket.txt) el cual contiene lo siguiente:
Ticket Nro. 12
Fecha: 05/01/12 Hora: 02:20




  3  AMARILLO LEDERNIL E - EURO    $27,00
  1  AMARILLO LEDERNIL RP - EURO   $13,00
  1  AMARILLO LEDERNIL L - EURO    $10,40

                                  -------
TOTAL                              $50,40


De este archivo lo que nos interesa extraer son 3 tipos de datos: cantidad de un producto, descripción del producto, y el precio del producto (que en el ticket ya aparece calculado el precio total del mismo, es decir, cantidad de un producto por el precio individual, razón por la cual tenemos que calcular el precio individual para asignar a esta variable)
En el caso de este ticket vemos que hay tres líneas de venta.
En la primera fila nos indica que vendió 3 productos, y en las filas 2 y 3 se vendió un solo producto de esos items.
En resumen, tenemos 3 variables por línea para extraer.
Ahora bien, con esos datos que extraemos de esas líneas tenemos que crear un archivo que se llame factura.txt, el cual debería tener el siguiente formato:
@ A S
B AMARILLO LEDERNIL E - EURO 3.0 9.0 21.0 M 0.0 0 b
B AMARILLO LEDERNIL RP - EURO 1.0 13.0 21.0 M 0.0 0 b
B AMARILLO LEDERNIL L - EURO 1.0 10.40 21.0 M 0.0 0 b
C P Subtotal 0
D Efectivo 100.00 T 0
E


Así es como debería quedar el archivo factura.txt.
Ahora te explico en detalle cómo esta conformado este archivo.
La primera línea es siempre igual:
@ A S
Luego seguirían las líneas en las cuales usaremos las variables extraídas de ticket.txt:
B AMARILLO LEDERNIL E - EURO 3.0 9.0 21.0 M 0.0 0 b
B AMARILLO LEDERNIL RP - EURO 1.0 13.0 21.0 M 0.0 0 b
B AMARILLO LEDERNIL L - EURO 1.0 10.40 21.0 M 0.0 0 b

Estas líneas estarían compuestas de la siguiente manera:
la línea comienza con una letra B mayúscula y un espacio, luego la descripción de un producto y un espacio, luego la cantidad de ese producto en formato cantidad.0 (por ejemplo, en caso de ser 3 unidades, 3.0) y un espacio, luego el precio unitario de ese producto en formato x.x (por ejemplo, si el precio es 10 sería 10.0, y si el precio es 10,40 sería 10.40) y un espacio, y luego la línea siempre terminaría con: 21.0 M 0.0 0 b
Finalmente, luego de las líneas de los productos vendidos seguirían las últimas líneas, que siempre son iguales:
C P Subtotal 0
D Efectivo 100.00 T 0
E


Con el archivo factura.txt creado ya puedo imprimir la operación de venta realizada en la impresora fiscal.

Bueno Leo, espero haberte explicado lo más detallado posible lo que deseo hacer para que puedas ayudarme. Cualquier duda que tengas estaré atento para contestarte lo más rápido posible. Y desde ya, un millón de gracias.

leogtz

Bien, dame un momento, ya estoy en ello.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

leogtz

Listo, terminé, resultó una solución demasiado artesanal. En parte porque en Windows carece de utilidades para procesar flujos, de expresiones regulares, en fin...

Antes que nada comentarte algo, batch es muy arcaico y simple, no tiene soporte para operaciones con decimales, así que hice un pequeño código en C solamente para la parte de sacar el precio unitario, es muy simple:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    if(argc != 3)
        return EXIT_FAILURE;
    printf("%.2f\n", atof(argv[1]) / atof(argv[2]));
    return EXIT_SUCCESS;
}


Esto es lo único que tendrás que utilizar, ahora el batch.

Teniendo el ticket.txt:

C:\Users\leo\batch>type ticket.txt
Ticket Nro. 12
Fecha: 05/01/12 Hora: 02:20




  3  AMARILLO LEDERNIL E - EURO    $27,00
  1  AMARILLO LEDERNIL RP - EURO   $13,00
  1  AMARILLO LEDERNIL L - EURO    $10,40

                                  -------
TOTAL                              $50,40
C:\Users\leo\batch>


Luego de ejecutar el script me genera esto en "factura.txt":


C:\Users\leo\batch>code.cmd

C:\Users\leo\batch>type factura.txt
@ A S
B AMARILLO LEDERNIL E - EURO 3.0 9.00 21.0 M 0.0 0 b
B AMARILLO LEDERNIL RP - EURO 1.0 13.00 21.0 M 0.0 0 b
B AMARILLO LEDERNIL L - EURO 1.0 10.40 21.0 M 0.0 0 b
C P Subtotal 0
D Efectivo 100.00 T 0
E

C:\Users\leo\batch>


Este es el código del archivo batch:
Código (bash) [Seleccionar]

@echo off
setlocal enabledelayedexpansion
set /a count=0
for /f "tokens=*" %%_ in ('type "ticket.txt" ^| findstr /r "^..[0-9].*$"') do (set "productos[!count!]=%%_" & set /a count+=1)
set /a count-=1
for /l %%_ in (0, 1, %count%) do (
for /f "tokens=1 delims= " %%# in ("!productos[%%_]!") do (
set "descripcion_final[%%_]=%%#"
)
)
for /l %%_ in (0, 1, !count!) do (
for /f "tokens=1* delims=$" %%a in ("!productos[%%_]!") do (call:process %%a)
set "descripcion_final[%%_]=!descripcion_final[%%_]!;!s!;"
set /a i+=1
)
for /l %%_ in (0, 1, %count%) do (
for /f "tokens=2 delims=$" %%a in ("!productos[%%_]!") do (set "precio=%%a")
set "descripcion_final[%%_]=!descripcion_final[%%_]!!precio:,=.!"
)
:: Generar "factura.txt"
echo @ A S > "factura.txt"
for /l %%_ in (0, 1, %count%) do (
for /f "tokens=1,2,3 delims=;" %%a in ("!descripcion_final[%%_]!") do (
for /f "tokens=*" %%x in ('div %%c %%a') do echo B %%b %%a.0 %%x 21.0 M 0.0 0 b >> "factura.txt"
)
)
echo C P Subtotal 0 >> "factura.txt"
echo D Efectivo 100.00 T 0 >> "factura.txt"
echo E >> "factura.txt"
goto:eof
:process
for /f "tokens=1*" %%a in ("%*") do (set "s=%%b")
goto:eof


El ejecutable en C que hice lo llamé "div.exe" y lo uso aquí:
for /f "tokens=*" %%x in ('div %%c %%a') do echo B %%b %%a.0

Sólo se encarga de dividir, por ejemplo
div.exe 10.0 2.0
Devolvería 5.0

Aquí lo puedes descargar:

http://www.megaupload.com/?d=OWC2YJSN

O sino puedes compilarlo tu mismo con el código fuente que te dejé arriba, si lo compilas tu mismo, no olvides llamar al ejecutable generado div.exe, sino el batch fallará.


Saludos, cualquier duda me dices.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

ariel_fnx

Hola Leo. Tuve que salir a la tarde y recién llego a casa. La verdad que me sorprendiste al ver que ya lo habías resuelto. Nuevamente lo digo, sos realmente bueno en lo tuyo.
Ahora voy a probarlo y luego te cuento cómo me fue.
Mil millones de gracias, no te das una idea la mano que me diste.
Hasta luego. Un abrazo.-

ariel_fnx

Hola Leo. El código que me pasaste junto al programa que hiciste en C para calcular los precios unitarios funciona a la perfección, y he podido hacer andar la impresora fiscal correctamente.
Dos millones de gracias por tu ayuda y por tu tiempo.
Sólo me resta seguir aprendiendo.
Gracias y éxitos.-

leogtz

Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

Demente117

Hola soy nuevo, primero no se si va aki en este pagina pero creo que si, perdonad por si me "ekivoko".
tengo 2 dudas




1. Voy a intentar explikarme, creo que es sencillo (supongo!!!) quiero hacer una lista como en el comando dir /b pero que incluya las subcarpetas tambien.
me explico: quiero conseguir hacer

@echo off
dir /b /s>"nombre de archivo.txt"

pero que el resultado no incluya las rutas de los archivos, como hace por defecto

@echo off
dir /b>"nombre del archivo.txt"

en definitiva pretendo hacer que quede solo el nombre del archivo en cada linea

he estado modificando (por que para crear no es que sea muy bueno) el codigo

@echo off
setlocal enabledelayedexpansion
for /f "tokens=* delims=" %%x in ('type nombre.txt') do (
set linea=%%x
set linea=!linea:C:\Prueba=!
call :show !linea!
)
:show
echo.%* >> nombre2.txt

pero no consigo mi proposito, mi idea es hacer una lista.txt y luego modificar el archivo quitando hasta el ultimo caracter "\" de las rutas pero no consigo hacer bien el codigo por que si cambio la carpeta donde ejecuto el bat, como tiene otra ruta no me sirve, tengo que hacer otros muxos bats para mi proposito lo kual es muuuuuu costosssoooooooo jejejejej

ALGUIEN me podria ayudar??
espero haberme explikado bien, mis preguntas serian:

1 ¿¿¿¿con el codigo anterior se podria hacer?????
¿¿¿¿se podria especificar que quiero cambiar todo lo que haya hasta el ultimo "\"????


2 ¿¿ se podria cambiar mas de una palabra en concreto con el mismo codigo anterior?? 
ejemplo para que me entendais mejor:

@echo off
setlocal enabledelayedexpansion
for /f "tokens=* delims=" %%x in ('type nombre.txt') do (
set linea=%%x
set linea=!linea:  .avi   .mpg   .mkv=!
call :show !linea!
)
:show
echo.%* >> nombre2.txt


algo asi, que por ejemplo si se trata de una terminacion de archivo que no solo sea un tipo que sean todos los posibles.


ojala me pudierais ayudar!!!!!
espero que si no he puesto este mensaje en mal sitio no tengo ni idea, me acabo de registrar para ver si alguien me puede ayudar con esto, es el primer cuadro de texto que he visto.

leogtz

Edita tu mensaje y pon el código con sus respectivas etiquetas para que se te pueda ayudar, o me veré en la penosa necesidad de eliminar el mensaje ya que no cumple las reglas (hay que leerlas).

Saludos.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com