Explicación de los certificados de pipetas
Como se menciona en Elementos de configuración del módulo Pipette, se proporcionan dos certificados Pipette de ejemplo: PIPETTE y PIPETTE COLUMNS. Ambos son idénticos, salvo por un par de pequeñas diferencias.
Empecemos por las diferencias: SubReport5 y SubReport6 se utilizan para mostrar las muestras individuales, respectivamente.
En PIPETTE, en SubReport5: Report, la opción Columns está establecida en 1, y en SubReport5: Detail, la opción ColumnTraversal está establecida en ctTopToBottom.


Por el contrario, en PIPETTE COLUMNS, SubReport5: Report tiene la opción Columns establecida en 4, y SubReport5: Detail tiene la opción ColumnTraversal establecida en ctLeftToRight.


En el resto de este análisis se utilizará la plantilla de certificación PIPETTE. Si observamos el árbol de informes, los informes «Main», «SubReport1», «SubReport3» y «SubReport4» correspondientes a certificados, eventos, maestros y procedimientos de eventos son bastante estándar. Por lo tanto, no se revisarán.

Los subinformes SubReport2 y SubReport5 se utilizan para mostrar los datos tal y como se encontraron, si los hay. Los informes SubReport7 y SubReport6 se utilizan para mostrar los datos de «Saldo pendiente», si los hay.
Si echas un vistazo al SubReport2, podrás ver la configuración básica.

Dado que todos los datos ambientales del estado «tal y como se encontró» se almacenan en todos los puntos de prueba, el título lo refleja. Cada grupo de cuatro puntos de prueba que representan un canal o una muestra determinados tiene el mismo texto en la columna «Grupo», por lo que se ha configurado una agrupación en ese campo, y en el pie de página del grupo aparece «un punto de prueba». Se utiliza la lógica de las hojas de cálculo para organizar los datos de forma adecuada. En el certificado PIPETTE, SubReport5 superpone los datos de modo que los datos de la primera muestra aparezcan alineados con los datos del resumen. En PIPETTE COLUMNS, aparece debajo de los datos resumidos.
El resto de las características que hacen que esto sea especial se encuentran en la pestaña «Cálculo». A modo de referencia, a continuación se muestran los controladores de eventos para cada subinforme:




Si los repasamos por orden de ejecución, empezaremos por SubReport2.
procedimiento TitleBeforeGenerate;
empezar
si UncertaintyOn = '1', entonces
empezar
Label61.visible := true;
Label70.Visible := true;
fin
o bien
empezar
Label61.visible := false;
Label70.Visible := false;
fin;
fin;
El único objetivo de «TitleBeforeGenerate» es ocultar la columna «Uncertainty» si no se ha registrado ningún valor en «Uncertainty». En los clientes a partir de la versión 11, la incertidumbre siempre se registra.
procedimiento TitleBeforePrint;
empezar
si '0' = ReturnFromSQL('SELECT COUNT(*) FROM CALPNTSEXTRA WHERE EVENT_NUM='+IntToStr(Events['Event Number'])+' AND FIELD_NAME LIKE ''AS FOUND%''') entonces
empezar
Title.Visible := false;
fin
o bien
empezar
Title.Visible := true;
fin;
fin;
TitleBeforePrint se utiliza para determinar si hay datos «tal y como se encontraron» y ocultar o mostrar el título en consecuencia.
procedimiento GroupHeaderBand1BeforePrint;
empezar
Label46.Caption := '';
Label47.Caption := '';
Label48.Caption := '';
Label49.Caption := '';
Label50.Caption := '';
Label51.Caption := '';
Label67.Caption := '';
Label70.Caption := '';
Label67.Caption := 'Aprobado';
si CalibrationTestPoints['As Found Num 4'] <> 0 entonces
Label100.Caption := FormatFloat('0.00000', CalibrationTestPoints['Valor medido n.º 1'] / CalibrationTestPoints['Valor medido n.º 4'])
o bien
Label100.Caption := '';
fin;
GroupHeaderBand1BeforePrint se utiliza para restablecer los datos del pie de página. Esto garantiza que no tengamos datos desactualizados. También calcula el factor Z sin procesar (Label100).
Para DetailBeforePrint, voy a dividir el código en partes.
procedimiento DetailBeforePrint;
Var
I, I2, I3, iNumResolution, iResResolution, iUncResolution : entero ;
sRes, sRes2, sResUnc, sDummy: String;
empezar
iNumResolution := StrToIntDef(CalibrationTestPoints['Res.'], 6);
iResResolution := StrToIntDef(CalibrationTestPoints['Result Res.'], 0);
iUncResolution := StrToIntDef(CalibrationTestPoints['Uncertainty Res.'], 6);
sRes := '#######0';
sRes2 := '#######0';
sResUnc := '#######0';
Si ((iNumResolution >= 0) y
(iNumResolution <=12) entonces
i2 := iNumResolution; si no, i2 := 6;
Si i2>0, entonces
empezar
sRes := sRes + '.';
para i := 0 hasta i2-1 hacer
empezar
sRes := sRes + '0';
fin;
fin;
Si ((iResResolution > 0) y
(iResResolution <= 12) entonces
empezar
i3 := iResResolution;
sRes2 := sRes2 + '.';
para i := 0 a i3-1 hacer
empezar
sRes2 := sRes2 + '0';
fin;
fin; si no, sRes2 := sRes;
Si ((iUncResolution > 0) y
(iUncResolution <=12) entonces
empezar
i3 := iUncResolution;
sResUnc := sResUnc + '.';
para i := 0 a i3-1 hacer
empezar
sResUnc := sResUnc + '0';
fin;
fin; si no, sResUnc := sRes;
El apartado anterior tiene un único objetivo: crear las cadenas para configurar la resolución que se utilizan en las llamadas a FormatFloat que aparecen a continuación. Así es como se muestran los datos del certificado con la misma resolución que en la tabla de resultados.
si CalibrationTestPoints['Description'] = (CalibrationTestPoints['Group'] + 'media') entonces
empezar
Label46.Caption := FormatFloat(sRes, CalibrationTestPoints['As Found']);
Label70.Caption := FormatFloat(sResUnc, CalibrationTestPoints['Uncertainty']);
fin
else if CalibrationTestPoints['Description'] = (CalibrationTestPoints['Group'] + ' SD') then
empezar
Label47.Caption := FormatFloat(sRes, CalibrationTestPoints['As Found']);
fin
else if CalibrationTestPoints['Description'] = (CalibrationTestPoints['Group'] + ' acc') then
empezar
Label48.Caption := FormatFloat(sRes, CalibrationTestPoints['As Found']);
Label49.Caption := FormatFloat(sRes, CalibrationTestPoints['Tolerancia +']);
Label59.Caption := 'Precisión ' + CalibrationTestPoints['Unit'];
Label104.Caption := FormatFloat(sRes, CalibrationTestPoints['N.º 5 tal y como se encontró']);
fin
else if CalibrationTestPoints['Description'] = (CalibrationTestPoints['Group'] + ' prec') then
empezar
Label50.Caption := FormatFloat(sRes, CalibrationTestPoints['As Found']);
Label51.Caption := FormatFloat(sRes, CalibrationTestPoints['Tolerancia +']);
Label65.Caption := 'Precisión ' + CalibrationTestPoints['Unit'];
Label105.Caption := FormatFloat(sRes, CalibrationTestPoints['As Found Num 5']);
fin;
si (CalibrationTestPoints['Verdict'] = 'A') o (CalibrationTestPoints['Verdict'] = 'F') entonces
Label67.Caption := 'Error';
fin;
En esta sección se analizan los campos «Group» y «Description» y se utilizan para determinar qué dato se está examinando (las líneas «if CalibrationTestPoints['Description']=(CalibrationTestPoints['Group']+»). Para cada sección, se configuran los campos «Tal y como se encontró», «Tolerancia» y «Unidad» en el pie de página del grupo. También comprueba si los resultados de «Tal y como se encontró» han dado error o no.
Como puedes ver, aquí es donde se encuentra la mayor parte de la lógica.
procedimiento GroupFooterBand1BeforePrint;
empezar
si '0' = ReturnFromSQL('SELECT COUNT(*) FROM CALPNTSEXTRA WHERE EVENT_NUM='+IntToStr(Events['Event Number'])+' AND SEQ='+CalibrationTestPoints['#']+' AND FIELD_NAME LIKE ''AS FOUND%''') entonces
empezar
GroupFooterBand1.Visible := false;
fin
o bien
empezar
GroupFooterBand1.Visible := true;
fin;
fin;
GroupFooterBand1BeforePrint simplemente oculta o muestra el pie de página del grupo en función de si hay o no datos tal y como se encontraron para el «punto de prueba» actual. Esto eliminará los datos que hayas omitido al recopilarlos.
Pasando al SubReport5, solo hay un controlador de eventos.
procedimiento DetailBeforePrint;
Var
I, I2, iNumResolution: entero;
sRes, sDummy, sValue, sUnits : String ;
empezar
iNumResolution := StrToIntDef(CalibrationTestPoints['Res.'], 6);
sRes := '#######0';
Si ((iNumResolution >= 0) y
(iNumResolution <=12) entonces
i2 := iNumResolution; si no, i2 := 6;
Si i2>0, entonces
empezar
sRes := sRes + '.';
para i := 0 hasta i2-1 hacer
empezar
sRes := sRes + '0';
fin;
fin;
DBText43.DisplayFormat := sRes;
sDummy := CalibrationTestPointsExtra['Valor de campo (texto)'];
sValue := copy(sDummy, 1, pos(' ', sDummy) - 1);
sUnits := copy(sDummy, pos(' ', sDummy) + 1, length(sDummy));
Label96.Caption := FormatFloat(sRes, StrToFloat(sValue)) + ' ' + sUnits;
si copy(CalibrationTestPointsExtra['Nombre del campo'], 1, 8) = 'TAL CUAL' entonces
empezar
Label52.Caption := inttostr(strtoint(copy(CalibrationTestPointsExtra['Field Name'], 10, 10000)));
Detail.visible := true;
fin
o bien
empezar
Label52.Caption := inttostr(strtoint(copy(CalibrationTestPointsExtra['Field Name'],9,10000)));
Detail.visible := false;
fin;
fin;
El único objetivo de esta lógica es calcular la cadena de resolución, aplicar dicha resolución a la masa y al volumen, y controlar la visibilidad en función de si se trata o no de una muestra «tal cual».
Las reglas personalizadas para SubReport7 y SubReport6 son básicamente las mismas, salvo que se han ajustado para que se apliquen a «Tal y como está» en lugar de «Tal y como se encontró».