martes, 18 de junio de 2019

Número a texto con formato.

Pasar de número a string utilizando la función Format y el registro TFormatSettings. También se puede usar Format para cadenas de texto (strings), básicamente para alinearlas y/o recortarlas, no obstante su potencia radica en lo numérico, no solo enteros y decimales, también hexadecimales, exponenciales y hasta punteros. Ejemplos de todos ellos en: https://www.freepascal.org/docs-html/rtl/sysutils/format.html la cual recomiendo leer antes de continuar. Como también las referidas a TFormatSettings y DefaultFormatSettings.

Como lo indica su nombre, DefaultFormatSettings, es una variable global del tipo TFormatSettings que contiene los valores actuales de formato, si se altera, afectará a todo el proyecto, por ende debe usarse con algunos recaudos, como ser, por ejemplo, si necesito que en una función se utilice el separador decimal punto pero luego continuar utilizando la coma, entonces una opción es, antes de llamar a la función usar DefaultFormatSettings.DecimalSeparator:='.' e inmediatamente en la siguiente línea de código que sucede a la función DefaultFormatSettings.DecimalSeparator:=',' o, lo mismo pero dentro de la función.

Otra opción, y según las necesidades, es crear una variable del tipo TFormatSettings (que es del tipo record) y especificar en ella únicamente los formatos que vamos a utilizar.

Recordemos que Format devuelve un string así que puede usarse casi para cualquier cosa, pero, siempre hay un pero, a nivel IDE, más precisamente en el componente TMemo, no produce siempre los resultados deseados, el problema es con los espacios y el ancho del caracter, a no ser que exista alguna Font de tamaño fijo que desconozco.

En mi caso, necesitaba imprimir unas tablas (no tablas de bases de datos) y no tenía ganas de recurrir a LazReport, porque era algo muy simple, por eso mi primera opción fue TMemo. Pero por qué no aprovechar lo que ya está hecho, por ejemplo un editor de texto plano que cualquier sistema operativo posee.
Fue entonces que opté por TStringList que dispone de dos procedimientos elementales: LoadFromFile y SaveToFile. Finalmente utilizo OpenDocument y listo, de ahí en más se encarga el sistema operativo.

procedure TForm1.BTablaRetGcias2019Click(Sender: TObject);
var
  mes:Integer=0;
  ind:Integer=0;
  FS:TFormatSettings; //Creo la variable del tipo TFormatSettings
  sl:TStringList; //Creo la variable del tipo TStringList
begin
  sl:=TStringList.Create;  //Creo la instancia porque TStringList es una clase
  FS.CurrencyFormat:=1;  //FS es un type record y no necesita instanciasión
  FS.CurrencyDecimals:=2;
  FS.DecimalSeparator:=',';
  FS.ThousandSeparator:='.';
  FS.CurrencyString:='';
  sl.Add('Año 2019');
  sl.Add('');
  sl.Add('Mes Fijo Alíc.% Exedente');
  for mes:=1 to 12 do
  begin
    sl.Add('--------------------------------------');
    for ind:=1 to 9 do
      sl.Add(
      Format('%2.0d',[mes])+
      Format('%14.2m',[TablaGcias19[mes,ind].fijo],FS)+
      Format('%6.0m',[TablaGcias19[mes,ind].alicuota],FS)+
      Format('%16.2m',[TablaGcias19[mes,ind].exedente],FS));
      //%16 cantidad de caracteres .2 es 2 decimales y m es que el argumento es currency
  end;
  sl.SaveToFile('SL_Tabla_2019.txt');
  OpenDocument('SL_Tabla_2019.txt');
  sl.Free;
end;


Algunas aclaraciones:

FS.CurrencyFormat: en este caso no importa el valor, porque lo anulo con FS.CurrencyString:=''. Pero ya que estamos, lo valores para este campo (CurrencyFormat) pueden ser:
0 : $1
1 : 1$
2 : $ 1
3 : 1 $

En este caso TablaGcias19 es una matriz del registro TTablaGcias

TTablaGcias = record
  fijo:Currency;
  exedente:Currency;
  alicuota:Currency;
end;


Y con muy poco código se obtiene esto:



Al final se libera el TStringList y de la variable FS que usamos para FormatSettings nos olvidamos ya que es local a la función y del tipo record.

No hay comentarios:

Publicar un comentario