unit uStringsUtils;

interface

uses
  Classes;

const
  DISPLAY_EUROS2 = '#,0.00 €';
  DISPLAY_PORCENTAJE = '#,0.00%';  

procedure StringToStrings(Source:string; Delimiter:char; Target:TStrings);
function StringsToString(Source:TStrings; Delimiter:char):string;
function EsCadenaVacia(const S: AnsiString): Boolean; overload;
function EsCadenaVacia(const S: Variant): Boolean; overload;
function EsNumerico(Cadena: String) : Boolean;
function calcularLetraNIF(numeroDNI : integer): string;
function comprobarLetraNIF(nif: string): boolean;
function validarCIF(Cif: string) : boolean;
function CadLimpiaCar(NIF: String): String;


implementation

uses
  Variants, SysUtils;

{ Convierte una cadena con items separados con un delimitador en un TString }
procedure StringToStrings(Source:string; Delimiter:char; Target:TStrings);
var i: integer;
begin
  for i:=1 to length(Source) do
    if Source[ i ] = Delimiter then Source[ i ]:=#10;
  Target.Text:=Source;
end;

{ Convierte un TString en una cadena de items separados con un delimitador }
function StringsToString(Source:TStrings; Delimiter:char):string;
var i: integer;
begin
  Result:='';
  for i:=0 to Source.Count-1 do
    Result:=Result + Delimiter + Source[ i ];
  if Result<>'' then Delete(Result, 1, 1)
end;

function EsCadenaVacia(const S: AnsiString): Boolean;
begin
  Result := (Length(Trim(S)) = 0)
end;

function EsCadenaVacia(const S: Variant): Boolean; overload;
begin
  Result := True;
  if VarIsNull(S) then
    Exit;
  Result := EsCadenaVacia(VarToStr(S));
end;

function EsNumerico(Cadena: String) : Boolean;
var
  Codigo: Integer;
  Valor: Double;
begin
  Val(Cadena, Valor, Codigo);
  Result := (Codigo = 0)
end;

//Obtiene la letra del DNI NIF de un número
function calcularLetraNIF(numeroDNI : integer): string;
begin
  Result := copy('TRWAGMYFPDXBNJZSQVHLCKET', 1 + numeroDNI mod 23, 1);
end;
 
//Comprueba si un NIF DNI es correcto (con letra incluida y extranjero)
function comprobarLetraNIF (nif: string): boolean;
var
  numeroDNI : Integer;
begin
  Result := false;
  if Length(nif) = 9 then
  begin
    // DNI normal
    if TryStrToInt(Copy(nif, 1, Length(nif) - 1), numeroDNI) then
      Result := UpperCase(Copy(nif, Length(nif), 1)) = calcularLetraNIF(numeroDNI);
    // DNI Extranjero
    if UpperCase(Copy(nif, 1, 1)) = 'X' then
      if TryStrToInt(Copy(nif, 2, Length(nif) - 2), numeroDNI) then
        Result := Uppercase(Copy(nif, Length(nif), 1)) = calcularLetraNIF(numeroDNI);
  end;
end;

//Comprueba si un CIF es correcto (se le pasa el CIF completo, incluida la letra)
function validarCIF (Cif : string) : boolean;
var
  Suma, Control : integer;
  n : byte;
begin
  Result:=False;
  Cif:=UpperCase(Cif);
  {El cif debe ser de 9 cifras}
  if Length(Cif)=9 then
  begin
    Suma:= StrToInt(Cif[3])+
    StrToInt(Cif[5])+
    StrToInt(Cif[7]);
    for n := 1 to 4 do
    begin
      Suma:=Suma+ ( (2*StrToInt(Cif[2*n])) mod 10 )+
      ( (2*StrToInt(Cif[2*n])) div 10 );
    end;
    Control := 10-(Suma mod 10);
    if Pos(Cif[1],'XP') <> 0 then
      {Control tipo letra}
      Result:= ( Cif[9] = Chr(64+ Control))
    else
    begin
      {Control tipo número}
      if Control =10 then
        Control := 0;
      Result:= ( StrToInt(Cif[9]) = Control);
    end;
  end;
end;

function CadLimpiaCar(NIF: String): String;
 begin
 Result:= NIF;
  while (pos(' ',NIF)>0) do
    delete(NIF,pos(' ',NIF),1);
  while (pos('-',NIF)>0) do
    delete(NIF,pos('-',NIF),1);
  while (pos('/',NIF)>0) do
    delete(NIF,pos('/',NIF),1);
  Result:=UpperCase(NIF);
end;

end.
