Ver la Versión Completa : Saber si una Variable tipo Tdatetime o Integer tiene Valor o esta vacia
webmasterplc
29-01-2017, 01:39:26
Buenas noches, tengo una duda y es como verificar si una variable tipo TdateTime o Integer esta vacia o nula para hacer clausualas condicionales
var
formAprobar: TformAprobar;
documento:Integer;
emision:TDateTime;
AgustinOrtu
29-01-2017, 03:11:33
De primeras, no se puede, porque los tipos primitivos no son "nullables". Alguna de las formas de solucionarlo es usar "valores bandera", es decir, definir un valor en tus reglas de negocio que se asuma como "invalido".
Por ej:
NullValues = record
public
const EmptyDateTime = 0; // por poner cualquier cosa
const EmptyInteger = -1234; // por poner cualquier cosa
class function IsEmptyDateTime(const Value: TDateTime): Boolean; static; inline;
class function IsEmptyInteger(const Value: Integer): Boolean; static; inline;
end;
La implementacion de los metodos es trivial (comparas el valor que recibes contra la constante)
Una solucion mejor es el uso de una biblioteca que soporte los llamados tipos "nullables"
Spring4D (spring4d.org/) ofrece una solucion muy buena, es OpenSource y es compatible con Delphi 2010 o superior. Los nullable se definen en la unidad Spring.pas
uses
System.SysUtils,
System.Variants,
Spring;
procedure Main;
var
Int: TNullableInteger;
begin
Int := TNullableInteger.Create(5); // creacion
Int := 5; // equivalente al anterior, la sobrecarga del operador implicito hace la magia
Writeln(Int.HasValue); // --> True
Int := TNullableInteger.Create(System.Variants.Null); // lo setea a null
Writeln(Int.HasValue); // --> False
try
Writeln(Int.Value); // --> exception
except
on E: EInvalidOperationException do
begin
Writeln('Nullable no tenia valor asignado');
end
else
raise;
end;
end;
El uso con cualquier tipo (gracias a los genericos y a TNullable<T> es posible) y la sobrecarga de operadores (sobre todo el implicito) lo hace muy limpio
En realidad, TNullable<T> es un record que se aprovecha de como estan implementados en Delphi para setear un Flag de "HasValue = True/False" dependiendo de como fue instanciada la variable
Por ej:
procedure UsarInt(const Value: Integer);
begin
WriteLn(Value.ToString);
end;
procedure Main;
var
Int: TNullableInteger;
begin
UsarInt(Int); // excepcion porque esto implica llamar al operador implicito y ejecutar un Int.Value
Int := 5;
UsarInt(Int); // ahora todo bien
end;
La unica "pega" es que no podes usar (directamente) los ayudantes como TStringHelper sobre una variable de tipo Nullable: por mas que tengas el operador implicito, te obliga a escribir ".Value"
var
Int: TNullableInteger;
begin
Int.ToString; // no compila
Int.Value.ToString; // todo bien
end;
Si no recuerdo mal en los proximos releases de Delphi estos "nullables" van a estar implementados de manera nativa y no hara falta usar bibliotecas externas
webmasterplc
29-01-2017, 04:55:33
uso delphi xe8 acabo de adquirir berlin 10
AgustinOrtu
29-01-2017, 06:49:56
uso delphi xe8 acabo de adquirir berlin 10
No entendi muy bien :D
Que yo sepa en Berlin no hay Nullables. Creo que esto es para la version que viene despues de Berlin
Por otra parte, en esas versiones de Delphi podes usar Spring4D como te comentaba
Por si alguno le interesa, esta es una lectura interesante sobre Nullable (https://community.embarcadero.com/blogs/entry/a-andquotnullableandquot-post-38869) en Delphi, por Allen Bauer. Spring hace algo similar, solo que mas sencillo, ya que en lugar de una interface como "sentinela", usa un string, que el compilador siempre inicializa a un valor conocido: EmptyStr, es decir, el string vacio
Edito:
Aca (https://community.embarcadero.com/article/news/16418-product-roadmap-august-2016) se menciona los nullables en Delphi nativo. La mala noticia: hay que esperar hasta Delphi 10.3, en el 2018. Apenas va 1 mes del año y ya hay que pensar en el proximo :(
vBulletin v3.6.8, Derechos ©2000-2024, Jelsoft Enterprises Ltd.