Boletín Pascal #19
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
Boletín Pascal #19 - 25-MAR-2001 INDICE 1. UNAS PALABRAS DEL EDITOR 2. PROGRAMACION EN DELPHI - EVALUACION DE EXPRESIONES AL MODO XBASE - INTRODUCCION - EVALUAR EXPRESIONES DADAS COMO CADENAS DE CARACTERES - SER O NO SER HE ALLI EL DILEMA - ¿COMO SE EVALUAN EXPRESIONES? - ¿Y LAS VARIABLES? - NO PODEMOS USAR CASE...OF - BUSQUEDA BINARIA - IMPLEMENTACION DE BUSQUEDAS POR "HASHING" - DONDE SQL NO HA IDO JAMAS - NOTAS RESPECTO AL EJEMPLO - VOLVIENDO AL PAQUETE - LO PROXIMO 3. CAPTURANDO MENSAJES DE LA APLICACION 4. ARREGLOS DINAMICOS - ARREGLOS DINAMICOS MULTIDIMENSIONALES 5. ARTICULOS EN LA COMUNIDAD BORLAND - DELPHI · Construcción de componentes para el profesional - por Ray Konopka · Migrando de Visual Basic a Delphi - por el Personal de Borland · Fundido de imágenes - Reporte de laboratorio de Earl F. Glynn II · Usando efectivamente listas de acciones - por Ray Konopka · Recursos matemáticos para Delphi - KYLIX · ¿Está listo para Kylix? - por David Intersimone · Aventuras en Kylix - por James R. Knowles · Código fuente de FreeCLX disponible en SourceForge - por John Ray Thomas - INTERBASE · 30 días de Paradox a InterBase - por Skip Rowland · InterBase V6 - Mejoras de Rendimiento - por Dave Schnepper · Los ABCs de migrar de InterBase 5 a InterBase 6 - por Mark Duquette · APIs de instalación y licencias de InterBase - por Personal de Inprise ________________________________________________________________________ 1. UNAS PALABRAS DEL EDITOR Me complace anunciar que el ganador de la licencia de la Librería JfControls es Santiago Cubero, un joven programador de Barcelona (España), quien tenía asignado el número 62. En esta edición tengo el agrado de presentar otro gran artículo de Alirio Gavidia que en esta oportunidad nos mostrará cómo evaluar expresiones en tiempo de ejecución en nuestras aplicaciones Delphi. Saludos, Ernesto De Spirito eds2004 @ latiumsoftware.com ________________________________________________________________________ JfControls Lib. Multilenguaje. Multiapariencia. Skins. Privilegios. Más de 40 componentes integrados y personalizables. Múltiples problemas de programación resueltos. Administración centralizada de recursos. Para Delphi 3-7 y C++ Builder 3-6. http://www.jfactivesoft.com/spindex.htm ________________________________________________________________________ 2. PROGRAMACION EN DELPHI - EVALUACION DE EXPRESIONES AL MODO XBASE Por Alirio A. Gavidia B. INTRODUCCION ------------ Hace un par de años se me encargó resolver un problema común de "Compatibilidad". Este era el poder evaluar desde Delphi expresiones xBase (por xBase entendemos a dBase y sus derivados como Clipper y FoxPro). Todo este asunto sucede porque los lenguajes xBase basados todos en alguna forma de interpretación soportan lo que se conoce como "Macros" (no confundir el almacenamiento de una serie de comandos y acciones para su repetición posterior). Los programadores, en muchas ocasiones, solicitan del usuario la definición de filtros para luego aplicarlos directamente como expresiones (mala práctica si el usuario no sabe escribir expresiones aritméticas bajo la sintaxis requerida). EVALUAR EXPRESIONES DADAS COMO CADENAS DE CARACTERES ---------------------------------------------------- La aplicación creada en aquella oportunidad solicita expresiones al usuario como filtros para búsquedas, consultas y reportes, pero cada vez que lo hace presenta un botón que despliega un formulario de diálogo con los elementos para construir la expresión. La expresión es tipo xBase así que si el usuario conoce aplicaciones de ese tipo puede dar su expresión directamente. SER O NO SER HE ALLI EL DILEMA ------------------------------ En principio se presentaron dos alternativas: 1.- Crear un control para evaluar expresiones xBase. 2.- Usar un control ya existente. La tercera, enseñarle SQL a los usuarios fue desechada por el principio de compatibilidad con la aplicación anterior. Existen algunos componentes interesantes a este respecto, de hecho encontré que existen dos conjuntos de componentes para ello: Orientados a aritmética y Orientados a bases de datos. Los primeros son prácticos, bonitos, baratos (hay varios freeware) pero suelen estar orientados a la resolución de gráficas y problemas matemáticos. Los segundos consideran el asunto de los campos, me interesé por los componentes del segundo tipo. Terminé usando un reemplazo del BDE con soporte para archivos de Clipper que acepta expresiones xBase como filtros. Sin embargo, paralelamente desarrollé algunas funciones para evaluar expresiones (están en mi página personal y son gratuitas, sólo documentadas en español) como parte de esta artículo presento la clase Texpression. Por otro lado desarrollé un conjunto de componentes (estos si son shareware en inglés y con documentación inglés/español) que permiten evaluar expresiones del tipo: (CLIENTE->FECNAC>CTOD('01/01/1900')) .AND. CREDITO cuando la mayoría de los componentes para evaluar fórmulas no pasan de expresiones constantes como: 3-2/3.14 ¿COMO SE EVALUAN EXPRESIONES? ----------------------------- Por lo general hay dos pasos: el análisis (búsqueda) de patrones y como segundo la combinación de los valores obtenidos en el paso previo para obtener un resultado. La búsqueda de patrones (lexicografía) permite reconocer entre una serie de caracteres el tipo y funcionalidad de ciertos patrones. Por ejemplo reconocer si una palabra empieza por un dígito indica que posiblemente es un número constante (o un error), si no es así posiblemente la palabra es un identificador que define algún valor u operador que altera un valor. Descubiertos los patrones estos de almacenan en alguna estructura de datos (normalmente una pila, lo he visto con dos pilas también) y se reducen en combinando valores según corresponda a los identificadores. Al final lo que queda es el resultado de la expresión en la pila. ¿Y LAS VARIABLES? ----------------- Las variables y las constantes y en fin cualquier cosa asociada a un identificador debe ser provisto por el programador a través de un evento o una lista. Los componentes que presento consideran estas dos vías. También consideran arreglos y funciones (varias predefinidas, fundamentalmente similares a las de Clipper). Por ejemplo: HalSimpleExpr.Eval('Variable*Pi()') En este caso hay dos identificadores "Variable" y "Pi". Como el segundo es seguido por un par de paréntesis es una función. El componente dispara el evento OnRequestIdentifier (para evaluar Variable) y OnRequestFunction (para evaluar Pi). La evaluación de Pi sería manejada así: procedure TForm1.HalSimpleExpr1RequestFunction(Sender: TObject; ident: String; var value: Variant; var cancel: Boolean); Var col, row : integer; begin if CompareText(ident,'Pi')=0 then value := Pi else cancel := true end; Nota: Debo señalar que hay un gran ausente entre los parámetros del evento; este es un arreglo con los argumentos de la función. Para una próxima versión el argumento de la función evaluada será parte de los parámetros por lo pronto es sólo un campo público en la clase. Por cierto verán que si la función no es Pi el control dispara una excepción (eso define el parámetro "cancel"). La solución para evaluar "Variable" es análoga pero con otro evento. Todo esto funciona muy bien hasta que tenemos unas 50 funciones. NO PODEMOS USAR CASE...OF ------------------------- No es posible el uso de la sentencia "case" debido a que esta funciona para tipos "contables" (enteros, caracteres, boléanos y similares) y la alternativa de implementar un "if" tras otro es eficiente para el primer identificador pero terrible para los últimos. El siguiente paso es usar una lista, pero ordenada. BUSQUEDA BINARIA ---------------- La búsqueda binaria sobre listas ordenadas parece una buena alternativa, si hablamos de 1000 elementos podremos hallar cualquier valor el 50% de las veces en unos 10 pasos (el otro 50% en menos). En la mayoría de los casos esto es muy bueno, sin embargo hay una alternativa digna de estudio. IMPLEMENTACION DE BUSQUEDAS POR "HASHING" ----------------------------------------- Mejor que revisar una lista es tener una función que de antemano señale la posición del identificador en la lista. Por ejemplo una función que sume el primer carácter, el último menos 97 y la longitud de la cadena, así si buscamos la palabra "program" aplicaríamos algo como IndexOf("program") que resultaría en Ord('p') + Ord('m') + Length('program'). Esto es 112 + 109 + 7 – 97 -> 131. De allí a la posición 131 de la tabla. Como se entiende la búsqueda por tablas de "Hash" mejoran los esfuerzos de búsqueda notablemente. Sin embargo, desperdician memoria. Queda al programador definir que camino usar, sin embargo, lo componentes que refiero como shareware presentan listas de este tipo como parte de su funcionamiento intrínseco. DONDE SQL NO HA IDO JAMAS ------------------------- Resulta que SQL resuelve bien los problemas en cuanto a filtros y búsquedas. Pero que pasa si quiero hacer algo menos voluminoso como una pequeña hoja de cálculo definible en sus formulas por el usuario. Por ello anexo un ejemplo usando un "stringrid" y la clase TExpression. Creo que en general hay pequeñas necesidades en las cuales puede resultar conveniente el uso de un evaluador de formulas más allá de querer imitar las macros xBase. NOTAS RESPECTO AL EJEMPLO ------------------------- El ejemplo es un control "TstringGrid" donde se hace uso de las propiedades "Cells" y "Objects". La primera presenta el resultado de un formula que es almacenado en "Objects". Los "strings" deben ser especificados con comillas simples. Los archivos que salva/carga son de texto simple. Cada fórmula definida requiere la presión de la tecla 'ok' para ser almacenada. Hay definido un evento para manejar la función "Cell(c,r)" donde 'c' es columna y 'r' fila. VOLVIENDO AL PAQUETE -------------------- El uso es simple, un método: eval. Con un parámetro la expresión dada como un "string". Sin embargo, hay diferentes métodos según el tipo a manejar. Los componentes consideran distintos tipos de sintaxis: xBase, Basic, Pascal y Java. Fundamentalmente alterando el uso de operadores lógicos entre puntos como lo hacen en expresiones xBase. Tres componentes con distintos alcances: ThalSimpleExpr, ThalMacroExpr y ThalArithmeticExpr. El primero carece de funciones y manejo de listas de identificadores, el segundo implementa unas 75 funciones, el manejo de listas y referencias a datasets. El tercero no tiene el manejo de "alias" ni datasets, sin embargo, soporta muchas de las funciones predefinidas. Los detalles están documentados con el paquete y hay ejemplos incluidos. Espero lo disfruten. Pueden bajar el demo shareware directamente de mi página personal en http://www.gavidia.org/he-shareware.zip También lo pueden solicitar a la dirección de correo delphi@gavidia.org. Para el ejemplo adjunto a este artículo http://www.latiumsoftware.com/descarga/p0019.zip En http://www.gavidia.org/pod hay material freeware relacionado con el tema. LO PROXIMO ---------- Me tomaré el tiempo para dar información respecto a las listas por "Hashing" que aquí mencioné. Para la próxima entrega ese será el tema. ------------------------------ Copyright © 2001 por Alirio A. Gavidia B. Todos los derechos reservados. Se permite la publicación de este material por cualquier medio por parte de cualquiera siempre que este no sea modificado en contenido y se cite la fuente original. ________________________________________________________________________ 3. CAPTURANDO MENSAJES DE LA APLICACION A veces necesitamos capturar los mensajes de Windows a nivel de la aplicación. Una forma es con un "hook" (gancho), y la otra es usando el evento Message del objeto Application que se produce cada vez que la aplicación recibe un mensaje de Windows. Vamos a seguir el segundo camino. Hay dos formas de establecer un manejador para este evento: una es usando un objeto ApplicationEvents que viene con Delphi 5 (simple- mente hay que hacer doble-clic en el cuadro combinado del evento OnMessage en el Inspector de Objetos) y la otra es haciéndolo "a mano": 1) En la sección privada de su formulario principal agregue la siguiente declaración: procedure ApplicationMessage(var Msg: TMsg; var Handled: Boolean); 2) Asigne la propiedad OnMessage en el evento Create del formulario, por ejemplo: procedure TForm1.FormCreate(Sender: TObject); begin Application.OnMessage := ApplicationMessage; end; 3) Cuando desee dejar de capturar mensajes todo lo que tiene que hacer es establecer OnMessage en nil: procedure TForm1.FormDestroy(Sender: TObject); begin Application.OnMessage := nil; end; Finalmente debe implementar el procedimiento. Por ejemplo, vamos a atrapar los mensajes de teclado WM_KEYUP y WM_KEYDOWN para convertir el punto decimal del teclado numérico en una coma (esto es útil en aplicaciones hispanas). procedure TForm1.ApplicationMessage(var Msg: TMsg; var Handled: Boolean); begin case Msg.Message of WM_KEYDOWN, WM_KEYUP: case Msg.wParam of // Reemplazar el punto del teclado numerico (key code = 110) // por una coma (key code = 188). 110: Msg.wParam := 188; end; end; end; Ahora puede colocar un control Edit en su formulario y probarlo. ________________________________________________________________________ 4. ARREGLOS DINAMICOS Los arreglos dinámicos son arreglos que pueden crecer o achicarse en tiempo de ejecución para acomodar más o menos elementos. La declaración de un arreglo dinámico es parecida a la de un arreglo estático, excepto que el rango de índices se omite. Por ejemplo: var a: array of integer; Un arreglo dinámico inicialmente no tiene elementos. Puede usar el procedimiento SetLength en su código para asignar el número de elementos que necesita. Puede llamar a SetLength tantas veces como sea necesario. Si la nueva longitud es mayor que el número actual de elementos, se agrega espacio para nuevos elementos, y si es menor entonces los últimos elementos del arreglo son descartados. Por ejemplo SetLength(a, 10) asigna espacio para 10 elementos. Los elementos en un arreglo dinámico se indexan comenzando por 0 hasta uno menos que la longitud del arreglo, así que por ejemplo el siguiente código se puede usar para inicializar los elementos de un arreglo en cero: for i := 0 to Length(a)-1 do a[i] := 0; En el ejemplo adjunto a este artículo verá el uso de un arreglo dinámico para guardar los nombres de los archivos en un directorio. Naturalmente, una lista de cadenas (stringlist) sería mejor para la tarea, pero se usó un arreglo dinámico por propósitos pedagógicos. ARREGLOS DINAMICOS MULTIDIMENSIONALES ----------------------------------- Un arreglo dinámico de dos dimensiones puede declararse así: var a: array of array of integer; De esta forma podrá asignar ambas dimensiones en tiempo de ejecución. El procedimiento SetLength admite tantos parámetros "NewLength" (nueva longitud) como dimensiones. Por ejemplo SetLength(a, 10, 10) establecería un arreglo cuadrado de 10 x 10. Un cosa interesante es que en vez de ver el arreglo como una matriz (es decir rectangular) puede verse como un vector de vectores que no necesa- riamente tienen que tener el mismo número de elementos. Por ejemplo el siguiente código crea un arreglo "triangular" e inicializa sus elementos con números consecutivos: k := 0; SetLength(a, 4); // 4 filas for i := 0 to 3 do begin // Por cada fila SetLength(a[i], i + 1); // Establece el número de columnas for j := 0 to i do begin // Inicializa la fila a[i,j] := k; inc(k); end; end; 0 1 2 3 +---+ 0 | 0 | +---+---+ 1 | 1 | 2 | +---+---+---+ 2 | 3 | 4 | 5 | +---+---+---+---+ 3 | 6 | 7 | 8 | 9 | +---+---+---+---+ ________________________________________________________________________ 5. ARTICULOS EN LA COMUNIDAD BORLAND Este mes se pueden encontrar algunas cosas interesantes en la Comunidad Borland. Todo en inglés, claro, pero bueno... DELPHI ====== * Construcción de componentes para el profesional - por Ray Konopka Este artículo describe los críticos pasos extra que deben seguirse para desarrollar componentes profesionales de calidad profesional. Temas específicos incluyen creación de ayuda del componente en línea, diseño efectivo de paquetes para la distribución del componente, soporte de múltiples versiones de Delphi, y cómo soportar la instalación automática de en un solo paso. http://community.borland.com/article/0,1410,27057,00.html * Migrando de Visual Basic a Delphi - por el Personal de Borland http://community.borland.com/article/images/26225/vbtodelphi.pdf * Fundido de imágenes - Reporte de laboratorio de Earl F. Glynn II Este artículo demuestra cómo fundir un fondo y una imagen de frente desvaneciendo de una imagen a la otra, pero sólo a lo largo de un borde de transición dibujado con una simple herramienta de dibujo. http://www.efg2.com/Lab/ImageProcessing/Feathering.htm * Usando efectivamente listas de acciones - por Ray Konopka Este artículo describe, en detalle, lo que las acciones y las listas de acciones pueden hacer por una aplicación. http://community.borland.com/article/0,1410,27058,00.html * Recursos matemáticos para Delphi He aquí un compendio de recursos matemáticos para Delphi http://www.efg2.com/Lab/Library/Delphi/MathInfo/Resources.htm KYLIX ===== * ¿Está listo para Kylix? - por David Intersimone ¿Está listo para Kylix? Por supuesto que lo está. ¿Está su sistema listo para Kylix? He aquí una forma de averiguarlo. http://community.borland.com/article/0,1410,26998,00.html * Aventuras en Kylix - por James R. Knowles Descripción de una primera experiencia con Kylix http://www.ifm-services.com/people/jamesk/kylix/ * Código fuente de FreeCLX disponible en SourceForge - por John Ray Thomas FreeCLX, el proyecto código abierto de la Librería de Componentes CLX de Borland para Linux ahora está abierto para colaboración. http://community.borland.com/article/0,1410,27100,00.html INTERBASE ========= * 30 días de Paradox a InterBase - por Skip Rowland Este artículo examina los problemas, las "curitas", las soluciones, y los éxitos encontrados durante una gran migración de Paradox a InterBase http://community.borland.com/article/0,1410,27006,00.html * InterBase V6 - Mejoras de Rendimiento - por Dave Schnepper Este artículo cubre cambios en InterBase 6 que directa o indirec- tamente mejorarán la velocidad y rendimento general de las consultas. http://community.borland.com/article/0,1410,27005,00.html * Los ABCs de migrar de InterBase 5 a InterBase 6 - por Mark Duquette Este artículo técnico es para ayudarlo a aprender los detalles a la vsta y ocultos de migrar sus aplicaciones desde InterBase 5 hacia InterBase 6. http://community.borland.com/article/0,1410,27004,00.html * APIs de instalación y licencias de InterBase - por Personal de Inprise InterBase 6 tiene una nueva API de instalación que automatiza muchas tareas involucradas en la incrustación de bases de datos en una aplicación. Esta sesión describe la API y cómo usarla. http://community.borland.com/article/0,1410,26415,00.html ________________________________________________________________________ ¡TÚ PUEDES AYUDARNOS! Necesitamos tu ayuda para que este boletín pueda continuar y crecer. Una forma en que puedes ayudarnos es enviando este enlace a tus amigos: http://www.latiumsoftware.com/es/pascal/index.php Otra forma es votándonos en alguno de estos rankings para darle más visibilidad a nuestro sitio web y aumentar así el número de suscrip- ciones al boletín, que esperamos en el futuro se traduzca también en un mayor número de colaboraciones de artículos, trucos, etc.: http://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium http://news.optimax.com/topdelphi/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://www.top219.org/cgi-bin/vote.cgi?delphi&83 http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium http://213.65.224.200/cgi-bin/toplist.cgi/hits?Id=80 http://www.programacion.net/votar-enlace.php?id=474 http://www.lawebdelprogramador.com/buscar/enlace.php?id=615 Por favor vota. Son sólo unos segundos para ti que REALMENTE pueden hacer la diferencia. Necesitamos tu ayuda para poder continuar. ________________________________________________________________________ Si no has recibido el archivo con el código fuente completo de los ejemplos que se presentan en este boletín, puedes descargarlo de la siguiente dirección: http://www.latiumsoftware.com/descarga/p0019.zip ________________________________________________________________________ Página principal: http://www.latiumsoftware.com/es/pascal/index.php Página del grupo: http://espanol.groups.yahoo.com/group/boletin-pascal/ Para suscribirse / apuntarse: boletin-pascal-subscribe@gruposyahoo.com Para cancelar / removerse: boletin-pascal-unsubscribe@gruposyahoo.com Para reportar problemas con la suscripción: eds2004 @ latiumsoftware.com ________________________________________________________________________ Este boletín se provee "TAL Y COMO ESTA", sin garantía de ninguna clase. Su uso implica la aceptación de nuestros términos de licencia y de la ausencia de garantía que puedes leer en nuestro sitio web. Allí también encontrarás una nota sobre marcas registradas. Te animamos a que redis- tribuyas este boletín, siempre y cuando lo hagas en forma completa (incluyendo la información de copyright), sin modificaciones y de manera gratuita. Los artículos son copyright de sus respectivos autores y se reproducen aquí con el permiso de los mismos. ________________________________________________________________________ Latium Software http://www.latiumsoftware.com/es/index.php Copyright (c) 2001 por Ernesto De Spirito. Todos los derechos reservados ________________________________________________________________________ |
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
¿Errores? ¿Omisiones? ¿Comentarios? Por favor contáctanos!






