20 de julio de 2004

Número de semana

A pesar de que existe la función nativa WEEK() que retorna el número de la semana del año, esta no satisfacía una necesidad que se me presentó, por lo que elaboré la función SEMANA() y su inversa.

Mi necesidad, era la de agrupar una consulta de todo un año, por el número de la semana. Aunque en la función WEEK() se puede especificar por ejemplo si la primer semana del año contiene el 1° de Enero, y cual será el primer día de la semana; ésta puede retornar el mismo valor para la primer semana de Enero como para la última semana de Diciembre, lo que me causaba un problema en el agrupado de mi consulta.
*-- Ejemplo de WEEK()
? WEEK(DATE(2004,1,2),1,1) && Primer semana de Enero de 2004
? WEEK(DATE(2004,12,29),1,1) && Ultima semana de Diciembre de 2004
La diferencia de la función WEEK() con la función SEMANA(), es que ésta última no retorna resultados repetidos para los meses de Enero y Diciembre.
*-- Ejemplo de SEMANA()
? SEMANA(DATE(2004,1,2),1) && Primer semana de Enero de 2004
? SEMANA(DATE(2004,12,29),1) && Ultima semana de Diciembre de 2004
A continuación, el código de las funciones SEMANA() e INVSEMANA(), ejemplos de uso y las diferencias entre WEEK() y SEMANA().
*-- Diferencias entre WEEK() y SEMANA()
ld = DATE(2004,12,15)
FOR ln = 1 TO 30
  ? ld, WEEK(ld,1,1), Semana(ld,1)
  ld = ld + 1
ENDFOR

*-- Ejemplo de INVSEMANA()
FOR ln = 1 TO 7
  ld = InvSemana(3,2005,ln,1)
  ? ld, CDOW(ld)
ENDFOR  

*------------------------------------------------------------
* FUNCTION Semana(tdFecha, tnPriDiaSem)
*------------------------------------------------------------
* Retorna el número de semana de una Fecha
* USO: Semana(DATE(2004,06,03),2)
* PARAMETROS:
*    tdFecha     = Fecha
*    tnPriDiaSem = Primer día de la semana (1=Domingo, ..., 7=Sábado)
* RETORNO: Numérico
*------------------------------------------------------------
FUNCTION Semana(tdFecha, tnPriDiaSem)
  IF EMPTY(tdFecha)
    RETURN 0
  ENDIF
  IF EMPTY(tnPriDiaSem)
    tnPriDiaSem = 1
  ENDIF
  RETURN INT((tdFecha - DATE(YEAR(tdFecha),1,1) + ;
    7 - DOW(tdFecha,tnPriDiaSem)) / 7) + 1
ENDFUNC

*------------------------------------------------------------
* FUNCTION InvSemana(tnSemana, tnAnio, tnNroDiaSem, tnPriDiaSem)
*------------------------------------------------------------
* Retorna una fecha a partir de un número de semana
* USO: InvSemana(23,2004,5,2)
* PARAMETROS:
*    tnSemana    = Número de semana
*    tnAnio      = Año de la semana
*    tnNroDiaSem = Número del día de la semana (1=Domingo, ..., 7=Sábado)
*    tnPriDiaSem = Primer día de la semana (1=Domingo, ..., 7=Sábado)
* RETORNO: Fecha
*------------------------------------------------------------
FUNCTION InvSemana(tnSemana, tnAnio, tnNroDiaSem, tnPriDiaSem)
  IF EMPTY(tnAnio)
    tnAnio = YEAR(DATE())
  ENDIF
  IF EMPTY(tnNroDiaSem)
    tnNroDiaSem = 1
  ENDIF
  IF EMPTY(tnPriDiaSem)
    tnPriDiaSem = 1
  ENDIF
  RETURN DATE(tnAnio,1,1) + (tnSemana * 7) - 7 + ;
    tnNroDiaSem - DOW(DATE(tnAnio,1,1),tnPriDiaSem)
ENDFUNC
*------------------------------------------------------------
Hasta la próxima.

Luis María Guayán

4 comentarios :

  1. hola disculpa, recién aprendo a programar en vfp... como llamo esa función? en el programa?

    ResponderEliminar
    Respuestas
    1. *-- Ejemplo de uso Función SEMANA()
      ? SEMANA(DATE(2004,1,2),1) && Primer semana de Enero de 2004
      ? SEMANA(DATE(2004,12,29),1) && Ultima semana de Diciembre de 2004

      Eliminar
    2. Hola Luis Muchas gracias por tu pronta respuesta me explico lo que necesito tal vez pueda ayudarme el año tiene 53 semanas Yo quisiera en un combo poner los número de semanas del 1 al 53 y al seleccionarlo por ejemplo en la semana 20 que me diga qué Rango de fechas están comprendidas en esta semana Y a qué mes pertenece no sé si eso sea posible hacerlo con esta función Gracias De antemano por la ayuda brindada

      Eliminar
    3. En el mismo artículo tienes la función inversa InvSemana(), para tu caso:

      ? InvSemana(20,2016,1,1) && PRIMER DIA DE LA SEMANA 20
      ? InvSemana(20,2016,1,7) && ULTIMO DIA DE LA SEMANA 20

      Eliminar