30 de abril de 2000

Busca un nombre de campo en una tabla

Buscar un nombre de campo en una tabla y retorna .T. si tuvo exito.
*--------------------------------------------------------
* FUNCTION FindField(lcCampo, lcAlias)
*--------------------------------------------------------
* Busca un nombre de campo en una tabla y retorna .T. si tuvo exito.
* USO: ? FindField("MiCampo", "MiAlias")
*      ? FindField("MiCampo") && Busca en el alias corriente
*--------------------------------------------------------
FUNCTION FindField(lcCampo, lcAlias)
  LOCAL ln
  IF EMPTY(lcAlias)
    lcAlias = ALIAS()
  ENDIF
  IF USED(lcAlias)
    ln = AFIELDS(MiArray, lcAlias)
    IF ln > 0
      ln = ASCAN(MiArray, UPPER(lcCampo))
    ENDIF
  ELSE
    ln = 0
    MESSAGEBOX("El alias no existe.",16)
  ENDIF
  RETURN ln 
ENDFUNC
Luis María Guayán

29 de abril de 2000

Calcular el domingo de pascua de un año

Con esta función podemos conocer la fecha del Domingo de Pascua de cualquier año.
*---------------------------------------------------------------
* FUNCTION _Pascua(tnAnio)
*---------------------------------------------------------------
* USE: _Pascua(1999)
* PARAMETRO: Año a calcular
* RETORNO: Fecha del Domingo de Pascua
*---------------------------------------------------------------
FUNCTION _Pascua(tnAnio)
  LOCAL lnCentena, lnAux, lnNroAureo, lnDomingo, lnEpactaJul, ;
    lnCorrSolar, lnCorrLunar, lnEpactaGreg, lnDiasLunaP, ;
    lnDiasLuna15, lnDiasPascua, ldFecIni, ldFecPascua

  IF NOT BETWEEN(tnAnio,1000,9999)
    MESSAGEBOX("Rango inválido [1000..9999]")
    RETURN {//}
  ENDIF

  lnCentena = INT(tnAnio / 100)
  lnAux = (tnAnio + 1) % 19
  lnNroAureo = lnAux + (19 * INT((19 - lnAux) / 19))
  lnDomingo = 7 + (1 - tnAnio - INT(tnAnio / 4) + lnCentena - INT(lnCentena / 4)) % 7
  lnEpactaJul = ((11 * lnNroAureo) - 10) % 30
  lnCorrSolar = - (lnCentena - 16) + INT((lnCentena- 16) / 4)
  lnCorrLunar = INT((lnCentena - 15 - INT((lnCentena - 17) / 25)) / 3)
  lnEpactaGreg = (30 + lnEpactaJul + lnCorrSolar + lnCorrLunar) % 30
  lnDiasLunaP = 24 - lnEpactaGreg + (30 * INT(lnEpactaGreg / 24))
  lnDiasLuna15 = (27 - lnEpactaGreg + (30 * INT(lnEpactaGreg / 24))) % 7
  lnDiasPascua = lnDiasLunaP + (7 + lnDomingo - lnDiasLuna15) % 7
  ldFecIni = DATE(tnAnio, 03, 21)
  ldFecPascua = ldFecIni + lnDiasPascua
  RETURN ldFecPascua
ENDFUNC

23 de abril de 2000

En que metodo pongo formatos especiales condicionados

En que metodo pongo formatos especiales condicionados, por ejemplo colores en funcion de su Value.

Trabajando con los textbox puede surgir la necesidad de ponerle un formato especial en función de que su valor (por ejemplo ponerlos en rojo, cuando su valor sea negativo).

Surge la duda de en que metodos poner el codigo para colorearlos, Valid, Refresh, ... ¿se me quedo alguno? ¿Como lo hago todo mas sencillo? ¿Tengo que repetir todo esto es cada texbox?

Bueno, lo primero pensar que deberiamos tener redefinida la clase estandard texbox (o aun mejor todas las clases visuales), y nuestros texbox hacerlos que dependieran de nuestras nuevas clases redefinidas, de tal manera que cuando hagamos un cambio en la clase cs_textbox (mi ejemplo), este se realice en todos los que usemos.

Trabajando con VFP6 + SP3, se podria estar tentado en utilizar el metodo value_assign, que es ejecutado cada vex que el valor de un textbox cambia, pero el metodo assign todavia tiene diversos bugs y problemas, como mas gordo citar que si se pone codigo en un value_assign (a nivel de clase), cualquier textbox de esa clase que usemos nos va a decir que se han realizado cambios en el (GETFLDSTATE), por tanto descartado el assign.

Los metodos a modificar son los siguientes:

  • InteractiveChange - Se modifica el valor con el raton
  • ProgrammaticChange - Se modifica el valor por codigo
  • Refresh - Se actualiza un textbox vinculado a datos (p.ejemplo con un SKIP)

En el ejemplo que estamos tratando, tambien creo un metodo a nivel de la clase texbox, por ejemplo llamado AnyChange y desde los tres metodos anteriores llamo a este AnyChange.

El codigo del AnyChange es:
IF VARTYPE(this.value)="N"
  this.forecolor = IIF(this.value < 0, RGB(255,0,0),0)
  this.disabledforecolor = IIF(this.value < 0,RGB(255,0,0),0)
ENDIF
Es decir si el valor es numerico y negativo lo pone en rojo.

Pablo Roca

18 de abril de 2000

Calcular la diferencia entre dos fechas en años, meses y días

Función para calcular la cantidad de años, meses y días entre dos variables tipo Date.
*-----------------------------------------------------
* FUNCTION Dif_AMD(tdIni, tdFin)
*-----------------------------------------------------
* Calcula la diferencia entre dos fechas en:
* años, meses y días
* Usa la función DiasDelMes()
*-----------------------------------------------------
FUNCTION Dif_AMD(tdIni, tdFin)
  LOCAL ldAux, lnAnio, lnMes, lnDia, lcRet
  *--- Fecha inicial siempre menor
  IF tdIni>tdFin
    ldAux = tdIni
    tdIni = tdFin
    tdFin = ldAux
  ENDIF
  lnAnio = YEAR(tdFin) - YEAR(tdIni)
  ldAux = GOMONTH(tdIni, 12 * lnAnio)
  *--- No cumplio el año aun
  IF ldAux > tdFin
    lnAnio = lnAnio - 1
  ENDIF
  lnMes = MONTH(tdFin) - MONTH(tdIni)
  IF lnMes < 0
    lnMes = lnMes + 12
  ENDIF
  lnDia = DAY(tdFin) - DAY(tdIni)
  IF lnDia < 0
    lnDia = lnDia + DiasDelMes(tdIni)
  ENDIF
  *--- Si el dia es mayor, no cumplio el mes
  IF (DAY(tdFin) < DAY(tdIni))
    IF lnMes = 0
      lnMes = 11
    ELSE
      lnMes = lnMes - 1
    ENDIF
  ENDIF
  lcRet = ALLTRIM(STR(lnAnio))+ " AÑOS, " + ;
    ALLTRIM(STR(lnMes))+ " MESES Y " + ;
    ALLTRIM(STR(lnDia))+ " DIAS."
  RETURN lcRet
ENDFUNC
*-----------------------------------------------------
* FUNCTION DiasDelMes(dFecha)
*------------------------------------------------
* Retorna los días de un mes. Usada por Dif_AMD
*------------------------------------------------
FUNCTION DiasDelMes(dFecha)
  LOCAL ld
  ld = GOMONTH(dFecha,1)
  RETURN DAY(ld - DAY(ld))
ENDFUNC
Luis María Guayán

14 de abril de 2000

Proteger y ocultar el codigo fuente de las clases

Haz una copia de los archivos VCX y VCT
COMPILE CLASSLIB libreriadeclases
USE libreriadeclases.vcx EXCLUSIVE
REPLACE ALL Methods WITH ""
USE
Esto eliminara todo el codigo fuente de un VCX. Si alguien intenta modificar un procedimiento entonces todas las clases dejarn de funcionar, ya que no hay codigo fuente a compilar.

Pablo Roca