Thursday, October 20, 2011

Elementos Recientes (Windows 7)


Para eliminar manualmente el listado de los programas y documentos que hemos abierto recientemente en Windows hay que entrar a la siguiente carpeta y eliminar los enlaces.

%appdata%\Microsoft\Windows\Recent

Además, En Windows 7, si deseamos eliminar los documentos recientes de los programas podemos eliminar los archivos de las siguientes carpetas:

%appdata%\Microsoft\Windows\Recent\AutomaticDestinations
%appdata%\Microsoft\Windows\Recent\CustomDestinations

Ojo, estos documentos recientes no son los recientes que están dentro de cada programa, sino los que va detectando Windows 7 como parte de su funcionalidad para mostrarlos tanto en el Menú de Programas como en el menú contextual cuando lo tenemos en la Barra de Herramientas de Inicio.


Thursday, May 26, 2011

Pensar en los usuarios finales

Recomiendo totalmente que los programadores al desarrollar alguna herramienta cuiden todos los frentes posibles.

Un punto muy importante es entregar las herramientas con un instalador para que de cero, puedan instalar lo que les estamos entregando.

Antes de continuar me gustaría que analizaran la siguiente caricatura:


La caricatura anterior me causa diversión, pero también me deja pensando el cómo hacemos todas las cosas que nos pide el cliente.

No se puede considerar un programa terminado sin tener su instalador y si no es necesario el instalador por lo menos un ejecutable Stand-Alone o que al descomprimir en alguna carpeta se pueda ejecutar desde ahí la aplicación sin ningún error o problema.

En el caso de las Herramientas de Maxicomercio es importante que se genere con su instalador. Está muy bien que me entreguen los avances en código fuente, pero si ya consideran que es funcional incluir el instalador para poderlo poner en las máquinas de los usuarios sin que nos de problemas.

Esto es, probarlo antes. Ejecuten en instalador en alguna máquina y vean que se instale y funcione correctamente sin requerir ninguna librería extra y que si la requiere, que la descargue automáticamente.

Otro punto importante es integrar al programa una manera automatizada para buscar y descargar actualizaciones. Estoy casi seguro que hay formas ya pre-programadas para hacerlo o incluso componentes que den esa funcionalidad sin tener que empezar desde cero. Esto nos evita tener que ir a cada equipo del cliente para actualizarle su versión. De ser posible recomiendo que dediquen tiempo a investigar este punto.

Resumiendo:

  1. Hacer instalador (SIEMPRE, cuidando que se integren todas las librerías y componentes que usemos en el desarrollo.)
  2. Probar nuestro instalador en algún equipo. Estar seguros de que funcionará con los sistemas operativos que utiliza el cliente.
  3. Integrar Actualizaciones Automáticas utilizando algún componente desarrollado previamente o integrado al sistema de desarrollo que estamos usando.

Friday, May 6, 2011

Guía Rápida de MySQL

Artículo Original: MySQL Cheat Sheet

Seleccionar una base de datos:
mysql> USE basededatos;

Mostrar las bases de datos existentes:
mysql> SHOW DATABASES;

Mostrar las tablas de la base de datos seleccionada:
mysql> SHOW TABLES;

Describir el formato de una tabla:
mysql> DESCRIBE tabla;

Crear una base de datos:
mysql> CREATE DATABASE nombre_basededatos;

Crear una tabla:
mysql> CREATE TABLE nombre_tabla (nombre_campo1 TIPO(TAMAÑO), nombre_campo2 TIPO(TAMAÑO), ...);


Por ejemplo:
mysql> CREATE TABLE mascota (nombre VARCHAR(20), sexo CHAR(1), nacimiento DATE);


Cargar un archivo separado por tabs a la base de datos:
mysql> LOAD DATA LOCAL INFILE "archivo.txt" INTO TABLE nombre_tabla;
(Usar \n para representar un valor NULL)

Agregar una fila por vez
mysql> INSERT INTO nombre_tabla VALUES ('Nombre', 'Dueño', '2006-05-23');
(Usar NULL para los valores NULL)

Obtener información:
mysql> SELECT columna1, columna2, ..., columna_n FROM tablas WHERE condiciones;

Toda la tabla: SELECT * FROM tabla;
Algunos valores: SELECT * FROM tabla WHERE nombre_columna = "valor";
Varios filtros: SELECT * FROM tabla WHERE columna1 = "valor1" AND columna2 = "valor2";

Modificar un conjunto de registros (que concuerden con un filtro)
mysql> UPDATE tabla SET nombre_columna = "nuevo_valor" WHERE nombre_columna = "valor_de_filtro";

Seleccionando sólo una columna en especial:
mysql> SELECT nombre_columna FROM tabla;

Obteniendo datos únicos/distintos/sin repetir:
mysql> SELECT DISTINCT nombre_columna FROM tabla;

Ordenar los datos
mysql> SELECT columna1, columna2, .... FROM tabla ORDER BY columna_n;

Orden inverso:
SELECT columna1, columna2, .... FROM tabla ORDER BY columna_n DESC;

Cálculo de fechas
mysql> SELECT CURRENT_DATE, (YEAR(CURRENT_DATE)-YEAR(columna_de_fecha)) AS diferencia_de_fechas [FROM tabla];

MONTH(una_fecha) extrae el mes de la fecha especificada, DAYOFMONTH(fecha) el día.

Búsqueda de patrones (expresiones):
mysql> SELECT * FROM tabla WHERE columna LIKE 'algo%';

% es el caracter de comodín que significa cualquier cantidad de caracteres


mysql> SELECT * FROM tabla WHERE columna LIKE '_____';


_ es el caracter de comodín que significa cualquier caracter (sólo 1).

Búsqueda avanzada de expresiones regulares:
mysql> SELECT * FROM tabla WHERE columna RLIKE '^b;

. para un caracter
[...] para un conjunto de caracteres
* para 0 o más caracteres
^ para el comienzo
{n} para n repeticiones
$ para el final

Es válido tanto para RLIKE como REGEXP. Sin embargo, para forzar la diferenciación de mayúsculas de minúsculas se recomendaría usar “REGEXP BINARY”.


Contando filas:
mysql> SELECT COUNT(*) FROM tabla;

Agrupar las cuentas
mysql> SELECT columna, COUNT(*) FROM tabla GROUP BY columna;

GROUP BY agrupa todos los registros de cada valor distinto de la columna especificada

Filtrando varias columnas:
mysql> SELECT tabla1.columna1, columna2 FROM tabla1, tabla2 WHERE tabla1.columna1 = tabla2.columna_n;

Se puede comparar una tabla consigo misma utilizando ‘AS’ para darle un nuevo nombre a una columna.

Seleccionar la base de datos actual:
mysql> SELECT DATABASE();

Calcular el máximo
mysql> SELECT MAX(nombre_columna) AS nombre_nueva_columnal FROM tabla;

Columna auto-incrementada
mysql> CREATE TABLE tabla (numero INT NOT NULL AUTO_INCREMENT, nombre CHAR(10) NOT NULL);

mysql> INSERT INTO tabla (nombre) VALUES ("tomas"),("pedro"),("juan");


Agregando una columna a una tabla ya existente:
mysql> ALTER TABLE tabla ADD COLUMN [sintaxis para una nueva columna] AFTER nombre_columna;

Borrando una columna:
mysql> ALTER TABLE tabla DROP COLUMN nombre_columna;

Haciendo una copia de seguridad con mysqldump:
# mysqldump --opt -u usario -p base_de_datos > respaldo.sql

Si se quiere hacer el respaldo de muchas bases de datos, hay que utilizar:
# mysqldump --opt --all-databases > respaldo_todo.sql

Wednesday, April 13, 2011

Mejoras Rápidas

Dado que el acceso a "Conexión" lo puede hacer cualquier persona que abra el programa necesitamos protegernos para que no cualquiera pueda ver esta información.

Se me ocurren 2 cosas:

La primera sería que para entrar a conexión tecleramos una contraseña integrada al sistema, que no la tome de ninguna base de datos, esta contraseña puede ser relativamente sencilla para digitarla rápidamente y acceder a la configuración.

La segunda es que servidor, usuario, contraseña y nombre de la base de datos aparezcan con asteriscos para que no estén visibles de primera mano.

La verdad a mi me parece muchisimo mejor la primer opción pero depende de que sea mejor.


El otro cambio que hay que tener en cuenta y que mejoraría mucho el trabajo en equipo es integrar al proyecto los controles utilizados.

Para ello, seleccionar el control, y en el parámetro Copia Local, establecerlo en True para que se copie el control a la libreria de nuestro proyecto.




Sunday, April 3, 2011

Comentar Múltiples Líneas en VB.NET

Para comentar o descomentar varias líneas de código utilice la siguiente combinación de teclas.


Ctrl+K, Ctrl+C para comentar
Ctrl+K, Ctrl+U para quitar los comentarios




Recuerden que tienen que estar seleccionadas dichas líneas.

Saturday, April 2, 2011

Creación de Relaciones en Dreamcoder

Para crear una relación entre tablas utilizando el Dreamcoder sería de la siguiente manera.

  • En el Dreamcoder (conectado a la base de datos) entrar a la opción del menú "Create" y después en "New constraint"


  • Aparecerá la siguiente ventana. En el primer grupo de opciones (Constraint Options) seleccionar la base de datos (se selecciona por defecto), en Table escoger el nombre de la tabla que tendrá relación a la tabla principal. Esta tabla es la que contendrá la lista de valores que deseamos ligar. En Type seleccionar Foreign Key.


  • En el segundo grupo de opciones (References) seleccione la tabla principal. En este caso es ut_cmcalzado, en Refered Column escoja el campo que almacenará el ID del elemento relacionado.
  • Recomiendo que en la opción "On delete" se escriba Restrict para evitar que se elimine un registro si tiene alguna relación.

Para concluir basta con presionar el botón OK y esperar a que realice el proceso.

El 31 de Marzo es el Día Mundial del Respaldo (World Backup Day) no se les olvide respaldar antes de afectar directamente la base de datos.

Suerte!



Thursday, March 31, 2011

Módulo de Acceso - Consideraciones

Considerar lo siguiente para la creación de la pantalla de acceso a las diferentes herramientas que hagamos en VB.Net 2010
  • Ya que haremos Módulos Independientes para diferentes funciones, considerar que debe de ser portable. Por ejemplo, se está trabajando en ClienteReport (Zepeda) y en CalzadoDeck (Landeta). El módulo deberá de ser sencillo de insertar en cada nuevo proyecto. Se me ocurre mandarlo a llamar con alguna función y que si regresa falso no continuar con la ejecución de la herramienta.
  • No podemos utilizar la contraseña que asigna Maxicomercio porque desconocemos la forma en que se encriptó.
  • Utilizaremos una columna que acabo de crear en la tabla tuser y que la nombre ut_altpass la hice varchar con 32 de longitud.
  • Desde Maxicomercio NO activaré que se pueda escribir o ver este password, así que necesito una interfaz que nos permita acceder a la lista de usuarios y podamos desde ahí agregar el password que nosotros queramos y que (ya lo pensé bien) NO SE ENCRIPTE, para que, si a alguien se le olvida ESE el password podamos revisar cual es fácilmente desde el Dreamcoder. Para acceder a la parte donde podamos agregar estas contraseñas puedes utilizar "Admin" y el password que tenemos actualmente en el Maxicomercio, pero por favor, este que no esté a la mano. El de conecta.txt está muy obvio para conocer la contraseña de Root. A ver que se te ocurre para esconderlo y que no sea facil de hackear.

  • Al abrir el módulo me gustaría ver primeramente una lista de los usuarios existentes similar al CalzadoDeck y con ese mismo campo para buscar. Que al buscar busque de los campos: UserID y UserName de la tabla tuser.

  • En la pantalla anterior no es que me haya faltado el botón agregar. Recuerda que los usuarios deberán de crearse desde Maxicomercio.
  • El Editar el elemento se deberá presentar un diálogo mostrándonos:
    • Usuario
    • Nombre
    • Si está bloqueado o no, con opción a bloquearlo o desbloquearlo
    • Dos campos para el código alterno y su confirmación. Si el elemento ya tiene asignado un password que nos permita escribir en los campos pero que nunca se muestre el contenido. Que salgan asteriscos.
    • Mensaje
    • Notas
    • Un listado de los módulos a los que tiene acceso y que ahí nos permita agregar o quitar. Inicialmente solo deseo controlar si tiene acceso o no. En un futuro podríamos pensar en si les damos acceso de lectura, escritura, etc pero ahorita no es necesario. Lo que quiero controlar es que no puedan entrar a todos los módulos con su contraseña.
  • La captura de este Password Alternativo, al momento de escribirlo NO DEBE PODERLO VER LA PERSONA QUE LO ESCRIBE, pero deberá de confirmarlo dos veces antes de grabarlo por eso deberá de presentarse con asteriscos ese campo.
  • El Acceso a los módulos, es por supuesto acceso a NUESTROS módulos. Para ello se deberá crear otra tabla. No la cree yo por falta de tiempo a través del creador de tablas de Maxicomercio. Me gustaría que se enlazara a tuser pero utilizando el Sys_GUID. Es eso posible??? Toma en cuenta que en un futuro replicaremos la tabla de acceso a módulos a las tiendas y es posible que cambie el Sys_PK. 
  • Para administrar los accesos se ocupan dos tablas. La tabla de accesos y la tabla que contendrá el listado de módulos. Lo visualizo de la siguiente manera:
Tabla 1: ut_mismodulos
* Campos normales que agrega Maxicomercio +
ut_codigo
ut_nombre

Tabla 2: ut_accesos
* Campos normales que agrega el Maxicomercio +
ut_folio
ut_PKUser
ut_PKModulo
ut_Status

Comentarios: El folios sería un número consecutivo además del Sys_PK para llevar nuestro control de relaciones.

El PKUser y el PKModulo son  los que hacen el enlace entre el nombre del módulo y el usuario.

Status sería si está activo o no. En este caso sería Booleano.

  • Si tienes alguna idea de como hacerlo de alguna manera más fácil lo comentamos. El chiste sería no limitar la cantidad de módulos y que estos puedan ser variables.
  • La otra opción es hacer perfiles, tal y como lo maneja Maxicomercio, al perfil es a quien le dices a qué módulos tienes acceso y luego relacionas el perfil con el usuario. Pero eso debemos comentarlo. Piensalo.
  • En donde sale el Grid de usuarios podría agregarse el botón para Crear y Editar el Listado de Módulos (Nosotros al hacer el módulo deberemos identificarlo para que se valide contra algún folio o código que definamos)

Espero que haya podido plasmar mis ideas, seguimos en contacto!