A validação de colunas é especificada em dicField.CustomConstraint.
Estão disponíveis todos os recursos do ArScript, além de:
- As colunas da tabela sendo alterada como variáveis variants (escrita e leitura)
- A variável x, somente leitura, com o novo valor da coluna.
Se ocorrer um erro imprevisto na execução do script, Argow mostra a seguinte mensagem:
Ocorreu um erro ao avaliar a restrição dos valores válidos da coluna %s ...
Por esta razão, não é possível determinar a validade dos dados modificados.
e o usuário pode optar por atualizar a tabela ou não. Para não dar esta alternativa e
evitar a gravação, atribua T na variável de
configuração global SCRIPT_ONERROR_STOP.
A forma de escrever a validação pode ser:
- In-line,
- Notação rápida, e
- Referência a dicScript
In-line
Nesta notação o script está em dicField.CustomConstraint. O script deve
conter uma função, chamada Constraint, que retorna um valor booleano e recebe um parâmetro,
o valor da coluna, como variant. Para ser reconhecida como in-line a primeira palavra do texto deve ser
function.
O código abaixo verifica a validade de um código de
contêiner (ou container ou contentor)
seguindo o algoritmo de
identificação
(note a semelhança com Delphi):
dicField |
tableName | fieldName | customConstraint | constraintErrorMessage |
tbCLIENTE | CPF | functio _codigo... | |
function _codigo( const c: char ): double;
begin
result:= -1;
case c of
'A': result:= 10;
'B'.. 'K': result:= Ord( c ) - 54;
'L'.. 'U': result:= Ord( c ) - 53;
'V'.. 'Z': result:= Ord( c ) - 52;
'0'.. '9': result:= Ord( c ) - 48;
end;
end;
//---------------------------------------------------------------
function digitoVerificador( const cId: string): char;
var
i: integer;
d: double;
begin
result:= #0;
d:= 0;
for i:= 1 to 10 do d:= d + _codigo( cId[i] ) * power( 2, double(i-1) );
if ( d > 0 ) then begin
i:= round( d ) - ( trunc( d / 11 ) * 11 );
result:= chr(i+48);
end;
end;
//---------------------------------------------------------------
function _tipo( const cId: string; const iIni, iEnd: integer; const c1, c2: char ): boolean;
var i: integer;
begin
result:= true;
i:= iIni;
while ( i <= iEnd ) and result do begin
result:= ( c1 <= cId[i] ) and ( cId[i] <= c2 );
inc( i );
end;
end;
//---------------------------------------------------------------
//-- Valida Container -------------------------------------------
//---------------------------------------------------------------
function validaContainer( const cId: string ): boolean;
var cMsg: string;
begin
result:= false;
cMsg:= 'Código de Container inválido, favor informar de novo';
if ( length( cId ) < 11 ) then begin
cMsg:= cMsg + ' (faltam digitos).'
end else if ( length( cId ) > 11 ) then begin
cMsg:= cMsg + ' (sobram digitos).'
end else if not _tipo( cId, 5, 11, '0', '9' ) then begin
cMsg:= cMsg + ' (números esperados).'
end else if not _tipo( cId, 1, 4, 'A', 'Z' ) then begin
cMsg:= cMsg + ' (letras esperadas).'
end else if not ( digitoVerificador( cId ) = cId[11] ) then begin
cMsg:= cMsg + '.'
end else begin
result:= true;
end;
if not result then sf.shell.sayWarn( cMsg, 'Container' );
end;
//---------------------------------------------------------------
//-- Constraint -------------------------------------------------
//---------------------------------------------------------------
function constraint( const x: variant ): boolean;
begin
result:= validaContainer( x );
end;
No exemplo a seguir, não é feita exatamente uma validação, mas é aproveitado o contexto (antes da atualização da tabela) para
mudar o valor de uma coluna DATA_MODIF se a coluna STATUS
mudou de valor ou estiver sendo inserida:
function Constraint( x: variant ): boolean;
begin
if sf.ActiveDataSet.isAppending then begin
DATA_MODIF:= now;
end else if not ( x = sf.ActiveDataSet.oldValue['STATUS'] ) then begin
DATA_MODIF:= now;
end;
result:= true;
end;
Notação rápida
A notação rápida foi projetada para facilitar as validações simples. O script, composto
de uma só linha, deve resultar em uma expressão booleana. O valor da
coluna sendo validada está representado por x.
length( x ) > 4
Se a condição não é cumprida, Argow mostra uma mensagem com
o texto de dicField.ConstraintErrorMessage.
Internamente, Argow converte a linha informada, em um script in-line, com
as seguintes características:
{$I {configuração global SCRIPT_INCLUDE} }
function Constraint( x: variant ): boolean;
begin
result:= {dicField.CustomConstraint};
if not result then msg_warning( [ {dicField.ConstraintErrorMessage} ], {Nome da Tabela});
end;
Se dicField.ConstraintErrorMessage não for especificado, Argow
fornece a mensagem: 'A restrição para os valores válidos da coluna "%s" não é satisfeita com os dados informados.'.
Referências a outras colunas podem ser feitas pelos nomes, levando em consideração que podem ser Nulos.
Referência
Nesta notação o valor de dicField.CustomConstraint e uma referência à tabela dicScript,
com a seguinte notação:
scriptName[.functionName]
Onde scriptName é uma entrada em dicScript, e
functionName é a função, contida em dicScript.scriptBody,
que retorna um valor booleano e recebe um parâmetro,
o valor da coluna, como variant. Se functionName não for especificado,
será utilizado Constraint.
|