Terminado curso avanzado de bases de datos con Delphi Prism!!

.NET, Delphi Prism 8 Comentarios »

Pues después de un largo tiempo de trabajo por fin está terminado el curso avanzado de bases de datos con Delphi Prism.  El objetivo del curso es poner en práctica los conocimientos teóricos adquiridos en los cursos básicos de Delphi Prism. En este curso se desarrolla una pequeña aplicación de facturación la cuál contiene todos los elementos necesarios para desarrollar una aplicación en el mundo real.  Como ya es costumbre el curso utiliza Firebird como manejador de base de datos y está basado en el curso de C# de Ian Marteens, se hicieron las correspondientes adaptaciones y mejoras para aprovechar todas las características tanto de Firebird como de Delphi Prism además de agregar cosas que son especificas para Delphi Prism.

Aquí muestro el temario de este curso, si necesita mayor información por favor pónganse en contacto conmigo.

Módulo 0 DISEÑO DE LA BASE DE DATOS
INSTALACIÓN DE LA DLL
FUNCIONES DE USUARIOS: NORMALIZACIÒN
ELEMENTOS COMUNES: CLAVES PRIMARIAS
COLUMNAS COMUNES
REGLAS SIMPLES BASADAS EN EL PAÍS
CLIENTES, DIRECCIONES Y ATRIBUTOS
EL MODELO DE PRODUCTOS
FACTURAS
REGLAS DE NEGOCIO Y PRECIOS DE VENTA

Módulo 1 GESTIÓN DE VENTANAS
MDI, SDI O MODELO DE PESTAÑAS
GESTORES DE VENTANAS
GESTORES DE MENÚS
REFLEXION
MANIOBRAS  DENTRO DE UN MENÚ
EL GESTOR EN MARCHA

Módulo 2 VENTANAS NO MODALES
EL GESTOR DE VENTANAS
APLICACIONES MDI
INTEGRACIÓN CON EL GESTOR DEL MENÚ

Módulo 3 MÓDULOS DE DATOS
LA ORGANIZACIÓN DEL PROYECTO
INTERFACES GENÉRICAS DE ACCESO A DATOS
COMPONENTES E INSTANCIAS GLOBALES

Módulo 4 VENTANAS DE NAVEGACIÓN
¿QUÉ ES UNA “VENTANA”?
FRAGMENTOS DE UNA VENTANA DECONSTRUIDA
¿EDICIÓN… SOBRE UNA REJILLA?
CONTROLES DE USUARIO
CAMBIOS EN LOS GESTORES DE MENÚS Y VENTANAS
GUARDAR LOS CAMBIOS
HERENCIA VISUAL

Módulo 5 ALGORITMOS BÁSICOS DE NAVEGACIÓN Y EDICIÓN
PROPIEDADES VISIBLES EN TIEMPO DE DISEÑO
EL ALGORITMO BÁSICO DE INICIALIZACIÓN
¿HAY CAMBIOS?
EL ALGORITMO BÁSICO DE GRABACIÓN
CONCILIACIÓN EN PRESENCIA DE CAMPOS AUTONUMERICOS
ACTUALIZACIÓN DEL ESTADO DE ELEMENTOS VISUALES

Módulo 6 CONSULTAS SOBRE TABLAS SENCILLAS
UNA CONEXIÓN CENTRAL
CONFIGURACIÓN DE LOS ADAPTADORES
CREACIÓN DE LOS CONJUNTOS DE DATOS CON TIPOS
IMPLEMENTACIÓN DEL ACCESO PARA LECTURA
LAS VENTANAS DE PAÍSES E IMPUESTOS

Módulo 7 RECUPERACIÓN DE REGISTROS POR PÁGINAS
UNA INTERFAZ GENÉRICA PARA LA RECUPERACIÓN POR GRUPOS
GENERACIÓN DINÁMICA DE CONSULTAS
MÁS REGISTROS POR FAVOR
INICIALIZACIÓN

Módulo 8 EDICIÓN MODAL
DIÁLOGOS MODALES Y OPERACIONES SOBRE DATOS
EL MOMENTO MÁS ADECUADO
EL GESTOR DE VENTANAS ASUME RESPONSABILIDADES
UN NOBLE LINAJE DE EDITORES MODALES
ENLACES CON LA VISTA DE DATOS

Módulo 9  CONTROLES PARA NAVEGACIÓN Y EDICIÓN
AUTOMATIZANDO LA EDICIÓN
CREACIÓN DE REGISTROS
BORRADOS
REAPROVECHANDO BOTONES
RELECTURA TRAS LA GRABACION
RETOQUES EN EL CONJUNTO DE DATOS

Módulo 10  REGLAS DE NEGOCIO DURANTE LA EDICIÓN
UN ADAPTADOR PARA PRODUCTOS
REGLAS DE NEGOCIO Y CONJUNTOS DE DATOS
¿QUIÉN VIGILA AL VIGILANTE?

Módulo 11  ALMACENAMIENTO EN CACHE
UNA CACHE DE CORTA VIDA
PERSISTENCIA XML
EL MOMENTO DEL ULTIMO CAMBIO
COMPARANDO CON LA VERSION LOCAL
UN SEGURO DE VIDA

Módulo 12  BÚSQUEDAS
UN REPASO A LA LISTA DE PALABRAS
PROCEDIMIENTOS ALMACENADOS QUE RETORNAN VALORES
DESMENUZANDO CADENAS

Módulo 13 NAVEGACIÓN MAESTRO/DETALLES
CLIENTES Y ATRIBUTOS
PRIMERA APROXIMACIÓN
PROPAGACIÓN DE FILTROS
EXTENSIONES DEL SISTEMA DE PAGINACIÓN

Módulo 14 BÚSQUEDAS BASADAS EN ATRIBUTOS
SINTAXIS DE LAS CADENAS DE BÚSQUEDA
ENUMERADORES
GENERACIÓN DE CONSULTAS

Módulo 15 RESOLUCIÓN DE REFERENCIAS
COLUMNAS BASADAS EN EXPRESIONES
EL ORDEN DE LAS LECTURAS
COMBOS PARA LA EDICIÓN DE REFERENCIAS

Módulo 16 EDICIÓN DE ENTIDADES CON ESQUEMAS ABIERTOS
ENLACE A DATOS ARTESANAL
TRANSACCIONES
GRABACIÓN MAESTRO/DETALLES
PROPAGANDO LOS CAMBIOS A LA VENTANA DE NAVEGACIÓN

Módulo 17  VALIDACIÓN
MÁS RESPONSABILIDADES PARA IWINDOW
EL PROVEEDOR DE ERRORES
VERIFICACIÓN MEDIANTE EXPRESIONES REGULARES
TRAMPAS DE ERRORES

Módulo 18  SELECCIÓN DE REGISTROS EN TABLAS GRANDES
CREACIÓN DE FACTURAS Y SELECCIÓN DE CLIENTES
EL DIÁLOGO DE EDICIÓN DE FACTURAS
EL CLIENTE QUIERE SUS GALLETAS
UN DIÁLOGO PARA LA SELECCIÓN
TRÁFICO DE DATOS
CUANDO SE TRATA DE UN NUEVO CLIENTE…

Módulo 19  GRABACIÓN DE FACTURAS
EL ALGORITMO DE GRABACIÓN
UNA ENREDADA CORTINA DE DISPAROS
ADAPTACIONES A LA EDICIÓN MAESTRO/DETALLES
COMPROBACIONES SOBRE LÍNEAS DE FACTURAS
NOTIFICACIONES ENTRE VENTANAS
NOTIFICACIONES DURANTE LAS ACTUALIZACIONES
CENTINELA ALERTA

Módulo 20  EXTENSIBILIDAD MEDIANTE SCRIPTS
EN BUSCA DEL VALLE DE LA EXTENSIBILIDAD PERDIDA
EXTENSIBILIDAD MEDIANTE CÓDIGO DINÁMICO
MOTORES DE SCRIPT
UN, DOS, TRES, PROBANDO…
REGLAS PARA DETERMINAR DESCUENTOS
EL MOTOR DE DESCUENTOS
APLICANDO LAS REGLAS

Módulo 21 NAVEGACIÓN SOBRE FACTURAS
ES NATURAL NAVEGAR SOBRE UN ENCUENTRO
CAMBIO DE SENTIDO
BÚSQUEDA Y NAVEGACIÓN SOBRE FACTURAS
LA VERSIÓN MÁS RECIENTE DE LA FACTURA

Módulo 22  MENSAJES DE ERROR
RESTRICCIONES CON NOMBRE
ADAPTANDO LOS MENSAJES AL CONTEXTO

Módulo 23  RECUPERACIÓN DE ERRORES DE CONCURRENCIA
CASOS ESPECIALES
CÓMO DISTINGUIR LOS ERRORES DE CONCURRENCIA
RELECTURA Y MEZCLA
ADVERTENCIAS Y ALTERNATIVAS

Curso C# de Ian Marteens traducido a Delphi Prism

.NET, Delphi Prism 5 Comentarios »

Hola amigos, pues es un gusto informarles que parece que he llegado a un acuerdo con Ian Marteens para pasar su curso de C# a Delphi Prism.

El curso que ahora mismo estoy traduciendo es el ejercicio práctico (programa de facturación) voy en el módulo 10 y en lugar de usar SQL Server estoy utilizando Firebird ya que la mayoría de la gente que programamos en Delphi utilizamos este manejador de base de datos.

Pronto estará disponible la primera parte del de este curso. También me da gusto informarles que Ian ya está trabajando en nuevos cursos de C#, los cuales, si Ian lo permite estaré traduciendo a Delphi Prism.

Es un gran trabajo pero creo que vale la pena ya que Ian (aunque ya no trabaja con Delphi) es un emblema de Delphi y que mejor que poder poner a disposición de la comunidad Delphi sus cursos que siempre nos han sido muy útiles.

Esperen noticias pronto.

Saludos

Uso de Contains en LINQ

.NET, Delphi Prism Sin Comentarios »

En muchas ocasiones cuando estamos desarrollando una aplicación necesitamos obtener los elementos de una colección que contengan o no un conjunto de elementos.

Para esta tarea, en LINQ hacemos uso de la extensión Contains.

Para poner un ejemplo similar y así pode entender de que hablo observe la siguiente instrucción SQL:

Select * from Tabla Where campo Not In (‘Valor1’,’Valor2’….)

En esta instrucción SQL estamos obteniendo los valores de la tabla que no estén dentro del conjunto de valores que estamos especificando.

Vamos a ver como lograr algo similar utilizando LINQ.

El siguiente ejemplo es únicamente demostrativo y está escrito en Delphi Prism.

Comenzamos por crear una clase muy simple de productos frutales por ejemplo:

type
TProducto = public class
public
   property fruta : String;
end;

Y el código de ejemplo demostrativo de LINQ y Contains sería:

var frutas : array of String := ['Peras','Platanos'];
var ColeccionProductos : List<TProducto> := new List<TProducto>();
ColeccionProductos.Add(new TProducto(fruta := 'Naranjas'));
ColeccionProductos.Add(new TProducto(fruta := 'Peras'));
ColeccionProductos.Add(new TProducto(fruta := 'Limones'));
ColeccionProductos.Add(new TProducto(fruta := 'Platanos'));
var ElementosProductos := from elemento in ColeccionProductos
                                     where not (frutas.Contains(elemento.fruta.ToString()))
                                     select elemento;
ColeccionProductos :=  ElementosProductos.ToList();
for each item in ColeccionProductos do
   MessageBox.Show(item.fruta);

Como podemos ver en este ejemplo, creamos una colección de frutas y una matriz con el nombre de dos frutas.
Lo que queremos obtener son todas las frutas que no están contenidas en la matriz.
Es decir, todas las frutas que no son ni Peras ni Plátanos.
En SQL estándar serían las frutas NOT IN (‘Peras’, ‘Platanos’).
Adicionalmente, también podemos hacer uso de las funciones Lambda, por lo que todo el funcionamiento anterior, se resumiría de la siguiente manera (equivalente de la anterior):

var frutas : array of String := ['Peras','Platanos'];
var ColeccionProductos : List<TProducto> := new List<TProducto>();
ColeccionProductos.Add(new TProducto(fruta := 'Naranjas'));
ColeccionProductos.Add(new TProducto(fruta := 'Peras'));
ColeccionProductos.Add(new TProducto(fruta := 'Limones'));
ColeccionProductos.Add(new TProducto(fruta := 'Platanos'));
ColeccionProductos := ColeccionProductos.Where((n) -> not (frutas.Contains(n.fruta.ToString()))).ToList();
for each item in ColeccionProductos do
  MessageBox.Show(item.fruta);

Espero que quede clara (para quien lo necesite) la funcionalidad, beneficios y usos de Contains en LINQ.

Expresiones regulares Parte 1

.NET 9 Comentarios »

En esta ocasión quiero hablar de las expresiones regulares, una herramienta muy útil pero también un poco complicado de comprender.

Las expresiones regulares son una manera estándar de buscar y reemplazar de manera opcional apariciones de subcadenas y patrones de texto. Si no conoces las expresiones regulares, sólo piensa en los caracteres comodines que usa el indicador de comandos para indicar un grupo de archivos (como *.txt) o en los caracteres especiales que puede usar con el operador Like en las consultas SQL:

SELECT nombre,ciudad FROM Clientes WHERE nombre LIKE “A%”

Muchos expertos en computación han investigado a fondo las expresiones regulares, y algunos lenguajes de programación están excesivamente basados en ellas.  A pesar de su mucha utilidad los programadores de Microsoft Windows rara vez usan las expresiones regulares, tal vez porque su sintaxis no es muy clara.

Aspectos Generales de las expresiones regulares

Microsoft .NET Framework viene con un motor de expresiones regulares muy poderoso al que se puede acceder desde cualquier lenguaje .NET, por lo que podemos usar es poder del análisis sintáctico de lenguajes como Perl sin tener que abandonar nuestro lenguaje favorito.
Fundamentos de las expresiones regulares
Regex es la clase más importante de este grupo, y cualquier código de expresión regular crea una instancia al menos de un objeto de esta clase (o usa uno de los métodos estáticos de Regex). Este objeto representa una expresión regular inmutable. Crearemos una instancia al pasar el patrón de búsqueda:

var re : Regex := new Regex('[aeiou]\d');

El método Matches del objeto Regex aplica la expresión regular a la cadena pasada como parámetro; devuelve un objeto MatchCollection, una colección de sólo lectura que representa todas las coincidencias que no se superponen:

var re : Regex := new Regex('[aeiou]\d');
//Esta cadena de entrada contiene tres grupos
//que coinciden en el Regex
var texto : String:= 'a1:= a1 + e2';
//Obtiene la colección de coincidencias
var mc : MatchCollection := re.Matches(texto);
//¿Cuantas apariciones encontramos?
Console.WriteLine('{0} concidencias',mc.Count);
Console.ReadLine;

También podemos pasarle al método Matches en segundo parámetro, que se interpreta como el índice donde comienza la búsqueda.
El objeto matchCollection contiene objetos Match individuales, que exponen propiedades como:

  • Value.- La cadena coincidente que se encontró.
  • Index.- La posición de la cadena coincidente en la cadena de entrada.
  • Length.- La longitud de la cadena coincidente, que es útil cuando la expresión regular coincide con cadenas de diversas longitudes.

El código anterior despliega estas líneas en la ventana de consola:

a1 en la posición 0
a1 en la posición 5
e2 en la posición 10

El lenguaje de expresiones regulares

En las siguientes tablas presento una lista de todas las construcciones legales como patrones de expresiones regulares, agrupados en las siguientes categorías:

  • Caracteres de escape.- Se usan para sustituir caracteres individuales. Los necesitamos para manejar los caracteres que no se imprimen (como los caracteres de nueva línea y de tabulador) y para proporcionar versiones de escape para los caracteres que tienen un significado especial en patrones de expresiones regulares. Junto con las sustituciones, éstas son las únicas secuencias que pueden aparecer en un modelo de reemplazo.
  • Clases de caracteres.- Ofrecen una manera de hacer coincidir un carácter de un grupo que se especifica entre corchetes como en el ejemplo de [aeiou]. No necesita tener caracteres especiales de escape cuando aparecen entre corchetes, con excepción de los casos del guión y el corchete de cierre, que son los únicos caracteres que tienen un significado especial entre corchetes. Por ejemplo, [()[\]{}] hace coincidir paréntesis, corchetes y llaves de apertura y cierre. (Hay que observar que el carácter] es de escape, pero el carácter [ no lo es.)
  • Aserciones atómicas de ancho cero.- Especifican dónde debe ir la cadena coincidente pero no consumen caracteres. Por ejemplo, la expresión regular abc$ coincide con cualquier palabra abc que esté inmediatamente antes del final de una línea sin coincidir con el final de la línea.
  • Cuantificadores.- Especifican que una subexpresión se debe repetir un número de veces determinado. Un cuantificador particular se aplica al carácter, clase de caracteres o grupo que lo precede inmediatamente. Por ejemplo, \w+ corresponde a todas las palabras con uno o más caracteres, mientras que \w{3,} corresponde a todas las palabras con tres caracteres, cuando menos. Los cuantificadores se dividen en dos categorías: expansivos y laxos. Un cuantificador expansivo, como * y +, siempre coincide con la mayor cantidad de caracteres posible, mientras que uno laxo, como *? Y +?, intenta coincidir con la menor cantidad de caracteres que sea posible.
  • Construcciones de agrupamiento.- Pueden capturar y nombrar grupos de subexpresiones, además de incrementar la eficiencia de las expresiones regulares con modificadores de búsquedas anticipadas y búsquedas tardías sin captura. Por ejemplo, (abc)+ coincide con secuencias repetidas de la cadena “abc”, (?<total>\d+) coincide con un grupo de uno o más dígitos consecutivos y le asigna el nombre total, que se puede usar después dentro del mismo modelo de expresión regular o para sustitución.
  • Sustituciones.- Sólo se pueden usar dentro de un modelo de reemplazo y, junto con los caracteres de escape, son las únicas construcciones que se pueden usar en patrones de reemplazo. Por ejemplo, cuando la secuencia ${total} aparece en un modelo de reemplazo, inserta el valor del grupo llamado total. Los paréntesis no tienen un significado especial en un modelo de reemplazo, así que no necesita caracteres de escape.
  • Construcciones de referencia inversa.- Nos permiten hacer referencia a un grupo anterior de caracteres en el modelo de expresión regular usando su número o nombre de grupo. Podemos usar estas construcciones como una manera de decir “coincidir otra vez con los mismo”. Por ejemplo, (?<valor>\d+)=\k<valor> hace coincidir números idénticos separados por un símbolo =, como en la secuencia “123=123”.
  • Construcciones de alternancia.- Proporcionan una manera de especificar opciones; por ejemplo, la secuencia “Yo (tengo|tenía)” puede hacer coincidir las cadenas “Yo tengo” y “Yo tenía”.
  • Construcciones diversas.- Incluyen que permiten modificar una o más opciones de una expresión regular en medio del modelo. Por ejemplo, A(?i)BC coincide con todas las variantes de la palabra ABC que comienzan con A mayúscula (como Abc, ABc, AbC, y ABC).

Categoría

Secuencia

Descripción

Caracteres de escape Cualquier carácter Los caracteres distintos de .$^{[(|)*+?\ equivalen a sí mismos.
\a El carácter de alarma de campana (igual que \x07)
\b El carácter de retroceso (igual que \x08), pero sólo cuando se usa entre corchetes o en un modelo de reemplazo. De otra manera, coincide con el límite de una palabra.
\t El carácter de tabulación (igual que \x09)
\r El retorno de carro (igual que \x0B)
\v El carácter de tabulación vertical
\f El carácter de avance de página
\n El carácter de nueva línea
\e El carácter de escape
\040 Un carácter ASCII expresado en notación octal (debe ser de hasta tres dígitos octales). Por ejemplo, \040 es un espacio.
\x20 Un carácter ASCII expresado en notación hexadecimal (debe tener exactamente dos dígitos). Por ejemplo, \x20 es un espacio.
\cC Un carácter de control Unicode. Por ejemplo, \cC es control + C.
\u0020 Un carácter ASCII en notación (debe tener exactamente cuatro dígitos). Por ejemplo, \u0020 es un espacio.
\* Cuando la diagonal invertida va seguida de un carácter en una manera que no forma una secuencia de escape, coincide con el carácter. Por ejemplo, \* coincide con el carácter *.

Categoría

Secuencia

Descripción

Clases de caracteres . El carácter de punto coincide con cualquier carácter, con excepción del carácter de nueva línea. Coincide con cualquier carácter, incluido el de nueva línea, si se usa la opción Singleline.
[aeiou] Cualquier carácter de la lista entre corchetes de apertura y cierre; [aeiou] coincide con cualquier vocal.
[^aeiou] Cualquier carácter que no esté en la lista entre corchetes de apertura y cierre; [^aeiou] no coincide con vocal alguna.
[a-zA-Z] El carácter de guión (-) permite especificar intervalos de caracteres: [a-zA-Z] coincide con cualquier carácter en minúscula o en mayúscula; [^0-9] con cualquier carácter que no sea in dígito. Sin embargo, hay que tomar en cuenta que no coincide con las letras acentuadas.
[a-z-[aeiou]] Sustracción de clases de caracteres: cuando un par de corchetes está anidado en otro par de corchetes y va precedido de un signo de menos, la expresión regular coincide con todos los caracteres del par externo pero no con los del interno. Por ejemplo, [a-z[aeiou]] coincide con cualquier carácter en minúscula que no sea una vocal.
\w Un carácter de una palabra, que es un carácter alfanumérico o el carácter de subrayado, igual que [a-zA-Z_0-9] pero también excluye letras acentuadas y otros símbolos alfabéticos.
\W Un carácter que no es de una palabra; igual que [^a-zA-Z_0-9] pero también excluye letras acentuadas y otros símbolos.
\s Un carácter de espacio en blanco, que es un espacio en blanco, un tabulador, un avance de página, una nueva línea, un retorno de carro o un carácter de avance vertical; igual que [\f\n\r\t\v].
\S Un carácter que no es un espacio en blanco; igual que [^\f\n\r\t\v]
\d Un dígito decimal; igual que [0-9].
\D Un carácter que no es un dígito; igual que [^0-9].
\p{nombre} Un carácter incluido en la clase de caracteres con nombre especificado por {nombre}; los nombre soportados son grupos Unicode e intervalos de bloques, por ejemplo, LI Nd o Z.
\P{nombre} Un carácter no incluido en grupos e intervalos de bloques especificados en {nombre}.
Entradas RSS Comentarios RSS Acceder