Árvore de páginas

Você está vendo a versão antiga da página. Ver a versão atual.

Comparar com o atual Ver Histórico da Página

Versão 1 Próxima »

ErrorBlock

Es importante el uso del errorblock cuando no es posible aceptar que un determinado procesamiento genere un error no amigable para el usuario o cuando el procesamiento se ejecuta por job o en una thread, y es necesario tratar el error, ya sea apuntando a una futura acción o conectándose a algún lugar, como, por ejemplo, en la consola del Protheus.

Esta función ErrorBlock define la actuación de un manejador (handler) de errores siempre que ocurra un error en tiempo de ejecución. Para ello, el manejador de errores se especifica con un bloque de código de la siguiente manera:
{ |<objError>| <lista de expresiones>, ...}
Se tienen:
<objError> es un error object que contiene información sobre el error. Dentro del bloque de código, es posible enviar mensajes al error object para obtener información sobre el error. Sin embargo, si el bloque de tratamiento de errores retorna verdadero (.T.), la operación que falló se repite; en caso contrario, falso (.F.), el procesamiento se iniciará nuevamente.
Si no se especifica ningún bloque de código, en el parámetro <bErrorHandler>, utilizando la función ErrorBlock(), y ocurre un error en tiempo de ejecución, se evalúa el bloque de tratamiento de errores estándar. Este manejador de errores mostrará un mensaje descriptivo en la pantalla, ajustará la función ErrorLevel a 1, y después saldrá del programa (QUIT).
Como esta función retorna el bloque de tratamiento al de errores corrientes, es posible especificar un bloque de tratamiento de errores para una operación grabando el bloque de manejo de errores corrientes y recuperándolo después al final de la operación. Además, una importante consecuencia del hecho que los bloques de tratamiento de errores se especifiquen como bloques de código es que pueden transferirse a rutinas y funciones definidas por el usuario y después retornar como valores.
Ejemplo:
// ErrorBlockExample.prw
#INCLUDE "TOTVS.CH"
Function ErrorBlockExample()
Local cError := ""
Local oLastError := ErrorBlock({|e| cError := e:Description + e:ErrorStack})
Local uTemp := Nil
uTemp := "A" + 1
ErrorBlock(oLastError)
// Anota el error en la consola.
ConOut(cError)
Return

FieldPos


La función FieldPos tiene la funcionalidad de retornar la posición dentro del diccionario de datos de un determinado campo y si el campo no existe retorna cero.
De esta manera, siempre que se haga una referencia a un determinado campo, creado por un compatibilizador, o creado en la versión/release, proteja la ejecución con el FieldPos.
Ejemplo:
// FieldPosExample.prw
#INCLUDE "TOTVS.CH"
Function FieldPosExample()
RpcSetEnv("99", "01")
If FieldPos("A1_NEW") > 0
cRet := SA1->A1_NEW
Else
ConOut("Field A1_NEW doesn`t exist.")
EndIf
Return
En este ejemplo, observamos cómo proteger de un error, cuando se hace referencia a un campo (A1_NEW) que no existe.

Type

La función Type() tiene la funcionalidad de retornar el tipo de dato de una determinada variable, con la ventaja de tener éxito aunque la variable no exista, diferente de la función ValType().
Se recomienda el uso de Type() cuando no se puede saber si una variable estática o pública existe y este conocimiento es necesario. Generalmente se utiliza cuando se pretende grabar el estado de una variable antes de modificarla, para que pueda restaurarse posteriormente, como sucede con las variables N, aCols y aHeader.
Ejemplo:
// TypeExample.prw
#INCLUDE "TOTVS.CH"
Function TypeExample()
Local nLastN := Nil
If Type("N") != "U"
nLastN := N
EndIf
// Haz alguna cosa con la variable N.
If Type("N") != "U"
N := nLastN
EndIf
Return

ValType


La función ValType() tiene la funcionalidad de retornar el tipo de dato de una determinada variable, cuya existencia es obligatoria, con la ventaja de ser una función de ejecución más rápida que la Type().
Se recomienda el uso del ValType() cuando el contenido de una variable no está correcta, como en el siguiente ejemplo, cuyo retorno del punto de entrada tiene que verificarse porque puede suceder que no retorne el contenido correcto:
Ejemplo:
// ValTypeExample.prw
#INCLUDE "TOTVS.CH"
Function ValTypeExample()
Local lExistFilPE := ExistBlock("DUMMYEP")
If lExistFilPE
cFilPE := ExecBlock("DUMMYEP", .F., .F., {})
If ValType(cFilPE) == "C"
ConOut("Uso cFilePE.")
Else
ConOut("Algo está equivocado.")
EndIf
EndIf
Return
User Function DUMMYEP()
Return 10
Salida:
Something goes wrong.

Array

Existen algunos cuidados necesarios para la creación y utilización de variables del tipo array, como por ejemplo:

  • En la creación siempre debe inicializarse como un Array.
    • Ejemplo:


// ArrayInitializationSample.prw
Local aRet1 := {}
Local aRet2 := Array()
De esta manera garantizamos que cuando utilicemos funciones como Len(), no se mostrará "Error".

  • Cargar en líneas en lugar de colocarlos en una sola línea de comando y colocar una posición por línea.
    • Ejemplo:


// ArrayAAddSample.prw
AAdd(aRet,{ X3Titulo(),; // 01
X3_CAMPO,; // 02
X3_PICTURE,; // 03
X3_TAMANHO,; // 04
X3_DECIMAL,; // 05
X3_VALID,; // 06
X3_USADO,; // 07
X3_TIPO,; // 08
X3_ARQUIVO,; // 09
X3_CONTEXT,; // 10
X3_PROPRI } ) // 11

  • Para ayudar en el mantenimiento y utilización de este Array, es importante documentar siempre cada posición.
    • Ejemplo:


// ArrayAssignmentSample.prw
// [01] Descuentos
// [02] Corrección monetaria
// [03] Intereses
// [04] Aumento
// [05] Decremento
// [06] Descuento
// [07] Valor original del título
// [08] Saldo del título en la moneda del título
// [09] Saldo del título en la moneda corriente
// [10] Pago parcial
// [11] Valor que se recibirá en la moneda del título
// [12] Valor que se recibirá en la moneda corriente
aRdpTlc[1][2] := aRdpTlc[1][2] + aValores[2]
aRdpTlc[2][2] := aRdpTlc[2][2] + aValores[10]
aRdpTlc[3][2] := aRdpTlc[3][2] + aValores[8]
aRdpTlc[4][2] := aRdpTlc[4][2] + aValores[5]
aRdpTlc[5][2] := aRdpTlc[5][2] + aValores[4]
aRdpTlc[6][2] := aRdpTlc[6][2] + aValores[9]
aRdpTlc[7][2] := aRdpTlc[7][2] + aValores[1]
aRdpTlc[8][2] := aRdpTlc[8][2] + aValores[6]
aRdpTlc[9][2] := aRdpTlc[9][2] + aValores[7]
aRdpTlc[10][2]:= aRdpTlc[10][2] + aValores[3]
aRdpTlc[11][2]:= aRdpTlc[11][2] + aValores[11]
aRdpTlc[12][2]:= aRdpTlc[12][2] + aValores[12]

  • Antes de referenciar los datos de un Array, es necesario verificar si realmente tiene datos cargados, para que no haya error.
    • Ejemplo:


// ArrayReferenceSample.prw
If Len(aRet) > 0
cRet := aRet[1]
EndIf

Preconfiguración de parámetros de función

A todas las funciones que reciben información por medio de los parámetros, es necesario colocar una Preconfiguración de cada uno de estos, respetando la regla de negocio y en caso de que no haya cómo hacerlo, simplemente inicializarla. De esta manera, siempre que estos parámetros se utilicen en líneas de códigos como condición, comparación y etc., quedarán protegidas de errores.
Ejemplo:
// DefaultExample.prw
Function DefaultExample()
OldFunction()
Return
Static Function OldFunction( nNewPar )
Local nRet := 0
Default nNewPar := 10
// Utilizo el nNewPar sin problema.
nRet := 10 * nNewPar
Return nRet
De esta manera, si la función "OldFunction" se llama sin el parámetro cNewPar informado, no ocurrirá error.

  • Sem rótulos