cace0353
07/05/14, 18:07:42
ANTECEDENTES
A raíz de un artículo que publiqué en este mismo foro relativo al uso de variables y matrices en Tasker: http://www.htcmania.com/showthread.php?t=815063
me surgió la idea de realizar una tarea "multipropósito" para procesar datos almacenados en variables preparadas para ser convertidas en matrices.
En posts posteriores del mismo hilo, y ayudado por los comentarios y aportaciones de Caravantes y Mlesir, la idea fué tomando cuerpo. Planteé la posibilidad de partir de hojas de cálculo previas de Excel, convirtiéndolas en archivos separados por comas y leyendo el archivo correspondiente desde Tasker, etc. (me remito al hilo reseñado donde se explica el procedimiento).
Puse manos a la obra y la tarea-base tomó forma. Luego empecé a añadir módulos de la forma "Devuélveme el dato que está en Fila-Columna", "Encuentra la media de los valores de la columna Cx", "Dime que valores de la columna Cy son mayores que un valor V", "Borra la fila Fn", "Dame el valor correspondiente al valor X de la columna Cn en la columna C1"... Todo al estilo de las fórmulas de Excel, pero en Tasker... El número de sub-tareas se iba multiplicando y complicando sin parar.
Entonces me dí cuenta de dos cosas:
a) Si queria hacer un programa de procesamiento de bases de datos iba mal encaminado, lo adecuado no era usar Tasker sino SQlite. Ya me lo habian sugerido los gurús del foro, pero uno es tozudo por naturaleza y hasta que no ve con sus ojos el sol, no para de andar a oscuras dando trompicones. Además, el "así no podrás" me estimula ;-)
b) La cantidad de prestaciones distintas que se me ocurrian no paraba de crecer. Para testear el trabajo que estaba haciendo me propuse un par de programas que utilizaban bases de datos en tablas Excel. Habia tal cantidad de particularidades a procesar para cada caso que abandoné definitivamente la idea. Es mejor que para cada caso el programador busque la solución más adecuada según su criterio.
PROGRAMA EINES (herramientas)
https://dl.dropboxusercontent.com/u/13481585/th_Screenshot_2014-05-07-23-34-18.png
https://dl.dropboxusercontent.com/u/13481585/th_Screenshot_2014-05-06-23-48-16.pnghttps://dl.dropboxusercontent.com/u/13481585/th_Screenshot_2014-05-06-23-48-00.png
El programa que presento són, en realidad, tres herramientas de uso común (y espero que útiles) que planteo como el resultado de mis prácticas y como un ejemplo del procesamiento de datos en matrices de 2 dimensiones a partir de tablas Excel.
CALCULO DE LA LETRA DEL NIF
Este és un programillo elemental y que tenia realizado en Excel. Sirve para calcular la letra del NIF a partir del número del DNI (8 caracteres)
Como seguramente sabreis, la letra se calcula haciendo la división entera del número del DNI por 23 y comparando el resto de la división con una lista de letras ordenadas de forma distinta a la del abecedario.
A cada resto le corresponde una letra y no hay más.
El programa parte de dos variables escritas en el propio cuerpo de la tarea y preparadas para ser convertidas en dos matrices lineales: los restos y las letras.
Se efectúa la división entera (%Num_Dni%23) y se compara, usando un bucle con un contador, el resultado con la lista de letras: a cada resto le corresponde una letra. Se acaba devolviendo el resultado a la escena general.
CALCULO DEL IBAN, NOMBRE DEL BANCO Y COMPROBACIÓN DE LOS DÍGITOS DE CONTROL DE LA CUENTA
Este programa ya es más complejo. Usa una tabla Excel extraida de internet con los nombres de entidades bancarias y el código de entidad correspondiente. Se ha preparado la tabla eliminando las cajas rurales. A pesar de todo queda una tabla de dos filas (codigo de entidad y nombre del banco) y 136 columnas. En total 272 datos.
La tarea IBAN monta la matriz a partir del archivo Taula-bancs.csv y compara el código de entidad de la cuenta entrada en la escena con los de la matriz para extraer el Nombre de la entidad.
El cálculo del IBAN es bastante complejo y se ha realizado a partir del procedimiento explicado aquí:
https://kutxa.kutxabank.es/cs/Satellite?blobcol=urldata&blobheader=application%2Fpdf&blobheadername1=Expires&blobheadername2=content-type&blobheadername3=MDT-Type&blobheadername4=Content-disposition&blobheadervalue1=Thu%2C+10+Dec+2020+16%3A00%3A00+G MT&blobheadervalue2=application%2Fpdf&blobheadervalue3=abinary%3Bcharset%3DUTF-8&blobheadervalue4=inline%3B+filename%3DC%C3%A1lculo +de+IBAN.pdf&blobkey=id&blobtable=MungoBlobs&blobwhere=1311844840805&ssbinary=true
En esencia consiste en obtener una cifra de 26 dígitos añadiendo al final de los 20 del nº de la cuenta 142800, que es el número que corresponde a España (14 por la E y 28 por la S) seguido de 00. Se obtiene el resto de la división entera por 97 y se resta el resultado de 98 obteniendo un número de dos cifras. Si el resultado es menor que 10 se antepone un 0. El código IBAN correspondiente será ESXX.
El problema surge en la división de un número tan grande: según se explica al final del texto en el link puesto, hay que realizar el cálculo por partes... Esto se hace en la misma tarea IBAN.
Para la comprobación de los dígitos de control hay una tarea específica "Comprovar DC" que es llamada por la tarea IBAN y que multiplica uno a uno los dígitos de la entidad y nº oficina por una serie de números determinados para obtener el primer DC. Luego se procesan de igual manera los 20 números de la cuenta para obtener el segundo DC. Según el procedimiento explicado por el tal Luciano aquí:
http://www.luciano.es/utiles/ccc.htm
Si el DC escrito en la casilla correspondiente es incorrecto se pone en fondo rojo y aparece un flash de alerta.
DETERMINACIÓN DEL CODIGO POSTAL, CIUDAD, COMARCA, PROVINCIA Y ALTITUD A PARTIR TANTO DEL CODIGO POSTAL COMO DE LAS 4 PRIMERAS LETRAS DEL NOMBRE DE LA POBLACIÓN
El tercer programa ya es otro cantar. Aquí la base de datos (solo para Catalunya) contiene 1008 nombres de población, y para cada uno de ellos hay los sigüientes datos: Código Postal, Nombre de la población, Comarca y Altitud topográfica: en total 4.032 datos (la provincia la extraigo a partir del CP..., no iba a añadir una columna con 1008 datos más!)
La base de partida es una hoja de Excel que formaba parte de un programa de cálculo (también en Excel) que utilizaba profesionalmente para determinar los valores de aislamiento térmico necesarios en las viviendas dependiendo de su ubicación.
Hay también, supongo, otras hojas parecidas para otras comunidades y cada uno podrá "trabajárselas" en el PC para adaptarlas. Una base de datos para toda España se escapa de mis pretensiones (ni aunque me piquéis!)
Para la consulta y extracción de datos de una base tan grande he partido del sigüiente procedimiento:
1) He preparado la base de datos en Excel y he hecho dos copias del archivo. Una con la primera columna conteniendo los nombres de los municipios ordenados alfabéticamente (Municipi-CP.csv) para la búsqueda por nombre de la población y otro archivo (CP-Municipi.csv) con la primera columna conteniendo los CP ordenados numéricamente para la búsqueda por el nº de C.Postal. Son, en realidad, dos copias del mismo archivo transponiendo la primera columna y ordenando por ésta el resto de datos.
2) Para la subtarea para la búsqueda por código postal "Cercar per CP" he localizado en la tabla de los CP (en Excel) los nº de línea en los que empiezan y acaban los CP de cada una de las 4 provincias. La subtarea mira primero cual es el primer dígito con valor del CP, creandose unos índices de principio y final del rango donde buscar en la tabla ordenada (%Index1 y %Index2) para cada provincia. Según sea el valor del primer caracter del CP de la población (8, 1, 2 o 4), se buscará en el rango acotado por %Index1 y %Index2... (si el CP es de Barcelona ciudad, del 08002 al 08042 salta directamente al final para evitar tener 40 lineas suplementarias iguales en la tabla...). La subtarea lee el archivo CP-Municipi.csv y se busca el CP entrado para la búsqueda en la lista acotada por %Index1 y %Index2.
3) Para la búsqueda por Población (la entrada en el campo de texto editable es de 4 caracteres) he localizado en la tabla de los nombres (en Excel), grupos de letras con un número de datos más o menos alrededor de 100. Así hay un grupo que empieza con A (indices de fila del 1 al 78), otro para la B (indices del 78 al 148), etc. y en la tarea Cercar per Nom he preparado una variable %lletres que contiene los pares de índices para cada letra del abecedario usada (no hay nombres de pueblos con K ni con W, Y o Z en Catalunya), separando los grupos de índices para cada letra con el separador "+".
La subtarea mira primero cual es la primera letra del nombre y busca en la matriz de 2 dimensiones %lletres (escrita al inicio de la tarea) los indices que acotan la búsqueda completa. Esta técnica me permite trabajar con un grupo más reducido de poblaciones, ya que se establecen para cada letra los %Index1 y %Index2 entre los que se buscará el nombre en la lista total de municipios (una cierta forma de indexar). Si no lo hubiera hecho así comprobé que podia tardar hasta 25 segundos en encontrar un nombre en toda la lista!
Luego, el programa abre el archivo correspondiente (Municipi-CP.csv) y prepara la matriz en la que se buscarán (solo en el rango %Index1-%Index2) las 4 letras que se han proporcionado en la escena de entrada. Cuando se encuentran coincidencias se almacenan con Array Push en una matriz lineal los nombres completos y el código postal. Si se acaban las coincidencias se muestra una escena con un menú donde se muestran las poblaciones cuyas 4 primeras letras coinciden con el criterio de búsqueda entrado. Elegimos la que necesitamos y automáticamente se nos muestra la escena principal con el resto de datos correspondientes. Si sólo hay una coincidencia se obvia el último paso y se muestra directamente el resultado en la escena principal.
LISTADO DE LAS TAREAS "Cercar Per Nom" y "Cercar Per CP" con <comentarios>
Cercar Per Nom (109)
Abortar Tarea Existente
A1: Establecer variable [ Nombre:%lletres A:A;1;78+B;79;148+C;149;262+D;263;315+E;263;315+F; 263;315+G;316;379+H;316;379+I;380;427+J;380;427+L; 380;427+M;428;511+N;512;636+O;512;636+P;512;636+Q; 637;684+R;637;684+S;685;853+T;854;913+U;914;1008+V ;914;1008+X;914;1008 Calcular:Apagado Añadir:Apagado ] La matriz que permite asociar letras con índices
A2: Sección de Variable [ Nombre:%Poblacio Desde:1 Longitud:1 Encajar:Apagado Almacenar Resultado en:%temporal ]
A3: Separar variable [ Nombre:%lletres Separador:+ Eliminar base:Apagado ]
A4: Establecer variable [ Nombre:%cont A:1 Calcular:Encendido Añadir:Apagado ]
<Busca la 1a lletra del nom>
A5: For [ Variable:%prov Ítems:%lletres(:) ]
A6: Sección de Variable [ Nombre:%prov Desde:1 Longitud:1 Encajar:Apagado Almacenar Resultado en:%prov ]
A7: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Continua ] Si (if) [ %temporal ~ %prov ]
A8: Sumar a variable [ Nombre:%cont Valor:1 Módulo (wrap around):0 ]
A9: End For
<Continua>
A10: Destino (de goto)
A11: Establecer variable [ Nombre:%lletres A:%lletres(%cont) Calcular:Apagado Añadir:Apagado ]
A12: Separar variable [ Nombre:%lletres Separador:; Eliminar base:Apagado ]
<Determina el rang de l'arxiu de dades on buscar>
A13: Establecer variable [ Nombre:%Index1 A:%lletres2 Calcular:Encendido Añadir:Apagado ]
A14: Establecer variable [ Nombre:%Index2 A:%lletres3 Calcular:Encendido Añadir:Apagado ]
<Obre l'arxiu i carrega les dades>
A15: Leer Archivo [ Archivo:Tasker/Municipi_CP.csv A la variable:%noms_pobles ]
A16: Buscar y Reemplazar Contenido de Variable [ Variable:%noms_pobles Buscar:\n Ignore Case:Apagado Multi-Line:Apagado One Match Only:Apagado Almacenar Coincidencias En: Reemplazar Coincidencias:Encendido Reemplazar Con:# ]
A17: Separar variable [ Nombre:%noms_pobles Separador:# Eliminar base:Apagado ]
A18: Array Clear [ Nombre:%Noms_pobles ]
<pels 2 casos que comencen amb Host>
A19: Si (if) [ %Poblacio ~ Host ] Este es el caso particular de que empieze por "Host"
A20: Array Push [ Nombre:%Noms_pobles Posición:1 Valor:Hostalets de Pierola - 8781 Rellenar Espacios:Apagado ]
A21: Array Push [ Nombre:%Noms_pobles Posición:2 Valor:Hostalric - 17450 Rellenar Espacios:Apagado ]
A22: Establecer variable [ Nombre:%cont A:65 Calcular:Encendido Añadir:Apagado ]
A23: Establecer variable [ Nombre:%repet A:2 Calcular:Encendido Añadir:Apagado ]
A24: Establecer variable [ Nombre:%Index1 A:316 Calcular:Encendido Añadir:Apagado ]
A25: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Ja Et Tinc ]
A26: Fin si (End if)
A27: Establecer variable [ Nombre:%repet A:0 Calcular:Encendido Añadir:Apagado ]
A28: Establecer variable [ Nombre:%cont A:1 Calcular:Encendido Añadir:Apagado ]
<Buscar el nom del poble en el rang…>
A29: For [ Variable:%temporal Ítems:%noms_pobles(%Index1:%Index2) ]
A30: Separar variable [ Nombre:%temporal Separador:; Eliminar base:Apagado ]
A31: Sección de Variable [ Nombre:%temporal1 Desde:1 Longitud:4 Encajar:Encendido Almacenar Resultado en:%nom_curt ]
<Si troba coincidencies, el guarda i segueix buscant…>
A32: Si (if) [ %Poblacio ~ %nom_curt ]
A33: Establecer variable [ Nombre:%repet A:%repet+1 Calcular:Encendido Añadir:Apagado ]
A34: Array Push [ Nombre:%Noms_pobles Posición:%repet Valor:%temporal1 - %temporal2 Rellenar Espacios:Apagado ]
A35: Fin si (End if)
<Si ja no hi ha mes repeticions, acaba i va al final>
A36: Si (if) [ %Poblacio !~ %nom_curt & %repet > 0 ]
A37: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Ja Et Tinc ]
A38: Fin si (End if)
A39: Sumar a variable [ Nombre:%cont Valor:1 Módulo (wrap around):0 ]
<Si no l'ha trobat incrementa %cont i segueix buscant...>
A40: End For
<Si no l'ha trobat al final de la llista, ho comunica i acaba…>
A41: Flash [ Texto:ATENCIÓ:
No s'ha trobat la Població que has escrit %Poblacio o ja la tens a pantalla. Largo:Apagado ]
A42: Detener [ Con error:Apagado Tarea:Cercar Per Nom ]
<Ja Et Tinc>
A43: Destino (de goto)
<Si nomes hi ha un poble, acaba…>
A44: Si (if) [ %repet ~ 1 ]
A45: Establecer variable [ Nombre:%definitiu A:%Index1+%cont-2 Calcular:Encendido Añadir:Apagado ]
A46: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:nomes hi ha un poble ]
A47: Fin si (End if)
<Pero si n'hi ha varis obre una escena-menu pet triar…>
A48: Mostrar Escena [ Nombre:Escollir Poble Mostrar como:Actividad, Pantalla Completa, Sin Título Posición Horizontal:100 Posición Vertical:100 Animación:Desvanecer Mostrar Botón Salida:Apagado Continuar tarea inmediatamente:Apagado ]
A49: Establecer variable [ Nombre:%definitiu A:%Index1+%cont-%repet+%Index_triat-2 Calcular:Encendido Añadir:Apagado ]
<nomes hi ha un poble>
A50: Destino (de goto)
A51: Establecer variable [ Nombre:%temporal A:%noms_pobles(%definitiu) Calcular:Apagado Añadir:Apagado ]
A52: Separar variable [ Nombre:%temporal Separador:; Eliminar base:Apagado ]
A53: Establecer variable [ Nombre:%retorn A:%temporal2;%temporal1;%temporal3;%temporal4 Calcular:Apagado Añadir:Apagado ]
A54: Realizar tarea [ Nombre:EINES-Iban Parar:Apagado Prioridad:10 Parámetro 1 (%par1):%retorn Parámetro 2 (%par2): Devolver Valor de Variable: ]
Cercar Per CP (110)
A1: Sección de Variable [ Nombre:%C_postal Desde:1 Longitud:1 Encajar:Apagado Almacenar Resultado en:%temporal ]
A2: Establecer variable [ Nombre:%Index1 A:0 Calcular:Encendido Añadir:Apagado ]
<Si es un poble de la prov. de Barcelona>
A3: Si (if) [ %temporal ~ 8 ]
A4: Establecer variable [ Nombre:%Index1 A:1 Calcular:Encendido Añadir:Apagado ]
A5: Establecer variable [ Nombre:%Index2 A:346 Calcular:Encendido Añadir:Apagado ]
<pels CP de Barcelona ciutat…> Esto evita tener 42 lineas en la B de datos para Barcelona ciudad
A6: Si (if) [ %C_postal > 08000 & %C_postal < 08043 ]
A7: Establecer variable [ Nombre:%retorn A:%C_postal;Barcelona;Barcelonès;50 Calcular:Apagado Añadir:Apagado ]
A8: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:nomes per Barcelona ]
A9: Fin si (End if)
A10: Fin si (End if)
<Si es de la prov. de Girona>
A11: Si (if) [ %temporal ~ 1 ]
A12: Establecer variable [ Nombre:%Index1 A:347 Calcular:Encendido Añadir:Apagado ]
A13: Establecer variable [ Nombre:%Index2 A:574 Calcular:Encendido Añadir:Apagado ]
A14: Fin si (End if)
<Si es de Lleida>
A15: Si (if) [ %temporal ~ 2 ]
A16: Establecer variable [ Nombre:%Index1 A:575 Calcular:Encendido Añadir:Apagado ]
A17: Establecer variable [ Nombre:%Index2 A:811 Calcular:Encendido Añadir:Apagado ]
A18: Fin si (End if)
<I si es de Tarragona…>
A19: Si (if) [ %temporal ~ 4 ]
A20: Establecer variable [ Nombre:%Index1 A:812 Calcular:Encendido Añadir:Apagado ]
A21: Establecer variable [ Nombre:%Index2 A:1008 Calcular:Encendido Añadir:Apagado ]
A22: Fin si (End if)
A23: Flash [ Texto:ATENCIO!
No hi ha pobles a Catalunya amb aquest codi postal… Largo:Apagado ] Si (if) [ %Index1 ~ 0 ]
A24: Leer Archivo [ Archivo:Tasker/CP_Municipi.csv A la variable:%codis_postals ]
A25: Buscar y Reemplazar Contenido de Variable [ Variable:%codis_postals Buscar:\n Ignore Case:Apagado Multi-Line:Apagado One Match Only:Apagado Almacenar Coincidencias En: Reemplazar Coincidencias:Encendido Reemplazar Con:# ]
A26: Separar variable [ Nombre:%codis_postals Separador:# Eliminar base:Apagado ]
A27: For [ Variable:%temporal Ítems:%codis_postals(%Index1:%Index2) ]
A28: Separar variable [ Nombre:%temporal Separador:; Eliminar base:Apagado ]
A29: Si (if) [ %C_postal ~ %temporal1 ]
A30: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Ja Et Tinc ]
A31: Fin si (End if)
A32: End For
<Ja Et Tinc>
A33: Destino (de goto)
A34: Establecer variable [ Nombre:%retorn A:%temporal1;%temporal2;%temporal3;%temporal4 Calcular:Apagado Añadir:Apagado ]
<nomes per Barcelona> para venir directo aquí si on CP de Barcelona ciudad
A35: Destino (de goto)
A36: Realizar tarea [ Nombre:EINES-Iban Parar:Apagado Prioridad:10 Parámetro 1 (%par1):%retorn Parámetro 2 (%par2): Devolver Valor de Variable: ] BUGS CONOCIDOS
1.- Cuando se ha hecho una búsqueda por C.Postal o por Población no puede repetirse la búsqueda volviendo a darle en "Calcular" ya que %new_val coincide con el valor existente... Para resolverlo tendria que crear una nueva variable global y ya tengo demasiadas... Si quieres repetir la misma búsqueda debes teclear el nombre o el CP nuevo.
2.- (bug resuelto gracias a Caravantes) Algunos caracteres (à è ç) propios de mi idioma son mostrados como un caracter "raro". Lo mismo pasa con la Ñ (en los nombres de banco que contienen la palabra ESPAÑA o ESPAÑOL). Intuyo que serà por la tabla de còdigos ASCII usada por Tasker, ya que el teclado si que los "pica". He intentado editar la tabla de datos con Notepad++, pero ni así...Si algún compañero conoce la solución, le agradeceré que la aporte en este mismo hilo.
3.- (bug resuelto con un "arreglillo") Si busco por nombre de población empezando por "Host" (en Catalunya hay dos poblaciones que empiezan por Host: Hostalric y Hostalets de Pierola) el programa no es capaz de encontrarlos. Pienso que se debe a que "Host" coincide con alguna palabra reservada del sistema relacionada con el alojamiento en redes. He resuelto el problema de una manera particular para estas dos poblaciones desviando el flujo del programa para estos dos casos (acciones de la 19 a la 26 de la tarea Cercar Per Nom).
CONCLUSIONES
1.- He abandonado la pretensión inicial de hacer una macro-tarea multipropósito para el proceso de bases de datos a partir de hojas de cálculo de Excel DEFINITIVAMENTE. O es "poco-propósito" o se hace muuuuy complicada. Si supiera manejar SQLite quizás, pero no con Tasker.
2.- Evidentemente Tasker no es un lenguaje de programación pero, a lo largo de los cuatro o cinco programas completos que he realizado y que he compartido en este foro, he visto que tiene mucho juego. Se puede hacer "casi" de todo... y, sobre todo, divirtiéndome!
3.- Voy a hacer un pequeño alto en el camino, no sea que, como ya me ocurrió programando con AutoLisp (dialecto de LISP para Autocad), acabe pensando en "¿para que podria hacer un programa ahora?"
Saludos a todos. Espero que mi trabajo os sea útil.
NOTAS
- La base de elaboración es Tasker 4.3u4 en Android 4.0+
- Los archivos .CSV, tal como los busca el programa, deben estar en la carpeta Tasker. Esto puede modificarse cambiando las rutas de acceso en las correspondientes tareas.
ENLACES en Dropbox al XML y los archivos de datos CSV: actualizados 9-05-2014 a las 19:00
El XML: https://dl.dropboxusercontent.com/u/13481585/EINES.prj.xml
Los datos en CSV: https://dl.dropboxusercontent.com/u/13481585/CP_Municipi.csv https://dl.dropboxusercontent.com/u/13481585/Municipi_CP.csv
Los datos de los bancos y códigos de entidad: https://dl.dropboxusercontent.com/u/13481585/Taula-bancs.csv
En formato texto: https://dl.dropboxusercontent.com/u/13481585/EINES.txt
A raíz de un artículo que publiqué en este mismo foro relativo al uso de variables y matrices en Tasker: http://www.htcmania.com/showthread.php?t=815063
me surgió la idea de realizar una tarea "multipropósito" para procesar datos almacenados en variables preparadas para ser convertidas en matrices.
En posts posteriores del mismo hilo, y ayudado por los comentarios y aportaciones de Caravantes y Mlesir, la idea fué tomando cuerpo. Planteé la posibilidad de partir de hojas de cálculo previas de Excel, convirtiéndolas en archivos separados por comas y leyendo el archivo correspondiente desde Tasker, etc. (me remito al hilo reseñado donde se explica el procedimiento).
Puse manos a la obra y la tarea-base tomó forma. Luego empecé a añadir módulos de la forma "Devuélveme el dato que está en Fila-Columna", "Encuentra la media de los valores de la columna Cx", "Dime que valores de la columna Cy son mayores que un valor V", "Borra la fila Fn", "Dame el valor correspondiente al valor X de la columna Cn en la columna C1"... Todo al estilo de las fórmulas de Excel, pero en Tasker... El número de sub-tareas se iba multiplicando y complicando sin parar.
Entonces me dí cuenta de dos cosas:
a) Si queria hacer un programa de procesamiento de bases de datos iba mal encaminado, lo adecuado no era usar Tasker sino SQlite. Ya me lo habian sugerido los gurús del foro, pero uno es tozudo por naturaleza y hasta que no ve con sus ojos el sol, no para de andar a oscuras dando trompicones. Además, el "así no podrás" me estimula ;-)
b) La cantidad de prestaciones distintas que se me ocurrian no paraba de crecer. Para testear el trabajo que estaba haciendo me propuse un par de programas que utilizaban bases de datos en tablas Excel. Habia tal cantidad de particularidades a procesar para cada caso que abandoné definitivamente la idea. Es mejor que para cada caso el programador busque la solución más adecuada según su criterio.
PROGRAMA EINES (herramientas)
https://dl.dropboxusercontent.com/u/13481585/th_Screenshot_2014-05-07-23-34-18.png
https://dl.dropboxusercontent.com/u/13481585/th_Screenshot_2014-05-06-23-48-16.pnghttps://dl.dropboxusercontent.com/u/13481585/th_Screenshot_2014-05-06-23-48-00.png
El programa que presento són, en realidad, tres herramientas de uso común (y espero que útiles) que planteo como el resultado de mis prácticas y como un ejemplo del procesamiento de datos en matrices de 2 dimensiones a partir de tablas Excel.
CALCULO DE LA LETRA DEL NIF
Este és un programillo elemental y que tenia realizado en Excel. Sirve para calcular la letra del NIF a partir del número del DNI (8 caracteres)
Como seguramente sabreis, la letra se calcula haciendo la división entera del número del DNI por 23 y comparando el resto de la división con una lista de letras ordenadas de forma distinta a la del abecedario.
A cada resto le corresponde una letra y no hay más.
El programa parte de dos variables escritas en el propio cuerpo de la tarea y preparadas para ser convertidas en dos matrices lineales: los restos y las letras.
Se efectúa la división entera (%Num_Dni%23) y se compara, usando un bucle con un contador, el resultado con la lista de letras: a cada resto le corresponde una letra. Se acaba devolviendo el resultado a la escena general.
CALCULO DEL IBAN, NOMBRE DEL BANCO Y COMPROBACIÓN DE LOS DÍGITOS DE CONTROL DE LA CUENTA
Este programa ya es más complejo. Usa una tabla Excel extraida de internet con los nombres de entidades bancarias y el código de entidad correspondiente. Se ha preparado la tabla eliminando las cajas rurales. A pesar de todo queda una tabla de dos filas (codigo de entidad y nombre del banco) y 136 columnas. En total 272 datos.
La tarea IBAN monta la matriz a partir del archivo Taula-bancs.csv y compara el código de entidad de la cuenta entrada en la escena con los de la matriz para extraer el Nombre de la entidad.
El cálculo del IBAN es bastante complejo y se ha realizado a partir del procedimiento explicado aquí:
https://kutxa.kutxabank.es/cs/Satellite?blobcol=urldata&blobheader=application%2Fpdf&blobheadername1=Expires&blobheadername2=content-type&blobheadername3=MDT-Type&blobheadername4=Content-disposition&blobheadervalue1=Thu%2C+10+Dec+2020+16%3A00%3A00+G MT&blobheadervalue2=application%2Fpdf&blobheadervalue3=abinary%3Bcharset%3DUTF-8&blobheadervalue4=inline%3B+filename%3DC%C3%A1lculo +de+IBAN.pdf&blobkey=id&blobtable=MungoBlobs&blobwhere=1311844840805&ssbinary=true
En esencia consiste en obtener una cifra de 26 dígitos añadiendo al final de los 20 del nº de la cuenta 142800, que es el número que corresponde a España (14 por la E y 28 por la S) seguido de 00. Se obtiene el resto de la división entera por 97 y se resta el resultado de 98 obteniendo un número de dos cifras. Si el resultado es menor que 10 se antepone un 0. El código IBAN correspondiente será ESXX.
El problema surge en la división de un número tan grande: según se explica al final del texto en el link puesto, hay que realizar el cálculo por partes... Esto se hace en la misma tarea IBAN.
Para la comprobación de los dígitos de control hay una tarea específica "Comprovar DC" que es llamada por la tarea IBAN y que multiplica uno a uno los dígitos de la entidad y nº oficina por una serie de números determinados para obtener el primer DC. Luego se procesan de igual manera los 20 números de la cuenta para obtener el segundo DC. Según el procedimiento explicado por el tal Luciano aquí:
http://www.luciano.es/utiles/ccc.htm
Si el DC escrito en la casilla correspondiente es incorrecto se pone en fondo rojo y aparece un flash de alerta.
DETERMINACIÓN DEL CODIGO POSTAL, CIUDAD, COMARCA, PROVINCIA Y ALTITUD A PARTIR TANTO DEL CODIGO POSTAL COMO DE LAS 4 PRIMERAS LETRAS DEL NOMBRE DE LA POBLACIÓN
El tercer programa ya es otro cantar. Aquí la base de datos (solo para Catalunya) contiene 1008 nombres de población, y para cada uno de ellos hay los sigüientes datos: Código Postal, Nombre de la población, Comarca y Altitud topográfica: en total 4.032 datos (la provincia la extraigo a partir del CP..., no iba a añadir una columna con 1008 datos más!)
La base de partida es una hoja de Excel que formaba parte de un programa de cálculo (también en Excel) que utilizaba profesionalmente para determinar los valores de aislamiento térmico necesarios en las viviendas dependiendo de su ubicación.
Hay también, supongo, otras hojas parecidas para otras comunidades y cada uno podrá "trabajárselas" en el PC para adaptarlas. Una base de datos para toda España se escapa de mis pretensiones (ni aunque me piquéis!)
Para la consulta y extracción de datos de una base tan grande he partido del sigüiente procedimiento:
1) He preparado la base de datos en Excel y he hecho dos copias del archivo. Una con la primera columna conteniendo los nombres de los municipios ordenados alfabéticamente (Municipi-CP.csv) para la búsqueda por nombre de la población y otro archivo (CP-Municipi.csv) con la primera columna conteniendo los CP ordenados numéricamente para la búsqueda por el nº de C.Postal. Son, en realidad, dos copias del mismo archivo transponiendo la primera columna y ordenando por ésta el resto de datos.
2) Para la subtarea para la búsqueda por código postal "Cercar per CP" he localizado en la tabla de los CP (en Excel) los nº de línea en los que empiezan y acaban los CP de cada una de las 4 provincias. La subtarea mira primero cual es el primer dígito con valor del CP, creandose unos índices de principio y final del rango donde buscar en la tabla ordenada (%Index1 y %Index2) para cada provincia. Según sea el valor del primer caracter del CP de la población (8, 1, 2 o 4), se buscará en el rango acotado por %Index1 y %Index2... (si el CP es de Barcelona ciudad, del 08002 al 08042 salta directamente al final para evitar tener 40 lineas suplementarias iguales en la tabla...). La subtarea lee el archivo CP-Municipi.csv y se busca el CP entrado para la búsqueda en la lista acotada por %Index1 y %Index2.
3) Para la búsqueda por Población (la entrada en el campo de texto editable es de 4 caracteres) he localizado en la tabla de los nombres (en Excel), grupos de letras con un número de datos más o menos alrededor de 100. Así hay un grupo que empieza con A (indices de fila del 1 al 78), otro para la B (indices del 78 al 148), etc. y en la tarea Cercar per Nom he preparado una variable %lletres que contiene los pares de índices para cada letra del abecedario usada (no hay nombres de pueblos con K ni con W, Y o Z en Catalunya), separando los grupos de índices para cada letra con el separador "+".
La subtarea mira primero cual es la primera letra del nombre y busca en la matriz de 2 dimensiones %lletres (escrita al inicio de la tarea) los indices que acotan la búsqueda completa. Esta técnica me permite trabajar con un grupo más reducido de poblaciones, ya que se establecen para cada letra los %Index1 y %Index2 entre los que se buscará el nombre en la lista total de municipios (una cierta forma de indexar). Si no lo hubiera hecho así comprobé que podia tardar hasta 25 segundos en encontrar un nombre en toda la lista!
Luego, el programa abre el archivo correspondiente (Municipi-CP.csv) y prepara la matriz en la que se buscarán (solo en el rango %Index1-%Index2) las 4 letras que se han proporcionado en la escena de entrada. Cuando se encuentran coincidencias se almacenan con Array Push en una matriz lineal los nombres completos y el código postal. Si se acaban las coincidencias se muestra una escena con un menú donde se muestran las poblaciones cuyas 4 primeras letras coinciden con el criterio de búsqueda entrado. Elegimos la que necesitamos y automáticamente se nos muestra la escena principal con el resto de datos correspondientes. Si sólo hay una coincidencia se obvia el último paso y se muestra directamente el resultado en la escena principal.
LISTADO DE LAS TAREAS "Cercar Per Nom" y "Cercar Per CP" con <comentarios>
Cercar Per Nom (109)
Abortar Tarea Existente
A1: Establecer variable [ Nombre:%lletres A:A;1;78+B;79;148+C;149;262+D;263;315+E;263;315+F; 263;315+G;316;379+H;316;379+I;380;427+J;380;427+L; 380;427+M;428;511+N;512;636+O;512;636+P;512;636+Q; 637;684+R;637;684+S;685;853+T;854;913+U;914;1008+V ;914;1008+X;914;1008 Calcular:Apagado Añadir:Apagado ] La matriz que permite asociar letras con índices
A2: Sección de Variable [ Nombre:%Poblacio Desde:1 Longitud:1 Encajar:Apagado Almacenar Resultado en:%temporal ]
A3: Separar variable [ Nombre:%lletres Separador:+ Eliminar base:Apagado ]
A4: Establecer variable [ Nombre:%cont A:1 Calcular:Encendido Añadir:Apagado ]
<Busca la 1a lletra del nom>
A5: For [ Variable:%prov Ítems:%lletres(:) ]
A6: Sección de Variable [ Nombre:%prov Desde:1 Longitud:1 Encajar:Apagado Almacenar Resultado en:%prov ]
A7: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Continua ] Si (if) [ %temporal ~ %prov ]
A8: Sumar a variable [ Nombre:%cont Valor:1 Módulo (wrap around):0 ]
A9: End For
<Continua>
A10: Destino (de goto)
A11: Establecer variable [ Nombre:%lletres A:%lletres(%cont) Calcular:Apagado Añadir:Apagado ]
A12: Separar variable [ Nombre:%lletres Separador:; Eliminar base:Apagado ]
<Determina el rang de l'arxiu de dades on buscar>
A13: Establecer variable [ Nombre:%Index1 A:%lletres2 Calcular:Encendido Añadir:Apagado ]
A14: Establecer variable [ Nombre:%Index2 A:%lletres3 Calcular:Encendido Añadir:Apagado ]
<Obre l'arxiu i carrega les dades>
A15: Leer Archivo [ Archivo:Tasker/Municipi_CP.csv A la variable:%noms_pobles ]
A16: Buscar y Reemplazar Contenido de Variable [ Variable:%noms_pobles Buscar:\n Ignore Case:Apagado Multi-Line:Apagado One Match Only:Apagado Almacenar Coincidencias En: Reemplazar Coincidencias:Encendido Reemplazar Con:# ]
A17: Separar variable [ Nombre:%noms_pobles Separador:# Eliminar base:Apagado ]
A18: Array Clear [ Nombre:%Noms_pobles ]
<pels 2 casos que comencen amb Host>
A19: Si (if) [ %Poblacio ~ Host ] Este es el caso particular de que empieze por "Host"
A20: Array Push [ Nombre:%Noms_pobles Posición:1 Valor:Hostalets de Pierola - 8781 Rellenar Espacios:Apagado ]
A21: Array Push [ Nombre:%Noms_pobles Posición:2 Valor:Hostalric - 17450 Rellenar Espacios:Apagado ]
A22: Establecer variable [ Nombre:%cont A:65 Calcular:Encendido Añadir:Apagado ]
A23: Establecer variable [ Nombre:%repet A:2 Calcular:Encendido Añadir:Apagado ]
A24: Establecer variable [ Nombre:%Index1 A:316 Calcular:Encendido Añadir:Apagado ]
A25: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Ja Et Tinc ]
A26: Fin si (End if)
A27: Establecer variable [ Nombre:%repet A:0 Calcular:Encendido Añadir:Apagado ]
A28: Establecer variable [ Nombre:%cont A:1 Calcular:Encendido Añadir:Apagado ]
<Buscar el nom del poble en el rang…>
A29: For [ Variable:%temporal Ítems:%noms_pobles(%Index1:%Index2) ]
A30: Separar variable [ Nombre:%temporal Separador:; Eliminar base:Apagado ]
A31: Sección de Variable [ Nombre:%temporal1 Desde:1 Longitud:4 Encajar:Encendido Almacenar Resultado en:%nom_curt ]
<Si troba coincidencies, el guarda i segueix buscant…>
A32: Si (if) [ %Poblacio ~ %nom_curt ]
A33: Establecer variable [ Nombre:%repet A:%repet+1 Calcular:Encendido Añadir:Apagado ]
A34: Array Push [ Nombre:%Noms_pobles Posición:%repet Valor:%temporal1 - %temporal2 Rellenar Espacios:Apagado ]
A35: Fin si (End if)
<Si ja no hi ha mes repeticions, acaba i va al final>
A36: Si (if) [ %Poblacio !~ %nom_curt & %repet > 0 ]
A37: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Ja Et Tinc ]
A38: Fin si (End if)
A39: Sumar a variable [ Nombre:%cont Valor:1 Módulo (wrap around):0 ]
<Si no l'ha trobat incrementa %cont i segueix buscant...>
A40: End For
<Si no l'ha trobat al final de la llista, ho comunica i acaba…>
A41: Flash [ Texto:ATENCIÓ:
No s'ha trobat la Població que has escrit %Poblacio o ja la tens a pantalla. Largo:Apagado ]
A42: Detener [ Con error:Apagado Tarea:Cercar Per Nom ]
<Ja Et Tinc>
A43: Destino (de goto)
<Si nomes hi ha un poble, acaba…>
A44: Si (if) [ %repet ~ 1 ]
A45: Establecer variable [ Nombre:%definitiu A:%Index1+%cont-2 Calcular:Encendido Añadir:Apagado ]
A46: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:nomes hi ha un poble ]
A47: Fin si (End if)
<Pero si n'hi ha varis obre una escena-menu pet triar…>
A48: Mostrar Escena [ Nombre:Escollir Poble Mostrar como:Actividad, Pantalla Completa, Sin Título Posición Horizontal:100 Posición Vertical:100 Animación:Desvanecer Mostrar Botón Salida:Apagado Continuar tarea inmediatamente:Apagado ]
A49: Establecer variable [ Nombre:%definitiu A:%Index1+%cont-%repet+%Index_triat-2 Calcular:Encendido Añadir:Apagado ]
<nomes hi ha un poble>
A50: Destino (de goto)
A51: Establecer variable [ Nombre:%temporal A:%noms_pobles(%definitiu) Calcular:Apagado Añadir:Apagado ]
A52: Separar variable [ Nombre:%temporal Separador:; Eliminar base:Apagado ]
A53: Establecer variable [ Nombre:%retorn A:%temporal2;%temporal1;%temporal3;%temporal4 Calcular:Apagado Añadir:Apagado ]
A54: Realizar tarea [ Nombre:EINES-Iban Parar:Apagado Prioridad:10 Parámetro 1 (%par1):%retorn Parámetro 2 (%par2): Devolver Valor de Variable: ]
Cercar Per CP (110)
A1: Sección de Variable [ Nombre:%C_postal Desde:1 Longitud:1 Encajar:Apagado Almacenar Resultado en:%temporal ]
A2: Establecer variable [ Nombre:%Index1 A:0 Calcular:Encendido Añadir:Apagado ]
<Si es un poble de la prov. de Barcelona>
A3: Si (if) [ %temporal ~ 8 ]
A4: Establecer variable [ Nombre:%Index1 A:1 Calcular:Encendido Añadir:Apagado ]
A5: Establecer variable [ Nombre:%Index2 A:346 Calcular:Encendido Añadir:Apagado ]
<pels CP de Barcelona ciutat…> Esto evita tener 42 lineas en la B de datos para Barcelona ciudad
A6: Si (if) [ %C_postal > 08000 & %C_postal < 08043 ]
A7: Establecer variable [ Nombre:%retorn A:%C_postal;Barcelona;Barcelonès;50 Calcular:Apagado Añadir:Apagado ]
A8: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:nomes per Barcelona ]
A9: Fin si (End if)
A10: Fin si (End if)
<Si es de la prov. de Girona>
A11: Si (if) [ %temporal ~ 1 ]
A12: Establecer variable [ Nombre:%Index1 A:347 Calcular:Encendido Añadir:Apagado ]
A13: Establecer variable [ Nombre:%Index2 A:574 Calcular:Encendido Añadir:Apagado ]
A14: Fin si (End if)
<Si es de Lleida>
A15: Si (if) [ %temporal ~ 2 ]
A16: Establecer variable [ Nombre:%Index1 A:575 Calcular:Encendido Añadir:Apagado ]
A17: Establecer variable [ Nombre:%Index2 A:811 Calcular:Encendido Añadir:Apagado ]
A18: Fin si (End if)
<I si es de Tarragona…>
A19: Si (if) [ %temporal ~ 4 ]
A20: Establecer variable [ Nombre:%Index1 A:812 Calcular:Encendido Añadir:Apagado ]
A21: Establecer variable [ Nombre:%Index2 A:1008 Calcular:Encendido Añadir:Apagado ]
A22: Fin si (End if)
A23: Flash [ Texto:ATENCIO!
No hi ha pobles a Catalunya amb aquest codi postal… Largo:Apagado ] Si (if) [ %Index1 ~ 0 ]
A24: Leer Archivo [ Archivo:Tasker/CP_Municipi.csv A la variable:%codis_postals ]
A25: Buscar y Reemplazar Contenido de Variable [ Variable:%codis_postals Buscar:\n Ignore Case:Apagado Multi-Line:Apagado One Match Only:Apagado Almacenar Coincidencias En: Reemplazar Coincidencias:Encendido Reemplazar Con:# ]
A26: Separar variable [ Nombre:%codis_postals Separador:# Eliminar base:Apagado ]
A27: For [ Variable:%temporal Ítems:%codis_postals(%Index1:%Index2) ]
A28: Separar variable [ Nombre:%temporal Separador:; Eliminar base:Apagado ]
A29: Si (if) [ %C_postal ~ %temporal1 ]
A30: Ir a acción [ Tipo:Etiqueta Acción Número:1 Etiqueta:Ja Et Tinc ]
A31: Fin si (End if)
A32: End For
<Ja Et Tinc>
A33: Destino (de goto)
A34: Establecer variable [ Nombre:%retorn A:%temporal1;%temporal2;%temporal3;%temporal4 Calcular:Apagado Añadir:Apagado ]
<nomes per Barcelona> para venir directo aquí si on CP de Barcelona ciudad
A35: Destino (de goto)
A36: Realizar tarea [ Nombre:EINES-Iban Parar:Apagado Prioridad:10 Parámetro 1 (%par1):%retorn Parámetro 2 (%par2): Devolver Valor de Variable: ] BUGS CONOCIDOS
1.- Cuando se ha hecho una búsqueda por C.Postal o por Población no puede repetirse la búsqueda volviendo a darle en "Calcular" ya que %new_val coincide con el valor existente... Para resolverlo tendria que crear una nueva variable global y ya tengo demasiadas... Si quieres repetir la misma búsqueda debes teclear el nombre o el CP nuevo.
2.- (bug resuelto gracias a Caravantes) Algunos caracteres (à è ç) propios de mi idioma son mostrados como un caracter "raro". Lo mismo pasa con la Ñ (en los nombres de banco que contienen la palabra ESPAÑA o ESPAÑOL). Intuyo que serà por la tabla de còdigos ASCII usada por Tasker, ya que el teclado si que los "pica". He intentado editar la tabla de datos con Notepad++, pero ni así...Si algún compañero conoce la solución, le agradeceré que la aporte en este mismo hilo.
3.- (bug resuelto con un "arreglillo") Si busco por nombre de población empezando por "Host" (en Catalunya hay dos poblaciones que empiezan por Host: Hostalric y Hostalets de Pierola) el programa no es capaz de encontrarlos. Pienso que se debe a que "Host" coincide con alguna palabra reservada del sistema relacionada con el alojamiento en redes. He resuelto el problema de una manera particular para estas dos poblaciones desviando el flujo del programa para estos dos casos (acciones de la 19 a la 26 de la tarea Cercar Per Nom).
CONCLUSIONES
1.- He abandonado la pretensión inicial de hacer una macro-tarea multipropósito para el proceso de bases de datos a partir de hojas de cálculo de Excel DEFINITIVAMENTE. O es "poco-propósito" o se hace muuuuy complicada. Si supiera manejar SQLite quizás, pero no con Tasker.
2.- Evidentemente Tasker no es un lenguaje de programación pero, a lo largo de los cuatro o cinco programas completos que he realizado y que he compartido en este foro, he visto que tiene mucho juego. Se puede hacer "casi" de todo... y, sobre todo, divirtiéndome!
3.- Voy a hacer un pequeño alto en el camino, no sea que, como ya me ocurrió programando con AutoLisp (dialecto de LISP para Autocad), acabe pensando en "¿para que podria hacer un programa ahora?"
Saludos a todos. Espero que mi trabajo os sea útil.
NOTAS
- La base de elaboración es Tasker 4.3u4 en Android 4.0+
- Los archivos .CSV, tal como los busca el programa, deben estar en la carpeta Tasker. Esto puede modificarse cambiando las rutas de acceso en las correspondientes tareas.
ENLACES en Dropbox al XML y los archivos de datos CSV: actualizados 9-05-2014 a las 19:00
El XML: https://dl.dropboxusercontent.com/u/13481585/EINES.prj.xml
Los datos en CSV: https://dl.dropboxusercontent.com/u/13481585/CP_Municipi.csv https://dl.dropboxusercontent.com/u/13481585/Municipi_CP.csv
Los datos de los bancos y códigos de entidad: https://dl.dropboxusercontent.com/u/13481585/Taula-bancs.csv
En formato texto: https://dl.dropboxusercontent.com/u/13481585/EINES.txt