miércoles, 28 de noviembre de 2012

Calcular dias de diferencia entre 2 fechas

Saludos. Algunas veces necesitamos calcular los dias de diferencia entre dos fechas. Por ejemplo... cuantos dias hay entre el 01/08/2012 y el 01/09/2012 (agosto - septiembre) y obtener el resultado en un numero entero especifico (30 dias). Imaginemos que tenemos un text1 donde ingresamos la fecha inicial (01/08/2012/) y un text2, donde ingresamos la fecha final (01/09/2012). Ambos tienen una D (formato fecha) en la propiedad Format de la pestaña DATA. En el Init del fomr configuramos (segun se desee) el tipo de siglo:

**--Para mostrar 2012 en lugar de 12
SET CENTURY ON

Luego, copiamos este codigo en algun evento:

LOCAL ldFechaDesde, ldFechaHasta, ldDiaD, ldMesD, ldAnoD,  ldDiaH, ldMesH, ldAnoH, lnFechaResul

*Fecha inicial
ldFechaDesde = CTOD(ALLTRIM(THISFORM.Text1.Value))

    ldAnoD = YEAR(ldFechaDesde)
    ldMesD = MONTH(ldFechaDesde)
    ldDiaD = DAY(ldFechaDesde)
   
**Fecha final
    ldFechaHasta = CTOD(ALLTRIM(THISFORM.Text2.Value))
   
        ldAnoH = YEAR(ldFechaHasta)
        ldMesH = MONTH(ldFechaHasta)
        ldDiaH = DAY(ldFechaHasta)
**
lnFechaResul =  DATE(ldAnoH, ldMesH, ldDiaH) - DATE(ldAnoD, ldMesD, ldDiaD)

MESSAGEBOX(lnFechaResul)


Y listo. Guardamos y ejecutamos.  El numero de dias lo tenemos contenido en la variable lnFechaResul y podemos proceder a hacer uso efectivo de el.

Saludos! Desde Managua, Nicaragua!
Ravenn :D :D :D

jueves, 15 de noviembre de 2012

Crear / Diseñar un formulario de acceso (Login) a nuestras aplicaciones - Visual FoxPro.

Saludos. En reiteradas ocasiones me han consultado como hacer un form de acceso (login) para nuestras aplicaciones. La solucion es sencilla. :)

 Todo parte de seguir una logica coherente: tenemos un formulario principal de nuestra aplicacion que es desde donde ejecutamos todas las transacciones. Para poder acceder a el, debemos "logearnos" o ingresar al sistema. Para esto, creamos un formulario adicional en donde podamos ingresar nuestro usuario y contraseña correspondiente. Asi mismo, debe existir, en la base de datos, una tabla en donde se lleve el control de los usuarios, contraseñas y accesos al sistema. Con accesos me refiero a los privilegios de entrada, visualizacion, adicion, modificacion y elimacion de registros. Este tema en especifico, lo tomaremos en la siguiente publicacion.

Veamos pues como se procede:

1. Diseñemos la tabla: los nombres de usuario y contraseña se almacenaran aqui. Creamos una tabla llamada "usuario" con los campos: codigousuario (numerico, width = 5, index = regular) , nom_usuar (caracter, width = 20, index = regular), contraseña (caracter, width = 15). Asi:


**Carguemos en la tabla algunos datos... para que podamos probar la funcionalidad posteriormente. Ingresemos el codigo: 1020 - usuario: Ravenn -  Contraseña: blogspot129

**Posterior a la creacion del login, se debe proceder a crear un form para la gestion (altas, bajas y modificaciones de los usuarios. Este punto, queda totalemente a criterio de los usuarios :)

2. Diseñemos el FORM: procedemos a crear un formulario para poder acceder con nuestro usuario y contraseña. Para esto, vamos al diseñador de forms y creamos un formulario llamado "Login" con los controles basicos necesarios, tales como: 2 cuadros de texto (TxtNom_Usuar, TxtContraseña), dos botones de comando (Command1, Command2). Uno para ingresar y otro para salir. Asi:


3. Escribimos el codigo:para esto, procedemos a crear un nuevo metodo en el formulario llamado "ingresar". Para esto, vamos al menu de foxpro, en el diseñador de forms y en el menu FORM, desplegamos y escogemos la opcion "NewMethod". Luego, vamos a las propiedades del form, en la pestaña Method y buscamos el metodo que acabamos de crear. Damos Db click y escribimos el siguiente codigo:

**--Ingreso**--

SELECT  usuario

SET ORDER to nom_usuar

SEEK  ALLTRIM(thisform.txtNom_usuar.value)        &&Asigna valor a variables&&

**--Devolvemos resultado
IF FOUND () AND ALLTRIM (THISFORM.txtContraseña.value) = ALLTRIM (usuario.Contraseña)
   
    **Si se encuentra el usuario y contraseña registrados.
   **Llamamos al form principal
   **Cerramos el form login

    DO FORM "principal.scx"
    THISFORM.Release
   
    **Si no encontramos usuario o contraseña
    ELSE
   
        MESSAGEBOX("El usuario y contraseña no son validos. Asegurese de digitar un usuario registrado.", 16, ;
       Error - Usuario y contraseña invalidos")
   
  **Cancelamos accion
   CANCEL

ENDIF

**--Fin--**


Ahora, vamos al evento click del Command 1 y llamamos al metodo:

THISFORM.ingresar

En el command2, escribimos (Salir):

THISFORM.Release

4. Agregamos la tabla: hacemos click derecho sobre el form y escogemos la opcion "data enviroment", ah buscamos la tabla usuario y la agregamos al entorno de datos de nuestro form.

 5. Desactivamos la tecla BloqMayus en contraseña: para evitar errores de escritura entre mayusculas y minusculas, podemos desactivar la tecla bloq mayus (para escribir solo minisculas) cuando el txtContraseña reciba el enfoque. Para esto, creamos otro metodo adicional al form llamado "desactivarBqMay" y en el, escribimos eset codigo:

**--Comprobamos el estado de la techa BloqMayus
**--Si esta encendida, procedemos a apagarla
**--CAPSLOCK() devuelve el estado de la tecla ON/OFF


IF CAPSLOCK() = .T.

        CAPSLOCK(.F.)

ENDIF
**--Fin**--

Ahora, en el evento GotFocus del TxtContraseña, llamamos al metodo:

**--
THISFORM.desactivarBqMay
**--

6. Configurar propiedades y funciones del Form: esto con el objetivo de mejorar el rendimiento del la aplicacion y evitar errores futuros.

6.1 **En las propiedades del form, en la pestaña DATA, escogemos la propiedad BufferMode y la establecemos en 2 - Optimistic. Asi mismo, la propiedad DATESESSION y establecemos 2 - private datesession (necesario para - SET EXCLUSIVE OFF - abrir archivos en modo compartido en red).

6.2 **En el evento INIT() del form, escribimos el siguiente conjunto de instrucciones.

**--Configuracion inicial
**----------------------
**----------------------

**--Apagamos conversacion de VFP
SET TALK OFF

**--Desactivamos registros marcados para eliminacion
SET DELETED ON

**--Por si usamos fecha para una vitacora de ingresos
**--El formato es dia/mes/año
SET DATE BRITISH

**--Necesario para modo compartido
SET MULTILOCKS ON


**--Abrir archivos en modo compartido
SET EXCLUSIVE OFF

**--Centrar el form
THISFORM.AutoCenter = .T.



**--Importante:
**--Configuramos modo (de bloqueo) compartido (Buffer) de tabla
**--Evitamos conflictos en red
CURSORSETPROP("Buffering", 5, "usuario")





Y listo. Guardemos y ejecutemos. Escribamos el usuario y contraseña.

Esta es una forma segura y sencilla de logearnos en nuestro sistema. No es la unica ni la mejor. Solo mi opinion! Cualquier duda, a la orden! Comenten!


Saludos! Desde Managua, Nicaragua!
Ravenn :D :D :D 


miércoles, 14 de noviembre de 2012

Generar un levantamiento de datos automatico de una tabla

Saludos. Siempre buscamos como automatizar mas los procedimientos de nuestras aplicaciones. :) Por ejemplo, para una aplicacion de facturacion, necesitamos introducir varios productos en un form (control grid) y para esto, es mas rapido si vamos digitando el codigo del producto y al presionar enter que se generen los datos de dicho producto, tales como descripcion, unidad de medida, precio, impuestos.. etc. Para lograr esto, procedemos asi:

Imaginemos que tenemos una tabla llamada "productos" con los campos: codigo, descripcion, unidadmedida, preciounitario. Queremos que, en un form de facturacion, digitemos (en una columna de un grid) el codigo del producto y que al presionar ENTER, se muestren los datos (en el resto de columnas) del producto de forma automatica.

1. Vamos al entorno de datos del formulario y agregamos la tabla que contiene los datos que vamos a "levantar" o "llamar": productos

2. En este ejemplo, tomamos que el codigo del producto se digitara en el text1 de la columna1 del grid1 y el resto de columnas mostraran la informacion al presionar enter. Para esto, escribimos un codigo como este en el evento KeyPress del text1 de la column1 del grid1:

**--

IF nKeyCode = 13     &&Presionamos enter
   
        SELECT productos
              LOCATE FOR productos.codigo = VAL(THISFORM.Grid1.Column1.Text1.Value)

                  IF FOUND()
                           **Cargamos descripcion
                           THISFORM.Grid1.Column2.Text1.Value = productos.descripcion
                           **Cargamos Unidad medida
                           THISFORM.Grid1.Column3.Text1.Value = productos.unidadmedida
                           **Cargamos precio
                           THISFORM.Grid1.Column4.Text1.Value = productos.preciounitario


                                         ELSE
                              
                                                   MESSAGEBOX("Producto no registrado en sistema. Verifique, 48, "Error")

ENDIF
**--


Guardamos y ejecutamos.

Saludos! Desde Managua, Nicaragua!
Ravenn :D :D :D












Saber el numero de registros marcados para eliminacion

Saludos. Algunas veces, necesitamos saber el numero de registros que hemos marcado para eliminacion (eliminados con DELETE y establecido SET DELETED en "ON") en nuestras tablas. Una forma sencilla de saber cuantos registros tenemos eliminados (no fisicamente) es asi:

1. Establecemos SET DELETED ON en el init del form



2.

LOCAL lnRegDel

**--
SELECT facturas

COUNT FOR DELETED() TO lnRegDel

MESSAGEBOX(lnRegDel)

**--

Saludos. Desde Managua, Nicaragua!
Ravenn :D :D :D

lunes, 12 de noviembre de 2012

Activar procesos con el teclado en metodo abreviado

Saludos. A veces necesitamos activar ciertos procesos en nuestros forms con las teclas (por lo general F1, F2...). Por ejemplo, activar un (form) calendario al presionar la tecla F9, agregar un nuevo registro al presionar la tecla F3, editar un registro con la tecla F4... cerrar un form con la tecla F12... entre otros. La solucion es asi:

1. En las propiedades del form, vamos a la pestaña OTHER y seleccionamos la propiedad Keypreview, estableciendola en .T.

2. Vamos al metodo KEYPRESS del formulario y colocamos un codigo como este:

**--Generamos calendario
IF nKeyCode = -3    &&Corresponde a F4
    THISFORM.activarcalendario
ENDIF


Lo que debemos hacer es buscar en la tabla de valores de la funcion INKEY() el valor correspondiente a la tecla que deseamos... o combinacion de teclas. Aqui dejo el link de la tabla!

http://msdn.microsoft.com/es-es/library/cc451013%28v=vs.71%29.aspx


Una vez escogido, solo asignamos el valor a nkeyCode, abajo colocamos el procedimiento que queremos, y listo. :)


Saludos! :) Desde Managua, Nicaragua.
Ravenn :D

viernes, 9 de noviembre de 2012

Importar hoja de excel a tabla (.dbf) de foxpro

Saludos. A veces  necesitamos importar un documento de excel a una tabla fisica (.dbf) o un cursor temporal de foxpro. Una forma practica de hacerlo es asi:

1.  Debemos, primeramente, tener en cuenta que el archivo de excel debe estar guardado en formato 5.0. Para esto, escogemos la opcion 

Libro de Microsoft Excel 5.0/95 (*.xls)

2.  Debemos tener en cuenta tambien que la etructura de la hoja de calculo debe ser similar a la de la tabla, en el sentido que si una de las columnas de excel almacena datos de fecha, el campo donde dichos datos seran guardados, debe ser tipo DATE.

3. Copiamos el siguiente codigo (en un boton [click] , por ejemplo):

LOCAL lcXlsArchivo

   
lcXlsArchivo = GETFILE('xls','Nombre:','Abrir',0 ,'Abrir Archivo de Planilla de Excel')

**--Si cancelamos la apertura
IF EMPTY(lcXlsArchivo)
    RETURN .F.
ENDIF
   
**--Si abrimos archivo, guardamos en cursor

SELECT personaltemp

APPEND FROM (xarchivo) TYPE XLS



Y listo. Ya tenemos un cursor guardado con datos de una hoja de excel 5.0 :)



SALUDOS! Desde Managua, Nicaragua! Raven :D

Generar un MENU CONTEXTUAL (con click derecho del mouse) para CORTAR, COPIAR, PEGAR

Saludos. Algunas veces deseamos colocar alguans opciones, tales como CORTAR - COPIAR - PEGAR al hacer click derecho sobre algun objeto (textbox, commandButton, etc...), asi:



La forma sencilla de hacerlo, es colocar el siguiente codigo en el evento RIGHTCLICK del objeto:


DEFINE POPUP menuccp  FROM MROW(),MCOL() ;
 SHORTCUT RELATIVE  MARGIN  COLOR RGB(255,255,255);
 FONT 'MS Sans Serif', 8
      DEFINE BAR  _MED_CUT OF menuccp  PROMPT "Cortar     Ctrl + X"   PICTURE 'cut.png'
      DEFINE BAR _MED_COPY OF menuccp PROMPT  "Copiar     Ctrl + C" PICTURE 'copiar.png'
      DEFINE BAR _MED_PASTE OF menuccp PROMPT "Pegar      Ctrl + V" PICTURE 'paste.png'
      DEFINE BAR 4 OF menuccp PROMPT '\-' 
      DEFINE BAR 5 OF menuccp PROMPT "Calculadora" PICTURE 'calc.png'
     
      **--Calculadora
      ON SELECTION BAR 5 OF menuccp ! /N calc.EXE
     
     
ACTIVATE POPUP menuccp
**--//Fin

Y listo. :D Guarden los cambios y ejecuten. Yo le agregue una opcion mas para activar la calculadora de WINDOWS! Pueden agregar n numero de opciones deseadas!


Saludos! Desde Managua, Nicaragua!
Ravenn! :D

Convertir un numero NEGATIVO (-) a POSITIVO (+)

Saludos! A veces necesitamos convertir un numero resultado negativo a positivo. Es facil. Asi:

ABS(numeronegativo)


**--

ABS(-45)

**--Resultado 45


Es una sencilla operacion, pero que a veces nos puede servir de mucho.

Saludos! Desde Managua, Nicaragua!
Ravenn

jueves, 8 de noviembre de 2012

Restar Dias a una Fecha

Saludos! Para restar dias enteros de una fecha, asi:

10/12/2012 - 3 = 07/12/2012

podemos proceder de la sieguiente manera:


LOCAL ldFecha, ldAnno, ldMes, ldDia, ldFecFinal

ldFecha = CTOD(10/12/2012)

**--Extraemos el Anno
ldAnno = YEAR(ldFecha)

**--Extraemos en Mes
ldMes = MONTH(ldFecha)

**--Extraemos el dia
ldDia = DAY(ldFecha)

**--Restamos el numero entero de dias a la fecha
ldFecFinal = DATE(ldAnno, ldMes, ldDia) - 3

**--Resultado
**--07/12/2012


Es una forma practica y segura de restar dias (NO UNA FECHA DE OTRA) enteros a una fecha especifica. Por ejemplo, saber que fecha es 15/12/2012 si restamos 5 dias = 10/12/2012


Saludos! Desde Managua, Nicaragua.
Ravenn