23 de agosto de 2018

Cerrar aplicación si un usuario esta mucho tiempo sin trabajar

¿Cuantas veces nos hemos encontrado que nuestros usuarios se van a tomar un cafe o marchan a comer con la aplicación abierta?

La verdad, es que a mi esto me há dado bastantes problemas, ya que realizo las copias de seguridad al mediodia. Y día si, día también hay usuarios que dejan la aplicación abierta, con el problema de que la copia no se realiza ya que los usuarios dejan archivos abiertos.

La solución es la siguiente:

crear un timer (p.ejemplo) programado para 15-20 minutos, y el el evento timer programar los pasos necesarios para cerrar la aplicación.

para que el timer no se dispare cuando los usuarios estan trabajando hago lo siguiente:

En el evento mouse move del formulario y en el keypress de cada objeto, hago:

IF VARTYPE(gotimer_inactividad)="O"
 * la cuenta atras de tiempo se inicia otra vez
    gotimer_inactividad.interval = gocsapp.tiempo_espera
ENDIF

En mi caso la parte del formulario la hago solo una vez, ya que todos mis formularios son hijos de uno maestro definido como una clase base.

¿Que codigo se pone para cerrar la aplicación? Depende de lo que desees hacer, es decir puedes no querer cerrar a un usuario si esta en el medio de una grabación,... yo en mi caso les cierro la aplicación descartando cualquier cambio que hayan realizado.

¿Drastico? Si, pero despues de que los usuarios pierden su trabajo dos veces, debido a su negligencia, os aseguro que no volveran a dejar el ordenador indebidamente encendido.

NOTAS:

gotimer_inactividad - es el objeto timer creado al iniciar la aplicación

gocsapp - es una clase general a todas las aplicaciones que desarrollo,
   tiene propiedades y metodos habituales.

gocsapp.tiempo_espera - define el tiempo de espera para lanzar el timer. Es
   por si aumento o disminuyo el tiempo de espera para no tener que cambiarselo
   a todos los objetos. Normalmente ahi le pongo 900000

Pablo Roca

8 de agosto de 2018

Copiar todo el contenido de un GRID a una hoja de cálculo de Excel

A veces puede ser cómodo utilizar VFP para calcular, extraer o preparar una vista, la cual puede ser visualizada utilizando un GRID. Pero no hay duda que una hoja de cálculo de Excel ofrece muchas mas posibilidades para elaborar, analizar y estudiar los datos preparados, o simplemente el usuario a veces sabe manejar bien Excel y prefiere usar esta herramienta.

VFP tiene una gran integración con estos sistemas y veremos lo fácil que es copiar el contenido de un GRID en una hoja de Excel.

Lo único que necesitamos es unas pocas líneas de código que podríamos poner, por ejemplo, en el evento click de un botón. Imaginando que el botón esté en el mismo formulario que el grid, el código será el siguiente:

LOCAL cErrores, lExcel

* BUSCO UNA SESION DE EXCEL YA ACTIVA:
cErrores = ON("ERROR")
ON ERROR lExcel = .F.
oExcel = GetObject(,"excel.application")
ON ERROR &cErrores

IF TYPE("oExcel")    * NO ESTABA ACTIVA. PREPARO UNA NUEVA SESION DE EXCEL:
   oExcel = CREATEOBJECT("Excel.Application")
ENDIF
oExcel.VISIBLE = .T.    && VISUALIZO EXCEL
oExcel.Workbooks.ADD    && PREPARO UN NUEVO TRABAJO DE EXCEL

SELE (THISFORM.GRID1.RECORDSOURCE)
GO TOP
nRows = 0
* EMPIEZO A CARGAR LA HOJA DE EXCEL LEYENDO LA ESTRUCTURA DEL GRID:
WITH THISFORM.GRID1
   SCAN
      nRows = nRows + 1
      FOR nColumn = 1 TO .COLUMNCOUNT
         oExcel.Cells(nRows,nColumn) = EVAL(.COLUMNS(nColumn).CONTROLSOURCE)
      NEXT nColumn
   ENDSCAN
ENDWITH

Pablo Roca

20 de julio de 2018

Evitar que un programa activado desde VFP se cargue más de una vez y visualizarla

La misma función que hemos visto en el caso anterior puede ser usada para evitar que un programa externo se cargue mós de una vez. Un ejemplo sencillo es el de la calculadora de Windows.

Imaginemos que en nuestra aplicación demos la posibilidad de utilizar la calculadora. Pondríamos una línea come esta:

RUN /N CALC.EXE

Pero si esta línea la ejecutamos más de una vez, se cargarás la calcuadora una y otra vez.

* Antes de activar la calculadora:
IF NOT F_ActivaWin("Calculadora")
    * La calculadora no está cargada:
    RUN /N CALC.EXE
ENDIF

* Y ESTA ES LA FUNCION QUE LO HACE TODO:
*-----------------------------
FUNCTION F_ActivaWin(cCaption)
*-----------------------------
LOCAL nHWD
DECLARE INTEGER FindWindow IN WIN32API ;
STRING cNULL, ;
STRING cWinName

DECLARE SetForegroundWindow IN WIN32API ;
INTEGER nHandle

DECLARE SetActiveWindow IN WIN32API ;
INTEGER nHandle

DECLARE ShowWindow IN WIN32API ;
INTEGER nHandle, ;
INTEGER nState

nHWD = FindWindow(0, cCaption)
IF nHWD > 0
    * VENTANA YA ACTIVA
    * LA "LLAMAMOS":
    ShowWindow(nHWD,9)

    * LA PONEMOS ENCIMA
    SetForegroundWindow(nHWD)

    * LA ACTIVAMOS
    SetActiveWindow(nHWD)
    RETURN .T.
ELSE
    * VENTANA NO ACTIVA
    RETURN .F.
ENDIF

Pablo Roca