viernes, septiembre 10, 2021

¿ Quien es "alias" ?

Tengo 20 años programando en Clipper, y mas o menos 15 dando clases de programación y análisis y diseño de sistemas, de los cuales 5 estuve dando clases en la Universidad La Salle de México, como catedrático de la Escuela de Ingeniería en la carrera de Ingeniería en Cibernética y Ciencias de la Computación. 

He dirigido algunos trabajos de tesis sobre bases de datos, 2 de ellos específicamente sobre lenguajes Xbase y hasta una tesis sobre programación orientada al Objeto con FiveWin, sí sí, aunque ustedes no lo crean FiveWin fue en su momento (hace como 8 años) el tema de un trabajo de titulación profesional de 2 de mis alumnos. 

El caso es que en todos estos años pegándole a la tecla con Clipper y ahora con (x)Harbour, me he encontrado con que casi nadie saber manejar los archivos DBF en condiciones. Actualmente la idea es ir mas por el tema del SQL, pero hay muchas personas que todavía manejan archivos DBF y que conociendo un poco mas sobre ellos se pueden hacer cosas muy interesante.  

Pero vamos a ver..... ¿ como que nadie sabe usar los DBFs ?, si cientos de programadores del mundo los han usado durante años..... de acuerdo, pero de todos esos cientos de programadores, que levanten la mano aquellos que consideren que saben manejar los DBF BIEN. 

Si levantaste la mano, continúa leyendo, espero poder enseñarte algo nuevo, si no la levantaste, también continúa leyendo, seguro vas a aprender algo nuevo.  

El mito de las 256 "áreas" de trabajo. 

 Los que venimos del dBase III recordamos que en los libros ponían, dBase puede abrir hasta 256 "areas" de trabajo, entendiendo por "areas de trabjo" un espacio de memoria en donde se "abría" la tabla DBF (está mal llamarla "base de datos"), lo que en el SQL moderno de hoy se llama "cursor".

 Estas "areas" estaban numeradas, de tal forma que cuando queríamos abrir una tabla, todos hacíamos (y algunos siguen haciendo) la forma erronea de abrir la tabla:  

SELECT 1 // para seleccionar el "area" donde vamos a abrir la tabla USE archivo.dbf 

Esto quería decir que la tabla ARCHIVO.DBF estaría abierta en el "área" 1, así pues siempre que quisiéramos hacer referencia a los campos o a alguna operación sobre ARCHIVO.DBF, antes que nada tendríamos que hacer primeramente un salto al "área" donde está abierta dicha tabla, algo como esto:

SELECT 1
GO TOP
DO WHILE ! EOF()
    ? Recno()
 
SKIP
ENDDO 

La cosa comienza a ponerse interesante cuando requieres usar mas tablas simultáneamente, digamos unas 5 tablas, entonces erroneamente haces:  

SELECT 1
USE archivo1.dbf
SELECT 2 USE archivo2.dbf
......

SELECT 5 USE archivo5.dbf 

Mal, mal, mal, esto te lleva a hacer lo que yo he llamado "código ping-pong", es decir selección de área, operación, selección de otra área, otra operación, selección de otra area mas, otra operación mas, y luego vamos de vuelta al área original, lo cual nos lleva a un código lleno de SELECTs por todos sitios, que es complicado de mantener. 

Si a esto aunamos que a 16 bits el número de áreas de trabajo estaba limitado por la memoria (las 256 áreas de trabajo que prometía dBase nunca fueron ciertas), entonces nuestro código se volvía un maremagnum de saltos entre áreas, de tener que cerrar tablas para abrir otras en las mismas "áreas" de tener que acordarte en que número de área quedaba tal o cual tabla DBF de tal o cual proceso, vamos, un rollo. 

Y todo por no utilizar el "alias" de los archivos DBF.  

¿ Y quien o qué es ALIAS ? 

En todos los lenguajes de programación no orientados a datos, como Pascal, "C" o el mismo Basic, cuando se manejan archivos de datos, siempre se les asignan 2 nombres, el nombre "físico" que es el nombre del archivo tal cual se almacena en el disco, y el nombre "lógico", que es el nombre con el cual haremos referencia dentro del código de nuestro programa.

Clipper/(x)Harbour no es una excepción a esta regla, porque en realidad, SIEMPRE estas manejando 2 nombres cuando abres una tabla DBF para trabajar sobre ella, es decir, cuando haces algo como esto : 

USE archivo.dbf 

En realidad estas generando un "ALIAS", es decir, un "apodo" para hacer referencia al archivo abierto durante la ejecución de tu programa. 

Si revisas la sintaxis del comando USE, te encontrarás varias cosas interesantes:  

USE [ ; [INDEX ] ; [ALIAS ] ; [EXCLUSIVE | SHARED] ; [NEW] ; [READONLY] ; [VIA ]  

El comando USE tiene una clausula ALIAS, que si no fuera importante, creeme, no la pondrían como parte de la sintaxis. 

Esta clausula ALIAS se utiliza para darle un "nombre lógico" a tu tabla para que puedas manejarla en memoria, si tu omites este nombre, se asigna automáticamente como "alias" el mismo nombre de la tabla, sin extensión. 

 El ALIAS de una tabla es una pieza muy importante de la programación de datos porque si sabes como utilizarlo, te ahorrarás lineas y líneas de SELECTS inútiles. 

Existe un "operador ALIAS", representado por un "->" signo de menos + signo de mayor que, este operador nos servirá para hacer referencia al área de trabajo que deseamos usar sin necesidad de tener que hacer un SELECT 

Por ejemplo:  

USE archivo1.dbf
archivo1->(dbgotop())

DO WHILE ! archivo1->(EOF())
  
? archivo1->(RECNO())
   archivo1->(DBSKIP())

ENDDO

En este ejemplo asumimos que no hemos usado la cáusula ALIAS, luego entonces el ALIAS asignado por omisión será "archivo1" (sin extensión), luego usaremos el operador "alias" (->) para indicar que operaciones deben realizarse sobre él.  

Nota por favor que todas las operaciones sobre la tabla son funciones NO COMANDOS y que todas las operaciones van encerradas entre paréntesis. 

Otra cláusula importante del comando USE es la claúsula NEW, esta clausula te ahorrará miles de lineas de SELECTS ya que esta clausula abre la tabla DBF en la primer área que se encuentre disponible, es decir, no tienes que hacer un SELECT previo a abrir un DBF, simplemente le pones NEW al momento de abrir, y dejas que Clipper/(x)Harbour se haga cargo del resto. 

 USE archivo1.dbf NEW
USE archivo2.dbf NEW
 

No tienes que hacer ningun SELECT para abrir las tablas, ahora, para hacer referencia a los campos de cada archivo, o bien realizar operaciones sobre las tablas, tampoco hay necesidad de hacer SELECT, el ALIAS nos soluciona la vida: 

USE archivo1.dbf NEW
USE archivo2.dbf NEW
archivo1->(DBGOTOP())
archivo2->(DBGOBOTTOM())
DO WHILE ! archivo2->(BOF())
   ? archivo2->(fieldget(1))

       ? archivo1->(fieldget(5))
       IF ! archivo1->(EOF())
      archivo1->(DBSKIP())

       ENDIF
       archivo2->(DBSKIP(-1))
ENDDO 

El manejo de los campos es muy simple, funciona igual, basta con que pongas el nombre del campo despues del operador alias SIN PARENTESIS:  

? archivo1->nombre
? archivo2->iva
 

Los campos también son asignables usando el operador alias, tanto para leer sus valores, como para actualizar o agregar valores, sustituyendo con esto al comando REPLACE:  

cNombre := archivo1->nombre
archivo2->(DBAPPEND()) // el comando APPEND BLANK se sustituye pro su función

archivo2->nombre := cNombre // no hay REPLACE, el valor se asinga directamente
 

Esto de los alias puede ser tan complejo como quieras, un ejemplo típico es buscar en una segunda tabla el valor de un campo contenido en la primera: 

CON SELECTS:  

SELECT 1
cNombre := field->nombre

SELECT 2 SEEK
cNombre
 

CON ALIAS:  

archivo2->(DBSEEK(archivo1->nombre)) 

Efectivamente, con la línea anterior, basta con que hagas referencia a los alias y en vez de usar 4 líneas de código en una sola solucionas el problema y haces exactamente lo mismo. 

Ahora esto del alias es mas versátil porque tu puedes dar TU PROPIO ALIAS  

USE archivo1.dbf ALIAS MiAlias NEW
MiAlias->(DBGOTOP())
? MiAlias->nombre
 

Usando tu propio ALIAS puedes darle un nombre mas identificativo al manejo de tus tablas DBFs. 

Veamos otro ejemplo mas complejo pero sin duda mucho mas útil:  

USE archivo.dbf ALIAS ArchPant SHARED NEW
USE archivo.dbf ALIAS ArchRep SHARED NEW

USE archivo.dbf ALIAS ArchMovs SHARED NEW
 

NO, No hay ningún error, estoy abriendo LA MISMA TABLA (archivo.dbf) 3 veces AL MISMO TIEMPO..... ¿ que no causa esto un error del tipo ALIAS already in use ?.... pues va a ser que no.... y esto es algo de lo mas alucinante y útil de los archivos DBFs. 

Una de las cosas que casi nadie usa es esta poderosa característica de los DBFs, poder abrir la misma tabla 2, 3, 4, o "n" veces al mismo tiempo, esto se logra CAMBIANDO EL ALIAS y abriendo la tabla como compartida (SHARED) como si fuesemos a programar para red. 

Lo interesante de esta forma de usar los DBFs es que cada "alias" mantiene su puntero independiente, es decir, puedes hacer algo tan loco como esto:  

ArchPant->(DBGOTOP())
ArchMovs->(DBGOTO(5))
ArchRep->(DBGOBOTTOM()) 

El puntero de cada "alias" se moverá a distintas posiciones, sin importar que estemos hablando del mismo archivo DBF (recuerda, una cosa es el nombre físico y otra es el nombre lógico).

Y si tu preguntas los valores de los campos :  

ArchPant->nombre
ArchMovs->nombre
ArchRep->nombre 

Seguramente obtendrás valores distintos en cada oportunidad, esto porque sin importar que sea el mismo archivo, para efectos prácticos en la memoria de la computadora esta "abierto" 3 veces bajo 3 alias distintos y cada alias guarda y mantiene su propio estado. 

Solo como comentario, Xailer a través de los DataSets facilita aun mas el manejo de los alias. 

Pero volviendo al tema, para los que no tienen Xailer o tienen la versión personal, aun así podemos seguir haciendo cosas interesantes a base de usar solo los alias: Si yo hago:  

ArchMovs->(DbAppend())
ArchMovs->nombre := "Juan Perez"
ArchMovs->direccion := "Da igual donde viva, Viva El"
ArchMovs->(DBCommit())
ArchMovs->(DBUnlock()) 

El registro añadido será visible EN TODOS LOS ALIAS QUE APUNTEN AL MISMO ARCHIVO FISICO, esto es maravilloso, porque es como dar de alta al mismo tiempo en 3 tablas distintas. 

La pregunta que puede surgir en este momento es .... ¿ y esto como para que me serviría en la vida real ?.... pues para facilitarte la existencia: 

Supongamos que tu quieres mostrar en pantalla un browse del archivo de clientes, donde tienes además 2 índices, uno por clave y otro por nombre, y que además quieres hacer operaciones de mantenimiento como altas bajas y cambios y para rematar quieres hacer reportes que pueden ir ordenados por clave o por nombre, entonces haríamos algo como esto:  

USE clientes ALIAS CliBrow SHARED NEW
CliBrow->(OrdSetFocus("nombre")) // arrancamos ordenado por nombre del cliente
CliBrow->(DBGOTOP())

USE clientes ALIAS CliMovs SHARED NEW
CliMovs->(OrdSetFocus("clave")) // esta segunda instacia del archivo va ordenado por clave

USE clientes ALIAS CliReps SHARED NEW

CliRep->(OrdSetFocus("clave") // idem anterior. 

Si yo quiero meter la primer instancia del archivo de clientes a un browse, basta con hacer: 

CliBrow->(Browse())  

¡¡¡Así de simple !!!!! 

El usuario podrá moverse sobre el browse y podrá cambiar los criterios de ordenación sin afectar a los otros 2 alias que apuntan a la misma tabla. 

Ahora viene lo bueno, si yo quiero hacer un reporte o hacer un ABM sobre la tabla clientes NO LO HAGO SOBRE EL ALIAS DEL BROWSE, lo hago ya sea sobre el alias CliMovs o sobre el alias CliReps para no molestar al alias del browse. 

Cuando trabajas con un solo alias, y quieres dar un mantenimiento a una tabla mostrada en un browse, entonces tienes que "guardar" el estado del área de trabajo que muestras en el browse, es decir, en que registro estás, sobre que indice estas trabajando, etc. y luego hacer las operaciones de mantenimiento sobre ese mismo alias que pueden vincular, mover el puntero sobre la tabla, agregar un registro nuevo, cambiar el orden del índice actual, realizar búsquedas, etc, y luego de la operación, debes regresar todo a como estaba antes. 

Esta técnica te evita eso precisamente. 

 Por ejemplo, si tu quieres agregar un registro el código sería algo como esto:  

CliMovs->(RLOCK())
CliMovs->(DBGOBOTTOM())
nSiguienteClave := CliMovs->clave+1
CliMovs->(DbAppend())

CliMovs->clave := nSiguienteClave
CliMovs->nombre:= cVariableConElNuevoNombre
CliMovs->(DbCommit())
CliMovs->(DBUnlock()) 

Nota que toda la operación de mantenimiento la hacemos sobre el Alias CliMovs, no sobre el Alias CliBrow, de esta manera no tenemos que guardar posiciones ni estados, porque CliBrow no se va a mover su puntero y su índice se quedan como están, en cambio CliMovs hará toda la labor de mantenimiento y el cambio se verá reflejado automáticamente en CliBrow y en CliRep en cuanto haya terminado la actualización CliMovs, el Browse ni si quiera se va a mover, a menos claro, que la operación de mantenimiento afecte al registro en el cual estaba el puntero del alias CliBrow. 

Lo mismo pasa para los reportes, si yo quiero un reporte, usualmente ese reporte abarca un rango de datos, para no molestar al Browse ni a su alias, pues el reporte lo emitimos sobre el alias CliRep:

CliRep->(OrdSetFocus("nombre"))
CliRep->(OrdScope(0,"A")) // reporte de todos los clientes cuyo nombre empiece con "A"
CliRep->(OrdScope(1,"A"))

CliRep->(DBGOTOP())
DO WHILE ! CliRep->(EOF())
 
... aqui val el codigo del reporte...
    CliRep->(DBSKIP())
ENDDO 

Y el CliBrow ni se va a enterar que hay un alias llamado CliRep con un Scope sobre la tabla moviendo el puntero para generar un informe.
 

Esta técnica de programación es ideal para Windows, sobre todo si estás trabajando en entornos MDI porque puedes asignar a cada ventana hija los alias que vaya a necesitar para trabajar, en los entornos MDI una de las cosas mas complicadas de manejar es precisamente esa, evitar que el puntero en la ventana "A" se mueva cuando en la ventana "B" se está realizando otra operación sobre la misma tabla DBF. 

Puedes incluso abrir todas las tablas al momento de arrancar tu programa, porque en (x)Harbour no existe la limitación de las 256 "areas" de dBase, en (x)Harbour prácticamente no hay limite en la cantidad de archivos que puedas abrir simultáneamente. 

En Xailer Pro y Enterprise no tienes los problemas de Alias cuando trabajas en entornos MDI porque Xailer te provee de los DataSets que usualmente ya van "atados" a cada formulario y como expliqué antes, te ahorran el tema de tener que lidiar con alias, en FiveWin o en la versión Personal de Xailer, el uso de esta técnica es indispensable para trabajar con entornos MDI, en (x)Harbour modo consola, esta ténica te puede ayudar a eliminar muchos vicios de programación y a ahorrar muchas líneas de código. Cabe señalar que esto mismo es aplicable a Advantage DataBase Server, de hecho el manual de ADS recomienda que todas las tablas estén abiertas desde que arranca la aplicación, esto es aplicable tanto a archivos DBF con NTX o CDX o bien a tablas ADT con índices ADI. 

 En un próximo artículo discutiremos otra técnica relacionada con esta llamada "alias dinámicos" que hará que no tengas que preocuparte prácticamente por nada que tenga que ver con el acomodo de las tablas en memoria.

miércoles, febrero 10, 2021

Que alguien me explique.... porque no lo comprendo

Como diría mi admirado Condorito (saludos Chile) ¡ Exijo una explicación !. 

Me gustaría saber.... ¿ porque muchos de los programadores de (x)Harbour y sus entornos visuales quieren usar una base de datos basada en SQL ? ..... 

¡¡¡¡ SI NO VAN A USAR EL SQL !!!!!!! 

¡ Que alguien me explique por favor ! 

 Abundan las preguntas en los foros del tipo: 

¿ como uso MySQL con xHarbour ?, ¿ Puedo leer tablas de Oracle con xHarbour ?, Quiero cambiar de base de datos y usar SQL Server en vez de DBFs, ¿ como lo hago ?, estas preguntas se repiten a puños en los foros..... tooooodo el mundo quiere usar un SQL ¡ Pero muchos programadores lo quieren usar o lo usan como si fueran DBFs ! como sucedería en la tira cómica de Condorito .... ¡ PLOP !

Que alguien me explique porqué, si el producto se llama MySQL, SQL Server, Postgre SQL,..... ¿ porqué "·%&·$"!"·@# lo quieren trabajar como si fuera un DBF y no por SQL? 

Y me respondo yo mismo: porque no conocen el lenguaje SQL, lo cual me parece increíble ya que SQL es un lenguaje de programación que se basa básicamente en 7 instrucciones, no entiendo entonces como un programador de (x)Harbour que se aprende mas de 20 comandos de Xbase, no puede aprender a usar 7 estúpidas instrucciones: SELECT, INSERT, UPDATE, DELETE, DROP, CREATE, ALTER. 

¡ Que alguien me explique ! Es como comprarse un Ferrari sin saber conducir ni tener licencia, o lo que es peor, es comprarse el Ferrari y pretender conducirlo como si fuera una bicicleta, porque no sé conducir un coche, pero la bicicleta la llevo bien. 

Lo peor de todo es que (x)Harbour fomenta seguir trabajando del modo equivocado con herramientas como el RDDSQL o el ADORDD.... vamos a ser serios por favor, si vamos a clavar un clavo en la pared, vamos a usar un martillo, no la suela del zapato, si es una herramienta SQL, vamos a trabajarla como SQL, no con parches ni apaños con el pretexto de "no conozco el lenguaje SQL", aprender SQL no tiene la menor complicación, unas 3 tardes de lectura y listo, no digo que te vas a volver un experto, pero si podrás comenzar a explotar a SQL. 

Hoy por ejemplo estaba revisando el foro de (x)Harbour y un colega preguntaba porqué no le funcionaba un SET RELATION con el RDDSQL y MySQL..... ¿ perdón ?..... ¿ como para qué tendrías que hacer un SET RELATION con MySQL si con un simple query (instrucción SQL) puedes obtener el resultado que necesitas ?, eso no es matar pulgas a cañonazos, es matar microbios con misiles. 

Los SQL son bases de datos RELACIONALES, es decir, las relaciones son parte de su naturaleza y las pueden resolver directamente, tú no tienes porqué hacer el trabajo del servidor, si no haz aprendido eso, apaga y vámonos, regresa a los DBFs, aprende a usar SQL y cuando sepas SQL, regresa, no te vas a arrepentir, pero por favor, pretender trabajar un SQL como si fuera un DBF es un desperdicio de recursos, una pérdida de tiempo, de líneas de código y de esfuerzo, créeme por mas que lo intentes, el mar no cabe en un vaso de agua, solo cabe un poquito. 

Si estás decidido a aprender SQL, te advierto una cosa.....SQL es una tecnología que causa adicción, es como el iPod, una vez que te enganchas..... a ver como te lo quitas de encima.... si no me crees, trabaja un mes con SQL, y te aseguro que nunca mas querrás volver a usar un DBF, cualquiera que haya hecho el cambio no me dejará mentir. 

Quizá la parte mas complicada de trabajar un SQL es como leer el "cursor" es decir, como acceder a los datos devueltos por la ejecución de un query, para hacer las cosas mas simples de entender, un "cursor" equivale al "alias" de un DBF, y para ello, ADO (Activex Data Objects) se pinta solo, conjunta lo mejor de 2 mundos: el Poder del SQL, con la facilidad de uso del modelo Xbase, automatizando mucho del trabajo de acceso a los servidores de datos. 

ADO tampoco es complicado de entender, son 3 objetos fácilmente accesibles desde xHarbour por medio de OLE (Object Linking and Embeding), si quieres saber mas sobre ADO, mi amigo Gabriel Maimò tiene estupendos artículos al respecto en su blog: BielSys

Así que para que gastar en herramientas externas como RDDSQL, Mediator, etc, cuando puedes usar todo el poder del SQL con un rato de estudio y además gratis usando (x)Harbour y te funciona tanto para modo consola como para entrono gráfico. 

Otro punto importante cuando trabajas con una base de datos SQL: Las bases de datos de este tipo son poderosas por la arquitectura sobre la cual están diseñadas: son Cliente / Servidor, ojo a la ultima palabra: SERVIDOR. 

Mientras te comienzas a sentir cómodo con el SQL, entiendo que programes los queries (instrucciones SQL) como parte de tu código fuente, pero eso solo será al principio, la idea es PONER A TRABAJAR AL SERVIDOR (por eso se llama Cliente / Servidor), para ello se inventaron los "Procedimientos almacenados" ó "Stored Procedures", ¿ que son ?, pues son como "funciones" de Clipper, pero que están escritas en SQL, y están almacenadas en el servidor como parte de la estructura de la base de datos, esto facilita muuuuuuucho la programación del SQL, porque no tienes mas que llamar a los procesos almacenados desde tu código fuente con parámetros, si tu quieres hacer algún cambio en un proceso almacenado, no tocas el código fuente de tu programa (x)Harbour, lo modificas directamente en el servidor de la base de datos, eso es parte de la "arquitectura de 3 capas". 

Resumiendo: Si estas usando un SQL Cliente / Servidor (= 100%) , sin la parte del SQL ( -50%), ni la parte del Servidor (-25%), lamento informarte, que estás usando solo un 25% de todo lo que podrías hacer si supieras explotar toda la herramienta, ahora imaginate, si estás usando SQL Server, sin parte del SQL ni la parte del Server......pues nos ha jodido, ¡ No estas usando nada ! y si no estás usando nada ...... ¿ para que quieres usar un SQL ?. 

¡ Que alguien me explique !

Programar bien y programar bonito

Buena pregunta..... 

¿ Tu programas bien o programas bonito ?

 ¿ Tienes estándares de programación ? 

¿ Haces códigos fuentes de menos de 1000 lineas ? 

¿ Usas notación húngara ? 

¿ Tus tablas están diseñadas siguiendo el modelo Entidad-Relación ? 

¿ Los nombres y tipos de tus campos son coherentes entre las tablas que los usan ? 

Eso en cuanto a programar bien, ahora en cuanto a programar bonito 

¿ Comentas tus códigos fuentes ? 

¿ Identas correctamente el código ? 

¿ DISEÑAS TU INTERFACE CORRECTAMENTE ? 

En este último punto es donde todos fallamos, me incluyo. Hace muchos años, durante la época del MS-DOS, realmente no existía un estándar para desarrollar una interfaz con el usuario, así que teníamos la libertad de hacer lo que nos diera la gana al momento de diseñar la interfaz de nuestros programas, eso era el salvaje oeste, y lo que para algunos podría parecer un asco de interfaz, para otros era útil, sencilla o práctica o simplemente los usuarios se han acostumbrado a ella, pero en 1987 las cosas cambiaron radicalmente. 

En 1987 IBM propuso un estándar de interfaz con el usuario a la que llamó CUA (Common User Access), el estándar CUA es (se sigue usando y tu lo usas todos los días aunque no lo sepas) un conjunto de especificaciones detalladas y reglas estrictas sobre la apariencia y la manera en que las aplicaciones deberían de funcionar, este fue el primer intento de poner en orden a las aplicaciones basadas en DOS, que como comenté anteriormente, hasta ese momento implementaban diferentes interfaces con el usuario. IBM adoptó este estándar en todas sus aplicaciones y sistemas operativos, y también lo hizo Microsoft, así que, mi querido lector, tu usas CUA todos los días cuando trabajas con Windows, ya que las interfaces de este sistema operativo están ampliamente basadas en CUA. El estándar CUA, a pesar de tener 33 años de edad, especifica cosas haces todos los días en tu trabajo diario, y que los programas que tu desarrollas deberían tener, como por ejemplo:

  • Todas las operaciones se deben poder hacer con el ratón, pero también con teclado, sin intervención del roedor.
  • Las opciones del menú se deben abrir usando la tecla Alt+Letra subrayada
  • Un grupo de opciones de un programa debe ser capturado usando dialogos, no ventanas
  • Las opciones en un diálogo se dividen usando pestañas, no se hacen dialogos larguísimos que se tengan que desplazar para capturar todas las opciones necesarias
  • La navegación dentro de un campo en un diálogo es con las flechas del cursor, la navegación entre los campos hacia adelante se hace con la tecla Tab; la tecla Shift+Tab navega hacia el campo anterior.
  • Los diálogos deben tener siempre un botón CANCELAR cuya operación debe relacionarse con la tecla ESC, y siempre se debe usar para descartar los cambios realizados en los campos capturados dentro del diálogo.
  • Los diálogos deben tener siempre un botón ACEPTAR, el cual acepta los cambios realizados en el diálogo y esta asociado siempre con la tecla ENTER
  • Todas las aplicaciones deben tener una opción de AYUDA en el menú, esta opción debe ser SIEMPRE la última del menú, la ayuda en línea para un caso específico debe ser invocada por la tecla F1
  • La primera opción del menú debe ser SIEMPRE la opción ARCHIVO, seguida siempre por la opción EDITAR
  • El comando CORTAR son las teclas SHIFT+DEL, COPIAR son las teclas CTRL+INS y PEGAR son las teclas SHIFT+INS
  • etc., etc., etc.

Detengo la lista hasta aquí porque estoy seguro que TOOOODOS tus programas siguen al pie de la letra el estándar CUA, el cual, dicho sea de paso, hace que tu aplicación califique como "compatible con Microsoft Windows". 

Seguramente tu no eres de esos que pone degradados de colores en los fondos de sus programas, no no no no, ¿ como lo vas a hacer ?, eso no está documentado en CUA, ni pones botones de 30 colores diferentes con bitmaps y seguramente sabes usar perfectamente una RibbonBar, no la pones en tus programas nada mas porque la acaban de incluir en la última versión de tu herramienta de programación o porque viene en Office 2007, estoy seguro que sabes como dividirla y cuando usar cada componente, después de todo programas BIEN para Windows ¿ no ?. 

Bueno, como todo lo anterior es cierto (programas BIEN en Windows), gracias por leer este artículo, nos veremos próximamente con algo más interesante, ¡ Hasta la próxima ! 

.... 

.... 

.... 

.... 

¿ Como ?...... 

¿ sigues ahí ?..... 

Ok, ok, si sigues ahí es porqué seguramente te sentiste identificado con algo que mencioné que tu NUNCA haces en tus programas. 

Hace unos días estaba mirando en Facebook las imagenes que puso un colega programador de su aplicación...... oh my dog !.... con RibbonBar, OutlookBar, Menú, todo metido en la ventana principal, dialogos con fondos degradados, mensajes por todos lados, imagenes de distintos estilos por todos sitios.... y lo peor, los mismos colegas programadores comentado ....oooohhh que bonita aplicación......

 No digo que la aplicación no se viera bonita, pero hay una línea muy fina entre lo bonito y lo grotesco, la verdad no sabría yo calificar si eso era bonito, o era grotesco. 

Hasta ahora no he visto ninguna aplicación, salvo el WinZip o el Office 2007 que utilicen una RibbonBar como se debe y son muy pero muy muy muy pocos programas que me ha tocado usar, especialmente de desarrolladores independientes y aún de empresas que se dedican al desarrollo de software que pasarían una certificación de Microsoft. 

No basta con que tu programa corra en Windows con una interfaz gráfica, tampoco basta decir que tu programa es "Compatible con Microsoft Windows" (y encima nos damos el lujo de decir con Windows XP y superiores 32 o 64 bits), hay que demostrar que tu programa realmente es 100% Windows compatible. 

Para que un programa sea 100% Windows compatible, tiene que seguir el estricto estándar que Microsoft ha impuesto para el desarrollo de aplicaciones Windows compatibles. 

Cada vez que Microsoft libera una versión de Windows, también publica una "guía" de la interacción que el usuario debe tener con el sistema operativo, elegantemente le llama "User Experience Interaction Guidelines" y está disponible en el MSDN como archivo PDF, te voy a ahorrar la molestia de buscarla, pero vas a tener que seguir leyendo hasta el final. 

En este documento, de 867 páginas y 41 Mbytes de tamaño, Microsoft explica todos los controles que se usan en la interfaz de Windows, así como también explica detalladamente como y cuando deben de ser utilizados, como deben ser emplazados dentro de un diálogo o ventana, que distancia debe de existir entre ellos. 

Otra cosa que también documenta es la lista de "violaciones" mas comunes que hacemos los programadores cuando estamos diseñado la interfaz de nuestros programas, como por ejemplo no usar textos en color azul porque el usuario asume que son links de internet, siempre coloca un boton CANCELAR, usa tooltips solo cuando el control no tenga etiqueta, asigna aceleradores a todas la etiquetas de controles, el orden de TAB siempre debe ser de izquierda a derecha y de arriba hacia abajo, en los mensajes de tus programas no uses las palabras ERROR, FALLA, ILEGAL, VIOLACION, ABORTAR, FATAL, eso espanta a los usuarios, etc. etc. etc. 

Lo que mas me gustó de la guía es que incluye una sección sumamente detallada del uso de controles, como usarlos adecuadamente, cuando tal control puede ser reemplazado por otro de otro tipo, cuando NO usar tal o cual control, baste con decir que la guía es tan detallada que solo la sección que trata del Checkbox ocupa 5 paginas, indicando con todo detalle ejemplos y casos de uso, solo como comentario, ¿ Sabias que la distancia que debe existir entre un LABEL y un CHECKBOX es de 5 pixeles y que la distancia entre cada CHECKBOX cuando hay varias opciones debe ser de 7 pixeles y que el tamaño del control debe ser de 10 pixeles de altura ?, bueno así como se detalla el Checkbox, se detallan el resto de los controles. 

Mención por separado merece la documentación de la creación y uso de la RibbonBar, esta si es una obra maestra de la documentación, en 33 páginas te documenta, detale a detalle, cada elemento de una RibbonBar, y la forma correcta de usarlo, una vez que leas esta documentación te darás cuenta si realmente la RibbonBar está bien soportada e implementada en tu lenguaje de programación. 

A estas alturas te podrías estar preguntando ¿ y realmente hay programas que respeten todo lo que dice el documento ?.... ¡ pues claro que los hay !, TODOS los programas que vienen en el sistema operativo de Windows y en genera TODOS los programas de Microsoft son diseñados siguiendo estrictamente las reglas de la UX Guide. 

 La UX Guide la puedes descargar haciendo Click aquí. La mala noticia es que está todo en inglés y no existe versión en Español, por lo menos hasta el día en que descargué el documento, de todas formas la guía incluye una estupenda información que te ayudará a hacer programas mas poderosos y bonitos. 

Ahora sí, programarás bien y programarás bonito.

Si programas no vendas, si vendes no programes

A raíz de los comentarios publicados en el post anterior por varios de ustedes, me tomo la libertad de compartir mis experiencias en este mundillo de comprar y vender software. 

Yo empecé como desarrollador en el año 1989, cuando aun la computadora no era un electrodoméstico mas y costaban mas o menos el precio que un viaje de 15 días de México a Europa. 

Como los equipos eran caros, pocas personas o empresas contaban con ellos, por lo tanto hacer software hace 20 años era un estupendo negocio. 

Hoy las cosas han cambiado y mucho, la computadora ha dejado de ser un objeto de lujo para convertirse en un artículo de consumo, pero lo que no ha cambiado es que siempre, al final de la cadena hay un usuario final que tiene necesidades de cubrir al cual le importa un cacahuate (o al menos debería importarle un cacahuate) en que está hecho el programa que usa, lo importante es que le resuelva el problema. 

Yo catalogo a las empresas de software en 3 tipos en base a su tiempo de vida: 

1) Empresas con buenos programadores pero con malos o ningún vendedor, son las que duran menos.

2) Empresas con buenos vendedores y con programadores regulares o malos. Que duran un poco mas que las anteriores, pero tampoco mucho mas. 

3) Empresas que equilibran buenos vendedores con no menos estupendos programadores, que son las que están "condenadas al éxito". 

Veamos el caso 1. Juanito programador decide lanzarse a la aventura de vender sus productos de software, es un programador extraordinario, en lo que sea, no vamos a etiquetar a ningún lenguaje, hace programas maravillosos, útiles y funcionales, pero no sabe vender, después de todo es su primer experiencia vendiendo sus productos, tampoco tiene dinero para contratar vendedores o publicidad, así que se lanza a hacer un software business do-it-yourself. 

Este tipo de empresa está condenada al fracaso en corto tiempo, ¿ Porqué ? porque Juanito programador tendrá que lidiar con 2 problemas: buscar clientes para sus productos, y encima crear y darles mantenimiento a los mismos (de hecho no es recomendable tener mas de un producto si es tu primera incursión en el mundo del negocio del software), con lo cual, como no puede hacer bien una cosa ni la otra, Juanito conseguirá 2 o 3 clientes, pero deberá de seguir dándole manteniendo al software y por conservar a sus 2 o 3 clientes les va a cumplir cuanto capricho le pidan, después de todo, son funcionalidades que quizá algún futuro cliente (que nunca va a llegar) le pida.

En poco menos de 1 año este tipo de empresa bajará la cortina, porque no es rentable, el super programador Juanito buscará un trabajo regularmente pagado, pero por lo menos llegará a fin de mes. 

El caso 2 tiene un poco mas de tiempo de vida, o al menos resultará economicamente viable, en este caso tenemos a Pedrito Vendedor, el comercial mas fiero, que le vende refrigeradores a los esquimales del Polo Norte y calefacción a los beduinos del Sahara, Pedrito sabe vender, tiene los contactos, la personalidad, el carisma y ese "algo" que tiene el vendedor nato, pero no tiene conocimientos de informática, computación o programación, sin embargo, sabe vender, así que ubica algún programa informático interesante (ojo, he dicho interesante, no he dicho BUENO o UTIL, o PRACTICO), contacta con el autor, llega a un acuerdo, y se lanza a comercializarlo. 

Como Pedrito tiene conocimientos de publicidad y una red de contactos en poco tiempo ese producto ha llegado a un montón de personas, ha producido una buena utilidad peeeeeroooo... el producto no era ni tan bueno, ni tan útil, ni tan práctico como Pedrito vendedor lo había dibujado y lo peor de todo, el programador tampoco era tan bueno. 

Viene ahora corregir todas las quejas, bugs, fallas, etc. y todos sabemos que la cantidad de quejas es proprocional a la cantidad de productos vendidos, por lo tanto, Pedrito se verá agobiado de quejas de sus clientes, le pedirá al programador que haga algo para solucionar los problemas, pero como el programador no es muy bueno entonces pasará de hacerlo, se contratará a otro programador para que ayude al autor, sin embargo como el autor es un mal programador no lo entiende nadie, y tarde o temprano la empresa cierra porque no hay quien se haga responsable del mantenimiento del programa. 

En este tipo de empresas rara vez la versión 2.0 del producto llega a ver la luz, sin embargo algo de dinero hizo (después de todo vendió montones de humo), así que, algo se ganó con la experiencia, Pedrito Vendedor ahora venderá GPS's, cepillos de dientes o cualquier otra cosa, y venderá montones, porque lo suyo es vender. 

El balance perfecto lo tiene aquella empresa que sabe que es tan importante tener buenos vendedores y no menos mejores programadores, conozco muchos caso de empresas que son rentables (y muy rentables) con un cuerpo de 4 o 5 buenos programadores (o menos) y un equipo de fieros vendedores y mercadologos, después de todo, como siempre he dicho, la característica mas importante de un programa, aparte de tener una bonita interfaz, ser robusto, fácil de usar y práctico es ..... que los posibles clientes lo conozcan..., si el producto no lo conoce nadie, entonces de nada vale toda la tecnología que tenga dentro ni todo el tiempo invertido. 

¿ Recuerdas el caso de un individuo llamado Bill Gates ?, sin duda un buen vendedor, consiguió un buen producto, el famoso MS-DOS y era tan buen vendedor que se lo vendió a IBM.... el resto es historia. 

Aparte de tener vendedores buenos y de invertir en publicidad, una empresa de software sin importar su tamaño deber saber que su materia prima es el programador, es su activo mas importante, le deben su existencia y por lo tanto, la estrella de la empresa debe ser el programador, por lo mismo hay que tenerlo mimado, contento y bien alimentado, si queremos tener productos finales de calidad, la materia prima debe ser de también de buena calidad. 

La semana pasada aprovechando una visita que por motivos de trabajo tuve que hacer al norte del país, tuve el gusto de cenar un par de veces con un estupendo amigo de muchos años, programador y dueño de su empresa de software. Me dió muchismo gusto verlo y ver lo ha hecho gracias al software (hecho en (x)Harbour por cierto), pasó a buscarme en un cochazo ultimo modelo, fuimos a cenar a unos sitios magnificos, y me comentó una cosa que me hizo pensar.... - a mi que me dejen programar, y que los vendedores hagan su trabajo -, -yo-, me dijo,- no vendo, para eso tengo vendores, yo programo, lo mio es hacer el software y que los vendedores hagan su trabajo -, siguiendo esta filosofía mi amigo ha logrado tener mas del 60% del mercado del software de punto de venta de su región, y ha penetrado el mercado de Estados Unidos con presencia en ciudades como San Diego y Los Angeles y el único producto que tiene es una Terminal Punto de Venta. 

¿ Cual es el secreto de este tipo de empresas de software exitosas ?, no es el precio del producto, definitivamente, lo que pasa es que han encontrado un NICHO de negocio, un software de alta especilización para un mercado específico. 

¿ Que no hay montones de TPV en el mercado ?, si, hay muchos, pero como dice mi amigo... - yo a mis clientes le vendo la experiencia que he tenido con todos mis otros clientes -, así por ejemplo tiene versiones de su Punto de Venta específicamente diseñadas para carnicerías, con control para básculas, para farmacias, con un catálogo precargado de mas de 5 mil medicamentos, lo que le ahorra al usuario tener que cargar los productos, versiones para puestos de periódicos y revistas, para dulcerías, panaderías, versiones especiales para cadenas de supermercados, etc. aún dentro de un área de software específica es posible encontrar aún mas especialización. 

Conozco otra empresa de software donde saben que sus programadores son sus estrellas, y el dueño (que también conoce de programación) es un vendedor nato, basta escucharlo hablar de las bondades de su producto para enamorarse de él (del producto). 

Una de las cosas que mas admiro de esta empresa es que no se cortan un pelo en comprar las herramientas que les piden sus programadores: pagan cursos, adquieren editores, reporteadores, bases de datos, lenguajes, equipos de escritorio y portátiles, todo de última generación para que el programador no se detenga y además se encuentre a gusto (eso sin contar el aire acondicionado las oficinas de cada uno) ¿ será por eso que sus programadores tienen mas de 10 años con ellos ?, y no son "todologos", solo hacen un software de nómina y solo eso. Y no son empresas del extranjero como Google o Fog Creek Software, son empresas donde trabaja algún colega programador que conoces muy bien, solo que estas empresas han entendido la importancia del programador. 

Aún siendo programador independiente, definitivamente te debes mimar y tratar de tener las mejores herramientas para realizar mejor tu trabajo, no pretendo que seas Stefan Didak, pero si es importante que tengas un espacio adecuado donde te sientas a agusto y la musa de la programación pueda correr libremente. 

 ¿ Que tal un comedor en la empresa con horno para asar un cordero incluído y una estupenda colección de vinos ? ¿ o una zona de descanso con máquinas expendedoras de café, refrescos y golosinas para que no tengas que salir a la calle ? ¿ Que me dices de unas oficinas en Cancún ? ¿ o programar tranquilamente sentado en una cafetería mirando al mar ? ¿ que tal tener vacaciones familiares en Orlando, Las Vegas o Nueva York cuando sientas que las necesitas ?, o poder tener un iPad o un MacBook Air como equipos de "capricho" ¿ que tal un BMW Serie 5 o un Mercedes descapotable afuera de tus oficinas ?, si crees que no hay programadores que hagan o tengan eso, estas muy muy muy equivocado, todas las descripciones anteriores corresponden a empresas donde yo he estado y veo como cuidan a sus programadores, lo mas curioso de todo, es que en todas esas oficinas y negocios que parecen salidos de un cuento de hadas informático programan en (x)Harbour y quizá alguna vez te hayas topado con algún programador que trabaja ahí ya sea en el messenger o en un foro. 

¿ Donde está el secreto ?.... podría resumirlo en lo siguiente: 

1) Venden software que cubre una necesidad muy especifica. 

2) Están enfocados en un nicho del mercado muy particular, es decir, con muy pocos competidores. 

3) Sus programas funcionan, hacen lo que tienen que hacer, y lo hacen bien, porque tienen buenos programadores. 

4) Generan muchas ventas porque tienen un equipo de vendedores comprometido, que sabe lo que están vendiendo. 

5) Cuentan con herramientas y tecnología, los programadores no tienen que estar perdiendo el tiempo buscando el crack de tal o cual programa, porque si lo necesitan, simplemente lo compran y así terminan antes. 

6) El medio ambiente de trabajo es agradable. y lo mas importante, que es donde se genera el flujo económico para la empresa: 

7) Le solucionan un problema al usuario final. 

Podría seguir hablando de estrategias para hacer rentable un negocio de software, creo que sería un buen tema de un futuro post de O.P. 

Moraleja: Si sabes programar pero no vender... ni lo intentes, si sabes vender pero no programar... tampoco lo intentes.