Files
MBS/PROYECTO/nodir/noprrp045.4gl
T

666 lines
26 KiB
Plaintext

{
-------------------------------------------------------------------------------
PROGRAMA : NOPRRP045
OBJETIVO : Informe para el Ministerio de Trabajo.
Genera (en el server, via motor de reportes) el
cuadro de:
- Monto en RD$ (SUELDO del mes) por NIVEL
EDUCATIVO, por mes y por sexo.
- Cantidad de empleados por mes y por sexo.
Se muestra en el visor de reportes; desde ahi el
usuario lo exporta a EXCEL o PDF.
FUENTES DE DATOS : Nivel educativo -> adtb00003.nivel_emp -> adtb00005
Sexo -> adtb00021.sexo ('M'/'F', titular
con cod_par IS NULL)
Sueldo -> notb00008.valor WHERE cod_mov = 1
(solo sueldo, sin horas extras)
DISENO : noprrp045.4rp (datos: noprrp045.rdd, rutina r_min)
PROGRAMADOR : Ing. Juan F. Soto
FECHA REALIZACION : Julio 30, 2026
-------------------------------------------------------------------------------
}
GLOBALS "noprgb000.4gl"
DEFINE p_anio INTEGER -- ano a reportar
MAIN
DEFER INTERRUPT
CALL ARG_VAL(1) RETURNING usuarios
CALL ARG_VAL(2) RETURNING clave
CALL startlog("noprrp045.log")
CONNECT TO "smarmotech" USER usuarios USING clave
SELECT a.* INTO p_companias.* FROM companias a
CALL noprrp045()
END MAIN
FUNCTION noprrp045()
DEFINE monto ARRAY[12,25] OF DECIMAL(16,2) -- [fila 6..12, col 2..25]
DEFINE conteo ARRAY[25] OF INTEGER -- [col 2..25]
DEFINE f, c, m SMALLINT
DEFINE r_nom CHAR(30)
DEFINE r_mes SMALLINT
DEFINE r_sexo CHAR(1)
DEFINE r_monto DECIMAL(16,2)
DEFINE r_cant INTEGER
DEFINE fila_e SMALLINT
DEFINE sin_edu DECIMAL(16,2)
DEFINE sin_sex DECIMAL(16,2)
DEFINE th, tm DECIMAL(18,2) -- totales de monto por mes (H, M)
DEFINE hay_datos SMALLINT
DEFINE niveles ARRAY[7] OF CHAR(35)
DEFINE vals DYNAMIC ARRAY OF VARCHAR(24)
LET niveles[1] = "NINGUNO"
LET niveles[2] = "PRIMARIA"
LET niveles[3] = "SECUNDARIA"
LET niveles[4] = "TECNICO SUPERIOR"
LET niveles[5] = "ESTUDIANTE UNIVERSITARIO"
LET niveles[6] = "GRADO UNIVERSITARIO (LICENCIATURA)"
LET niveles[7] = "POSGRADO"
OPTIONS FORM LINE 8, ERROR LINE 23, COMMENT LINE 21
CLEAR SCREEN
OPEN FORM nofmrp045 FROM "nofmrp045"
DISPLAY FORM nofmrp045
DISPLAY "noprrp045" AT 4,3 ATTRIBUTE(RED)
DISPLAY "Informe Ministerio de Trabajo" AT 6,25 ATTRIBUTE(BLACK)
LET p_anio = YEAR(TODAY)
INPUT BY NAME p_anio WITHOUT DEFAULTS
AFTER FIELD p_anio
IF p_anio IS NULL OR p_anio < 1990 OR p_anio > 2100 THEN
CALL fgl_winmessage("Aviso", "Digite un ano valido.", "stop")
NEXT FIELD p_anio
END IF
ON ACTION cancel
RETURN
AFTER INPUT
IF int_flag THEN
LET int_flag = FALSE
RETURN
END IF
END INPUT
------------------------------------------------------------------
-- Inicializa acumuladores
------------------------------------------------------------------
FOR f = 1 TO 12
FOR c = 1 TO 25
LET monto[f,c] = 0
END FOR
END FOR
FOR c = 1 TO 25
LET conteo[c] = 0
END FOR
LET sin_edu = 0
LET sin_sex = 0
LET hay_datos = FALSE
DISPLAY "Buscando informacion... Espere por favor" AT 19,14
ATTRIBUTE(REVERSE, BOLD)
------------------------------------------------------------------
-- (1) Monto RD$ = SUELDO (cod_mov=1) por nivel educativo / mes / sexo
------------------------------------------------------------------
LET selec =
"SELECT RTRIM(ISNULL(ed.nom_educa,'')) AS nom_educa, ",
" MONTH(n.fecha) AS mes, ",
" ISNULL(dep.sexo,'') AS sexo, ",
" SUM(n.valor) AS monto ",
"FROM notb00008 n ",
" JOIN adtb00003 e ON e.num_emp = n.num_emp ",
" LEFT JOIN adtb00005 ed ON ed.cod_educa = e.nivel_emp ",
" LEFT JOIN (SELECT num_emp, MAX(sexo) AS sexo ",
" FROM adtb00021 WHERE cod_par IS NULL ",
" GROUP BY num_emp) dep ON dep.num_emp = e.num_emp ",
"WHERE YEAR(n.fecha) = ", p_anio, " ",
" AND n.cod_mov = 1 ", -- SOLO SUELDO (sin horas extras ni otros ingresos)
"GROUP BY RTRIM(ISNULL(ed.nom_educa,'')), MONTH(n.fecha), ISNULL(dep.sexo,'') "
PREPARE q_monto FROM selec
DECLARE cur_monto CURSOR FOR q_monto
FOREACH cur_monto INTO r_nom, r_mes, r_sexo, r_monto
LET hay_datos = TRUE
LET c = col_grid(r_mes, r_sexo)
IF c = 0 THEN
LET sin_sex = sin_sex + r_monto
CONTINUE FOREACH
END IF
LET fila_e = fila_educa(r_nom)
IF fila_e = 0 THEN
LET sin_edu = sin_edu + r_monto
CONTINUE FOREACH
END IF
LET monto[fila_e,c] = monto[fila_e,c] + r_monto
END FOREACH
------------------------------------------------------------------
-- (2) Cantidad de empleados por mes / sexo (solo con SUELDO, cod_mov=1)
------------------------------------------------------------------
LET selec =
"SELECT MONTH(n.fecha) AS mes, ",
" ISNULL(dep.sexo,'') AS sexo, ",
" COUNT(DISTINCT n.num_emp) AS cant ",
"FROM notb00008 n ",
" JOIN adtb00003 e ON e.num_emp = n.num_emp ",
" LEFT JOIN (SELECT num_emp, MAX(sexo) AS sexo ",
" FROM adtb00021 WHERE cod_par IS NULL ",
" GROUP BY num_emp) dep ON dep.num_emp = e.num_emp ",
"WHERE YEAR(n.fecha) = ", p_anio, " ",
" AND n.cod_mov = 1 ", -- solo empleados con SUELDO en el mes
"GROUP BY MONTH(n.fecha), ISNULL(dep.sexo,'') "
PREPARE q_cant FROM selec
DECLARE cur_cant CURSOR FOR q_cant
FOREACH cur_cant INTO r_mes, r_sexo, r_cant
LET c = col_grid(r_mes, r_sexo)
IF c = 0 THEN
CONTINUE FOREACH
END IF
LET conteo[c] = conteo[c] + r_cant
END FOREACH
IF NOT hay_datos THEN
CALL fgl_winmessage("Informe Ministerio",
"No existe nomina procesada para el ano "||p_anio USING "&&&&"||".",
"stop")
RETURN
END IF
------------------------------------------------------------------
-- Motor de reportes: carga el diseno y arranca el visor (preview).
-- Desde el visor el usuario exporta a EXCEL o PDF.
------------------------------------------------------------------
LET r_filename = "noprrp045.4rp"
IF NOT fgl_report_loadCurrentSettings(r_filename) THEN
CALL fgl_winmessage("Error",
"No se encontro el diseno del reporte (noprrp045.4rp).", "stop")
RETURN
END IF
-- El usuario elige el formato de salida (EXCEL / PDF / SVG) con la
-- funcion compartida seleccionarSalida() (otrodir/seleccionarsalida.4gl).
LET preview = 1
CALL seleccionarSalida() RETURNING r_output
CALL fgl_report_selectDevice(r_output)
CALL fgl_report_selectPreview(preview)
LET handler = fgl_report_commitCurrentSettings()
START REPORT r_min TO XML HANDLER handler
-- fila de titulo con empresa y ano
FOR c = 1 TO 36
LET vals[c] = " "
END FOR
CALL emite_fila("T",
p_companias.nombre CLIPPED||" - ANO "||(p_anio USING "&&&&"), vals)
-- 7 filas de monto (grid 6..12 -> niveles 1..7).
-- Por cada mes se emiten 3 columnas: Hombre, Mujer, Total (H+M).
FOR f = 6 TO 12
FOR m = 1 TO 12
LET vals[3*m-2] = monto[f,2*m] USING "-###,###,##&.&&"
LET vals[3*m-1] = monto[f,2*m+1] USING "-###,###,##&.&&"
LET vals[3*m] = (monto[f,2*m]+monto[f,2*m+1]) USING "-###,###,##&.&&"
END FOR
CALL emite_fila("A", niveles[f-5], vals)
END FOR
-- fila TOTAL MONTO EMPLEADO: suma de todos los niveles por mes.
-- (Hombre = suma de todos los H; Mujer = suma de todas las M; Total = H+M)
-- Sirve para cuadrar con el total de la nomina pagada.
FOR m = 1 TO 12
LET th = 0
LET tm = 0
FOR f = 6 TO 12
LET th = th + monto[f,2*m]
LET tm = tm + monto[f,2*m+1]
END FOR
LET vals[3*m-2] = th USING "-###,###,##&.&&"
LET vals[3*m-1] = tm USING "-###,###,##&.&&"
LET vals[3*m] = (th+tm) USING "-###,###,##&.&&"
END FOR
CALL emite_fila("M", "TOTAL MONTO EMPLEADO", vals)
-- fila de conteo total de empleados (Hombre, Mujer, Total por mes)
FOR m = 1 TO 12
LET vals[3*m-2] = conteo[2*m] USING "-###,###,##&"
LET vals[3*m-1] = conteo[2*m+1] USING "-###,###,##&"
LET vals[3*m] = (conteo[2*m]+conteo[2*m+1]) USING "-###,###,##&"
END FOR
CALL emite_fila("C", "TOTAL EMPLEADOS", vals)
-- Secciones 4-8: foto demografica de empleados activos (status_t IS NULL) a hoy
CALL emite_demografia()
FINISH REPORT r_min
CLEAR SCREEN
------------------------------------------------------------------
-- Aviso de datos que no se pudieron clasificar (no se pierden en
-- silencio: se informa para corregir el maestro)
------------------------------------------------------------------
IF sin_edu > 0 OR sin_sex > 0 THEN
CALL fgl_winmessage("Datos sin clasificar",
"Monto sin nivel educativo mapeado: "||(sin_edu USING "-#,###,###,##&.&&")||
"\nMonto de empleados sin sexo en adtb00021: "||(sin_sex USING "-#,###,###,##&.&&")||
"\n\nRevise el nivel educativo (nivel_emp/adtb00005) y el sexo de "||
"esos empleados en la maestra.", "exclamation")
END IF
END FUNCTION
------------------------------------------------------------------------
-- Emite una fila al reporte. tipo: 'A'=monto RD$, 'C'=conteo
------------------------------------------------------------------------
FUNCTION emite_fila(p_tipo, p_nivel, p_vals)
DEFINE p_tipo CHAR(1)
DEFINE p_nivel CHAR(60)
DEFINE p_vals DYNAMIC ARRAY OF VARCHAR(24)
DEFINE reg RECORD
tipo CHAR(1),
nivel CHAR(60),
v01 VARCHAR(24), v02 VARCHAR(24), v03 VARCHAR(24), v04 VARCHAR(24),
v05 VARCHAR(24), v06 VARCHAR(24), v07 VARCHAR(24), v08 VARCHAR(24),
v09 VARCHAR(24), v10 VARCHAR(24), v11 VARCHAR(24), v12 VARCHAR(24),
v13 VARCHAR(24), v14 VARCHAR(24), v15 VARCHAR(24), v16 VARCHAR(24),
v17 VARCHAR(24), v18 VARCHAR(24), v19 VARCHAR(24), v20 VARCHAR(24),
v21 VARCHAR(24), v22 VARCHAR(24), v23 VARCHAR(24), v24 VARCHAR(24),
v25 VARCHAR(24), v26 VARCHAR(24), v27 VARCHAR(24), v28 VARCHAR(24),
v29 VARCHAR(24), v30 VARCHAR(24), v31 VARCHAR(24), v32 VARCHAR(24),
v33 VARCHAR(24), v34 VARCHAR(24), v35 VARCHAR(24), v36 VARCHAR(24)
END RECORD
LET reg.tipo = p_tipo
LET reg.nivel = p_nivel
LET reg.v01 = p_vals[1] LET reg.v02 = p_vals[2]
LET reg.v03 = p_vals[3] LET reg.v04 = p_vals[4]
LET reg.v05 = p_vals[5] LET reg.v06 = p_vals[6]
LET reg.v07 = p_vals[7] LET reg.v08 = p_vals[8]
LET reg.v09 = p_vals[9] LET reg.v10 = p_vals[10]
LET reg.v11 = p_vals[11] LET reg.v12 = p_vals[12]
LET reg.v13 = p_vals[13] LET reg.v14 = p_vals[14]
LET reg.v15 = p_vals[15] LET reg.v16 = p_vals[16]
LET reg.v17 = p_vals[17] LET reg.v18 = p_vals[18]
LET reg.v19 = p_vals[19] LET reg.v20 = p_vals[20]
LET reg.v21 = p_vals[21] LET reg.v22 = p_vals[22]
LET reg.v23 = p_vals[23] LET reg.v24 = p_vals[24]
LET reg.v25 = p_vals[25] LET reg.v26 = p_vals[26]
LET reg.v27 = p_vals[27] LET reg.v28 = p_vals[28]
LET reg.v29 = p_vals[29] LET reg.v30 = p_vals[30]
LET reg.v31 = p_vals[31] LET reg.v32 = p_vals[32]
LET reg.v33 = p_vals[33] LET reg.v34 = p_vals[34]
LET reg.v35 = p_vals[35] LET reg.v36 = p_vals[36]
OUTPUT TO REPORT r_min(reg.*)
END FUNCTION
------------------------------------------------------------------------
-- Rutina de reporte. Un registro por fila del cuadro.
------------------------------------------------------------------------
REPORT r_min(x)
DEFINE x RECORD
tipo CHAR(1),
nivel CHAR(60),
v01 VARCHAR(24), v02 VARCHAR(24), v03 VARCHAR(24), v04 VARCHAR(24),
v05 VARCHAR(24), v06 VARCHAR(24), v07 VARCHAR(24), v08 VARCHAR(24),
v09 VARCHAR(24), v10 VARCHAR(24), v11 VARCHAR(24), v12 VARCHAR(24),
v13 VARCHAR(24), v14 VARCHAR(24), v15 VARCHAR(24), v16 VARCHAR(24),
v17 VARCHAR(24), v18 VARCHAR(24), v19 VARCHAR(24), v20 VARCHAR(24),
v21 VARCHAR(24), v22 VARCHAR(24), v23 VARCHAR(24), v24 VARCHAR(24),
v25 VARCHAR(24), v26 VARCHAR(24), v27 VARCHAR(24), v28 VARCHAR(24),
v29 VARCHAR(24), v30 VARCHAR(24), v31 VARCHAR(24), v32 VARCHAR(24),
v33 VARCHAR(24), v34 VARCHAR(24), v35 VARCHAR(24), v36 VARCHAR(24)
END RECORD
DEFINE fecha_actual DATE
FORMAT
FIRST PAGE HEADER
LET fecha_actual = TODAY
PRINTX p_companias.nombre, p_anio, fecha_actual
ON EVERY ROW
PRINTX x.tipo, x.nivel,
x.v01, x.v02, x.v03, x.v04, x.v05, x.v06,
x.v07, x.v08, x.v09, x.v10, x.v11, x.v12,
x.v13, x.v14, x.v15, x.v16, x.v17, x.v18,
x.v19, x.v20, x.v21, x.v22, x.v23, x.v24,
x.v25, x.v26, x.v27, x.v28, x.v29, x.v30,
x.v31, x.v32, x.v33, x.v34, x.v35, x.v36
END REPORT
------------------------------------------------------------------------
-- Devuelve la fila del formato (6..12) segun el nombre del nivel
-- educativo (catalogo adtb00005). 0 = no mapeado.
-- BASICA->7 SECUNDARIA/BACHILLER->8 TECNICO->9
-- ESTUDIANTE UNIVERSITARIO->10 PROFESIONAL->11
-- DIPLOMADO/POSTGRADO/MAESTRIA/ESPECIALIDAD/DOCTORADO->12
-- El orden importa: POSTGRADO antes que GRADO; ESTUDIANTE antes que
-- UNIVERSITARIO.
------------------------------------------------------------------------
FUNCTION fila_educa(p_nom)
DEFINE p_nom STRING
DEFINE s CHAR(40)
LET s = UPSHIFT(p_nom CLIPPED)
IF s CLIPPED = "" THEN RETURN 0 END IF
IF s MATCHES "*NINGUN*" THEN RETURN 6 END IF
IF s MATCHES "*PRIMARIA*" OR s MATCHES "*BASICA*"
THEN RETURN 7 END IF
IF s MATCHES "*SECUNDAR*" OR s MATCHES "*BACHILLER*"
THEN RETURN 8 END IF
IF s MATCHES "*TECNIC*" THEN RETURN 9 END IF
IF s MATCHES "*ESTUDIANTE*" THEN RETURN 10 END IF
IF s MATCHES "*POSGRAD*" OR s MATCHES "*POSTGRAD*"
OR s MATCHES "*MAESTR*" OR s MATCHES "*DOCTORAD*"
OR s MATCHES "*ESPECIALIDAD*" OR s MATCHES "*DIPLOM*"
THEN RETURN 12 END IF
IF s MATCHES "*LICENCIAT*" OR s MATCHES "*GRADO*"
OR s MATCHES "*UNIVERSITARI*" OR s MATCHES "*PROFESIONAL*"
THEN RETURN 11 END IF
RETURN 0
END FUNCTION
------------------------------------------------------------------------
-- Columna del grid (2..25) segun mes (1..12) y sexo.
-- Hombre ('M') -> 2*mes Mujer ('F') -> 2*mes+1 0 = invalido
------------------------------------------------------------------------
FUNCTION col_grid(p_mes, p_sexo)
DEFINE p_mes SMALLINT
DEFINE p_sexo CHAR(1)
IF p_mes < 1 OR p_mes > 12 THEN RETURN 0 END IF
CASE UPSHIFT(p_sexo)
WHEN "M" RETURN 2 * p_mes
WHEN "F" RETURN 2 * p_mes + 1
OTHERWISE RETURN 0
END CASE
END FUNCTION
------------------------------------------------------------------------
-- Secciones 4-8: foto demografica de los empleados ACTIVOS (status_t IS
-- NULL) al dia de hoy. Cuenta empleados (sec 8 = promedio de sueldo_ac).
-- Edad -> adtb00003.fech_nac a hoy
-- Antiguedad -> adtb00003.fech_efec a hoy
-- Sexo -> adtb00021 (titular, cod_par IS NULL)
-- Nivel -> adtb00005 via nivel_emp
-- E.civil -> adtb00003.estado_civil
------------------------------------------------------------------------
FUNCTION emite_demografia()
DEFINE e_sexo CHAR(1)
DEFINE e_ecivil CHAR(1)
DEFINE e_fnac DATE
DEFINE e_fefec DATE
DEFINE e_sueldo DECIMAL(12,2)
DEFINE e_nom CHAR(30)
DEFINE si, nf, ageg, teng, mi SMALLINT
DEFINE edad, tanios INTEGER
DEFINE i, g SMALLINT
DEFINE tot, th_, tm_ INTEGER
DEFINE prom DECIMAL(16,2)
DEFINE gsum DECIMAL(18,2)
DEFINE gcnt INTEGER
DEFINE vals DYNAMIC ARRAY OF VARCHAR(24)
DEFINE c4 ARRAY[7,2] OF INTEGER -- nivel x (H,M)
DEFINE c5 ARRAY[7,5] OF INTEGER -- nivel x grupo edad
DEFINE c6 ARRAY[6,7] OF INTEGER -- e.civil x (H,M,edad1..5)
DEFINE c7 ARRAY[5,7] OF INTEGER -- antiguedad x (H,M,edad1..5)
DEFINE s8sum ARRAY[6,5] OF DECIMAL(18,2) -- suma sueldo por (estado civil, grupo edad)
DEFINE s8cnt ARRAY[6,5] OF INTEGER
DEFINE csum DECIMAL(18,2)
DEFINE ccnt INTEGER
DEFINE niv ARRAY[7] OF CHAR(35)
DEFINE agl ARRAY[5] OF CHAR(8)
DEFINE mar ARRAY[6] OF CHAR(20)
DEFINE ten ARRAY[5] OF CHAR(14)
LET niv[1]="NINGUNO" LET niv[2]="PRIMARIA"
LET niv[3]="SECUNDARIA" LET niv[4]="TECNICO SUPERIOR"
LET niv[5]="ESTUDIANTE UNIVERSITARIO" LET niv[6]="GRADO UNIVERSIT. (LIC.)"
LET niv[7]="POSGRADO"
LET agl[1]="18-25" LET agl[2]="26-30" LET agl[3]="31-40"
LET agl[4]="41-50" LET agl[5]="51+"
LET mar[1]="SOLTERO(A)" LET mar[2]="CASADO(A)" LET mar[3]="UNION LIBRE"
LET mar[4]="DIVORCIADO(A)" LET mar[5]="VIUDO(A)" LET mar[6]="NO INDICADO"
LET ten[1]="MENOS DE 1" LET ten[2]="1 A 5" LET ten[3]="6 A 10"
LET ten[4]="11 A 20" LET ten[5]="MAS DE 20"
FOR i=1 TO 7 LET c4[i,1]=0 LET c4[i,2]=0 END FOR
FOR i=1 TO 7 FOR g=1 TO 5 LET c5[i,g]=0 END FOR END FOR
FOR i=1 TO 6 FOR g=1 TO 7 LET c6[i,g]=0 END FOR END FOR
FOR i=1 TO 5 FOR g=1 TO 7 LET c7[i,g]=0 END FOR END FOR
FOR i=1 TO 6 FOR g=1 TO 5 LET s8sum[i,g]=0 LET s8cnt[i,g]=0 END FOR END FOR
LET selec =
"SELECT ISNULL(dep.sexo,''), ISNULL(e.estado_civil,''), e.fech_nac, ",
" e.fech_efec, ISNULL(e.sueldo_ac,0), RTRIM(ISNULL(ed.nom_educa,'')) ",
"FROM adtb00003 e ",
" LEFT JOIN adtb00005 ed ON ed.cod_educa = e.nivel_emp ",
" LEFT JOIN (SELECT num_emp, MAX(sexo) AS sexo FROM adtb00021 ",
" WHERE cod_par IS NULL GROUP BY num_emp) dep ON dep.num_emp = e.num_emp ",
"WHERE e.status_t IS NULL "
PREPARE q_demo FROM selec
DECLARE cur_demo CURSOR FOR q_demo
FOREACH cur_demo INTO e_sexo, e_ecivil, e_fnac, e_fefec, e_sueldo, e_nom
LET si = 0
IF UPSHIFT(e_sexo) = "M" THEN LET si = 1 END IF
IF UPSHIFT(e_sexo) = "F" THEN LET si = 2 END IF
LET nf = fila_educa(e_nom)
IF nf > 0 THEN LET nf = nf - 5 END IF -- 1..7 (0 si no mapea)
LET edad = anios_hasta_hoy(e_fnac)
LET ageg = 0
IF edad >= 0 THEN LET ageg = grupo_edad(edad) END IF
LET tanios = anios_hasta_hoy(e_fefec)
LET teng = 0
IF tanios >= 0 THEN LET teng = rango_antig(tanios) END IF
LET mi = grupo_marital(e_ecivil)
IF nf > 0 AND si > 0 THEN LET c4[nf,si] = c4[nf,si] + 1 END IF
IF nf > 0 AND ageg > 0 THEN LET c5[nf,ageg] = c5[nf,ageg] + 1 END IF
IF si > 0 THEN LET c6[mi,si] = c6[mi,si] + 1 END IF
IF ageg > 0 THEN LET c6[mi,2+ageg] = c6[mi,2+ageg] + 1 END IF
IF teng > 0 THEN
IF si > 0 THEN LET c7[teng,si] = c7[teng,si] + 1 END IF
IF ageg > 0 THEN LET c7[teng,2+ageg] = c7[teng,2+ageg] + 1 END IF
END IF
IF ageg > 0 THEN
LET s8sum[mi,ageg] = s8sum[mi,ageg] + e_sueldo
LET s8cnt[mi,ageg] = s8cnt[mi,ageg] + 1
END IF
END FOREACH
---------------- 4- Nivel academico por genero ----------------
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
CALL emite_fila("S", "4- NIVEL ACADEMICO POR GENERO", vals)
CALL limpia_vals(vals)
LET vals[1]="HOMBRE" LET vals[2]="MUJER" LET vals[3]="TOTAL"
CALL emite_fila("H", "NIVEL ACADEMICO", vals)
LET th_=0 LET tm_=0
FOR i=1 TO 7
CALL limpia_vals(vals)
LET vals[1] = c4[i,1] USING "-###,###,##&"
LET vals[2] = c4[i,2] USING "-###,###,##&"
LET vals[3] = (c4[i,1]+c4[i,2]) USING "-###,###,##&"
CALL emite_fila("D", niv[i], vals)
LET th_=th_+c4[i,1] LET tm_=tm_+c4[i,2]
END FOR
CALL limpia_vals(vals)
LET vals[1]=th_ USING "-###,###,##&" LET vals[2]=tm_ USING "-###,###,##&"
LET vals[3]=(th_+tm_) USING "-###,###,##&"
CALL emite_fila("D", "TOTAL", vals)
---------------- 5- Nivel academico por grupo de edad ----------------
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
CALL emite_fila("S", "5- NIVEL ACADEMICO POR GRUPO EDAD", vals)
CALL limpia_vals(vals)
FOR g=1 TO 5 LET vals[g]=agl[g] END FOR
LET vals[6]="TOTAL"
CALL emite_fila("H", "NIVEL ACADEMICO", vals)
FOR i=1 TO 7
CALL limpia_vals(vals)
LET tot=0
FOR g=1 TO 5
LET vals[g]=c5[i,g] USING "-###,###,##&"
LET tot=tot+c5[i,g]
END FOR
LET vals[6]=tot USING "-###,###,##&"
CALL emite_fila("D", niv[i], vals)
END FOR
CALL limpia_vals(vals)
LET tot=0
FOR g=1 TO 5
LET th_=0
FOR i=1 TO 7 LET th_=th_+c5[i,g] END FOR
LET vals[g]=th_ USING "-###,###,##&"
LET tot=tot+th_
END FOR
LET vals[6]=tot USING "-###,###,##&"
CALL emite_fila("D", "TOTAL", vals)
---------------- 6- Estatus marital por genero y grupo de edad ----------------
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
CALL emite_fila("S", "6- ESTADO CIVIL POR GENERO Y EDAD", vals)
CALL limpia_vals(vals)
LET vals[1]="HOMBRE" LET vals[2]="MUJER"
FOR g=1 TO 5 LET vals[2+g]=agl[g] END FOR
LET vals[8]="TOTAL"
CALL emite_fila("H", "ESTADO CIVIL", vals)
FOR i=1 TO 6
CALL limpia_vals(vals)
FOR g=1 TO 7 LET vals[g]=c6[i,g] USING "-###,###,##&" END FOR
LET vals[8]=(c6[i,1]+c6[i,2]) USING "-###,###,##&"
CALL emite_fila("D", mar[i], vals)
END FOR
---------------- 7- Tiempo en la empresa por genero y grupo de edad ----------------
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
CALL emite_fila("S", "7- ANTIGUEDAD POR GENERO Y EDAD (anos)", vals)
CALL limpia_vals(vals)
LET vals[1]="HOMBRE" LET vals[2]="MUJER"
FOR g=1 TO 5 LET vals[2+g]=agl[g] END FOR
LET vals[8]="TOTAL"
CALL emite_fila("H", "ANTIGUEDAD", vals)
FOR i=1 TO 5
CALL limpia_vals(vals)
FOR g=1 TO 7 LET vals[g]=c7[i,g] USING "-###,###,##&" END FOR
LET vals[8]=(c7[i,1]+c7[i,2]) USING "-###,###,##&"
CALL emite_fila("D", ten[i], vals)
END FOR
---------------- 8- Sueldo promedio por estado civil y grupo de edad ----------------
CALL limpia_vals(vals) CALL emite_fila("S", "", vals)
CALL emite_fila("S", "8- SUELDO PROMEDIO POR ESTADO CIVIL Y GRUPO EDAD", vals)
CALL limpia_vals(vals)
FOR g=1 TO 5 LET vals[g]=agl[g] END FOR
LET vals[6]="GENERAL"
CALL emite_fila("H", "ESTADO CIVIL", vals)
-- una fila por estado civil: promedio de sueldo por grupo de edad
FOR i=1 TO 6
CALL limpia_vals(vals)
LET gsum=0 LET gcnt=0
FOR g=1 TO 5
IF s8cnt[i,g] > 0 THEN
LET prom = s8sum[i,g] / s8cnt[i,g]
ELSE
LET prom = 0
END IF
LET vals[g] = prom USING "-###,###,##&.&&"
LET gsum = gsum + s8sum[i,g]
LET gcnt = gcnt + s8cnt[i,g]
END FOR
IF gcnt > 0 THEN LET prom = gsum / gcnt ELSE LET prom = 0 END IF
LET vals[6] = prom USING "-###,###,##&.&&"
CALL emite_fila("D", mar[i], vals)
END FOR
-- fila GENERAL: promedio por grupo de edad (todos los estados civiles)
CALL limpia_vals(vals)
LET gsum=0 LET gcnt=0
FOR g=1 TO 5
LET csum=0 LET ccnt=0
FOR i=1 TO 6
LET csum = csum + s8sum[i,g]
LET ccnt = ccnt + s8cnt[i,g]
END FOR
IF ccnt > 0 THEN LET prom = csum / ccnt ELSE LET prom = 0 END IF
LET vals[g] = prom USING "-###,###,##&.&&"
LET gsum = gsum + csum
LET gcnt = gcnt + ccnt
END FOR
IF gcnt > 0 THEN LET prom = gsum / gcnt ELSE LET prom = 0 END IF
LET vals[6] = prom USING "-###,###,##&.&&"
CALL emite_fila("D", "GENERAL", vals)
END FUNCTION
-- Limpia las 36 columnas de valores (las deja en blanco)
FUNCTION limpia_vals(v)
DEFINE v DYNAMIC ARRAY OF VARCHAR(24)
DEFINE i SMALLINT
FOR i = 1 TO 36
LET v[i] = " "
END FOR
END FUNCTION
-- Anos completos desde p_desde hasta hoy (-1 si es nulo)
FUNCTION anios_hasta_hoy(p_desde)
DEFINE p_desde DATE
DEFINE a INTEGER
IF p_desde IS NULL THEN RETURN -1 END IF
LET a = YEAR(TODAY) - YEAR(p_desde)
IF MONTH(TODAY) < MONTH(p_desde)
OR (MONTH(TODAY) = MONTH(p_desde) AND DAY(TODAY) < DAY(p_desde)) THEN
LET a = a - 1
END IF
RETURN a
END FUNCTION
-- Grupo de edad: 1=18-25 2=26-30 3=31-40 4=41-50 5=51+
FUNCTION grupo_edad(p_edad)
DEFINE p_edad INTEGER
IF p_edad <= 25 THEN RETURN 1 END IF
IF p_edad <= 30 THEN RETURN 2 END IF
IF p_edad <= 40 THEN RETURN 3 END IF
IF p_edad <= 50 THEN RETURN 4 END IF
RETURN 5
END FUNCTION
-- Rango antiguedad: 1=<1 2=1-5 3=6-10 4=11-20 5=20+
FUNCTION rango_antig(p_anos)
DEFINE p_anos INTEGER
IF p_anos < 1 THEN RETURN 1 END IF
IF p_anos <= 5 THEN RETURN 2 END IF
IF p_anos <= 10 THEN RETURN 3 END IF
IF p_anos <= 20 THEN RETURN 4 END IF
RETURN 5
END FUNCTION
-- Grupo estado civil: 1=S 2=C 3=U 4=D 5=V 6=otro/blanco
FUNCTION grupo_marital(p_ec)
DEFINE p_ec CHAR(1)
CASE UPSHIFT(p_ec)
WHEN "S" RETURN 1
WHEN "C" RETURN 2
WHEN "U" RETURN 3
WHEN "D" RETURN 4
WHEN "V" RETURN 5
OTHERWISE RETURN 6
END CASE
END FUNCTION