Mostrando entradas con la etiqueta freepascal. Mostrar todas las entradas
Mostrando entradas con la etiqueta freepascal. Mostrar todas las entradas

lunes, septiembre 02, 2013

FreePascal: Fecha y Hora



Hola,
Continuemos un poco más con FreePascal. Hoy tocan las funciones de Fecha y Hora.
Hay diferentes funciones para hacer cosas similares. Yo recomendaría utilizar las funciones incluidas en la unidad sysutils.

La documentación oficial:



Uso del TIME para obtener la hora actual:




Uso del DATE para obtener la fecha:






CONVERSIÓN DE TIPOS:

Normalmente leemos la fecha de un fichero de texto o base de datos, lo que nos obligará normalmente a realizar la conversión entre tipos tanto al escribirla como al leerla.



Conversión de string en fecha:

Conversión de fecha a string:


Ejemplo de uso: En mi ejemplo he creado una variable Regla de tipo Record. Voy a leer de un fichero de texto una fecha:

Leo 10 caracteres a partir del carácter número 71:

regla.fecha:= Copy(linea,71,10);

Elimino los espacios vacíos:
 regla.fecha:= StringReplace(regla.fecha,' ','',[rfReplaceAll]);

Si no está todo vacío (o sea, que hay una fecha), intento la conversión a TIPO FECHA:
if regla.fecha <> '' then
      TryStrToDateTime(regla.fecha, regla.tdatetimeFecha);


OPERACIÓN DE COMPARACIÓN CON FECHAS:

Las fechas se pueden comparar entre sí.

if fecha1 < fecha2 then


CONVERSIÓN DE FECHA A STRING CON FORMATO:

Writeln(FormatDateTime('DD MM YYYY',fecha1);

Saludos.

jueves, agosto 29, 2013

Manipulación de Excel desde FreePascal-Lazarus



Primer post desde el 12 de Julio. Creo que como paréntesis ya está bien. Ya de vuelta en el trabajo he tenido que programar una utilidad para revisar contenido borrable de las unidades de red. He elegido FreePascal como lenguaje y Lazarus como IDE de desarrollo.

¿Los motivos?
  1. Creo que lo iba a hacer más rápido en Pascal que en C++.
  2. En Pascal tengo todas las funciones y procedimientos necesarios desde el minuto 0. No voy a tener que buscar librerías por ahí. (al menos no sin contar con la ayuda de la comunidad de FreePascal-Lazarus).
  3. He podido comprobar que la documentación de FreePascal-Lazarus es muy completa. Esto es lo que más miedo me daba, junto a la posibilidad de que hubiera funciones, procedimientos, librerías inacabados, o con bug-s (cosa que no ha ocurrido).
Vamos al meollo: Queremos que nuestro programa Pascal sea capaz de generar un fichero Excel (mi versión es la 2010 y ha funcionado bien), y de guardar datos en él. La versión de Lazarus que me he bajado es la 1.0.12.

PRIMERO.-Necesitamos descargar el paquete fpspreadsheet_pkg
En SourceForge.net tenemos la última versión: http://sourceforge.net/projects/lazarus-ccr/files/FPSpreadsheet/

SEGUNDO.-Se abre el paquete dentro del IDE Lazarus. Para ello tenemos que ir al menú PAQUETE, opción "ABRIR ARCHIVO DE PAQUETE".


TERCERO.-Le damos al botón COMPILAR y ya podemos darle a USAR, AGREGAR AL PROYECTO. De esta forma ya podemos utilizar los procedimientos y funciones para crear o acceder a un fichero Excel.

CUARTO.-EJEMPLO DE CREACIÓN DE UN EXCEL CON ALGUNOS VALORES.

Declaramos estas variables:
  • LibroExcel: TsWorkbook; 
  • HojaExcel: TsWorksheet;
Inicializamos las mismas: 
  • LibroExcel:= TsWorkbook.Create; 
  • HojaExcel:= LibroExcel.AddWorksheet('Resultado');
Damos valores a celdas:
Según sea el tipo de dato hay que usar un procedimiento diferentes: WriteUTF8Text, WriteNumber, etc. El primer parámetro que pasamos es el número de fila Excel, el segundo es el número de columna, y el tercero es el dato que escribimos.
  • HojaExcel.WriteUTF8Text(fila, 0, directorio);
  • HojaExcel.WriteNumber(fila, 1, numeroDeFicheros);
          LibroExcel.WriteToFile('result-unidad-' + unidad + format('%d-%d-%d ',[dd,mm,yy])+ STR_EXCEL_EXTENSION, true);


Escribimos todo en un fichero Excel. El primer parámetro es el nombre del fichero y el segundo es TRUE o FALSE dependiendo si queremos sobreescribir el fichero en caso de que exista (true), o no (false).

  • LibroExcel.WriteToFile('resultado.xls', true);
Saludos.

P.D.: Documentación del uso de los procedimientos y funciones del paquete este enlace de freepascal.org: http://wiki.freepascal.org/FPSpreadsheet

martes, septiembre 11, 2012

Freepascal y Lazarus: existe el fichero?


Función FileExists

FileExists nos indicar si un fichero existe o no. Pero OJO, busca en el mismo directorio que el ejecutable del programa.

He creado un formulario en Lazarus. Le he agregado un botón, y este es el código que se ejecuta cuando hacemos clic en él:


procedure TfrmPrincipal.btnIniciarClick(Sender: TObject);
type Tprogramas = Array[0..2] of string;
var
   prog : Tprogramas;
   s : string;
   fichero : Text;
begin
    prog[0]:='toad.exe';
    prog[1]:='gpg.exe';
    prog[2]:='r.exe';
    system.Assign(fichero,'programas.txt');
    Rewrite(fichero);
    for s in prog do begin
        if FileExists(s) then begin
           Writeln(fichero, s);
        end
    end;
    system.Close(fichero);
end;

¿Por qué he puesto system.Assign en lugar de invocar Assign a secas?

Assign asigna un nombre a un fichero.

Si ponemos Assign(fichero,'programa.txt') nos saldrá el siguiente error de compilación:
ERROR: Wrong number of parameters specified for call to "Assign".

El problema es que el compilador interpreta que queremos utilizar el método Assign de la clase del formulario (TfrmPrincipal en mi caso). Se soluciona indicando que llamamos al método Assign de la clase System: System.Assign.

Lo mismo ocurre con System.Close.

Saludos.

martes, agosto 28, 2012

Abrir formularios en Lazarus-FreePascal



Como en un lenguaje de programación moderno (con extensión para orientación a objetos), en Lazarus - FreePascal tenemos dos formas de abrir formularios:



  1. De forma estática. Diseñas los formularios. Luego, al iniciar la aplicación se crean todos los formularios, aunque están ocultos. Cuando quieras lo haces visible en tiempo de ejecución.
  2. De forma dinámica. Cuando abres una aplicación como el Microsoft Word, tú no sabes cuantos formularios "de documento" vas a tener que abrir. El usuario puede abrir 1 documento o 20. Cada vez que haga clic en "Nuevo documento" hay que abrir un formulario.
1.-FORMA ESTÁTICA DE CREAR FORMULARIOS.

Diseñamos los formularios que necesitemos con Lazarus. Para crear un nuevo formulario vamos al MENÚ ARCHIVO, Opción NUEVO FORMULARIO.

Hay que tener en cuenta que cada formulario gráfico que hemos creado está descrito en una unidad (UNIT). Para verlo seleccionamos el formulario y vamos al MENÚ VER, Opción "EDITOR DE CÓDIGO FUENTE". El nombre de la unidad se encuentra en la primera línea del código fuente del formulario. Por ejemplo:

unit Unit1;

Si desde este form1 que está definido en Unit1, queremos llamar al form2, tenemos que incluir la definición de form2 dentró de la sección uses:

uses: 
xxxxx, xxxxxx, xxxxxx, xxxxxx, unit2;

Ahora ya podemos "llamar" al form2 desde form1. Realmente la invocación sólo consiste en hacer visible el formulario. Eso es así porque al arrancar se crean todos los formularios que hemos diseñado.

form2.show;

2.-FORMA DINÁMICA DE CREAR FORMULARIOS.

Tenemos que pensar que cada formulario es un objeto. Nuestro programa puede necesitar abrir varios objetos de ese tipo (formularios de entrada, informes, etc.), aunque cada uno tenga datos diferentes.

Vamos al MENÚ PROYECTO, Opción OPCIONES DEL PROYECTO, y elegimos FORMULARIO. Saldrá esta ventana:


Pasamos los formularios que haya que abrir dinámicamente, de la columna "CREAR FORMULARIOS AUTOMÁTICAMENTE" a la de "FORMULARIOS DISPONIBLES".

En los eventos OnClose de los formularios tenemos que añandir lo siguiente para que libere la memoria:
CloseAction:= caFree;

Lo único que hay que hacer ahora para abrir el form2 desde el form1 es instanciar el objeto form2:

procedure Tform1.Button1Click(Sender: TObject);
var
   frmDocumento: Tform2;
begin
   frmDocumento:= Tform2.Create(Application);
   frmDocumento.Show;
end;  

Saludos.

lunes, agosto 27, 2012

Lazarus (freepascal), acceso a Oracle, segunda parte




El otro día explicaba cómo acceder a la base de datos desde FreePascal, aunque realmente sólo hacía una SELECT.
Hoy toca una update que es muy parecido.






Es muy similar a la SELECT del otro día. Hay estas diferencias:

  • En la SELECT se hace SQLQuery1.Open.
  • En la UPDATE SQLQuery1.ExecSQL.
  • En la UPDATE hay que hacer COMMIT de la transacción con SQLTransaction1.Commit.
Luego hay que tener en cuenta unos detalles para que no se generen errores:

ORACLE espera que indiquemos los valores VARCHAR2 (equivalentes al tipo String) entre comillas simples. El problema es que si ponemos comillas simples dentro de SQLquery1.SQL.Text, se corta el string y nos salta un error que indica que el String está mal construido.

La solución es incluir dos comillas simples. FreePascal entiende que la primera comilla es un caracter de escape y en el String que se forma tiene que haber una comilla simple.


El código fuente para el copia-pega:



procedure TfrmPrincipal.Button2Click(Sender: TObject);
var
  OracleConnection1: TOracleConnection;
  SQLquery1: TSQLQuery;
  SQLtransaction1: TSQLTransaction;
begin
  OracleConnection1 := TOracleConnection.Create(nil);
  SQLquery1 := TSQLQuery.Create(nil);
  SQLtransaction1 := TSQLTransaction.Create(nil);
  try
    try
      with OracleConnection1 do begin
           DatabaseName:='entradaTNS-ORACLE';
           UserName:='usuario';
           Password:='password';
           Transaction := SQLtransaction1;
      end;
      OracleConnection1.Connected:=true;
      SQLtransaction1.Active:=true;
      SQLquery1.DataBase := OracleConnection1;
      SQLquery1.SQL.Text := 'update TABLA set CAMPO=''C'' where CAMPO2=''D''';
      SQLQuery1.ExecSQL;
      SQLTransaction1.Commit;
      ShowMessage ('Campo actualizado');
      SQLquery1.Close;
      OracleConnection1.Close;
    finally
      SQLtransaction1.Free;
      SQLquery1.Free;
      OracleConnection1.Free;
    end;
  except
    on E: Exception do
      writeln(E.message);
  end;
end;

Saludos,

viernes, agosto 24, 2012

Formulario MDI en Lazarus - FreePascal

Quiero iniciar una aplicación en Lazarus. Lo primero es el formulario MDI principal (Multiple Document Interface). Si abrimos el Word por ejemplo, hay un formulario principal MDI que contiene los menús, las barras de herramientas, etc. Y luego podemos abrir múltiples documentos Word, cada uno de ellos en formularios "hijos" que se pueden minimizar, maximizar, hacer un mosaico, pero dentro del formulario MDI principal.

Como el otro día, reina la confusión. En este foro de freePascal de Enero de 2010, una persona pregunta por los formularios MDI y por las respuestas, todo parece indicar que no existe la implementación.

En el Club Delphi una persona recomienda utilizar la propiedad FormStyle. Dice que pongamos el formulario principal como fsnormal y los formularios hijos como fsStayOnTop.

En los Wiki de FreePascal y de Lazarus, indican que no hay formularios MDI, pero que tenemos algo similar que denominan MultiDoc (MultiDoc en FreePascal y MultiDoc en Lazarus). Sin embargo, es un desarrollo de un tercero, y los enlaces a la descarga de la última versión (0.3.1) están rotos.

Llegados a este punto desisto de los formularios MDI. Ya me he hecho a la idea que habrá que usar el truco del FormStyle. Voy a la propiedad FormSyle de mi formulario principal y SORPRESA!!! LA PROPIEDAD ADMITE LOS SIGUIENTES VALORES:


  1. fsNormal
  2. fsSplash
  3. fsStayOnTop
  4. fsSystemStayOnTop
  5. fsMDIForm
  6. fsMDIChild
Bueno, pues salvo nuevas sorpresas parece que ya hay formularios MDI en freePascal/Lazarus.

Saludos.

jueves, agosto 23, 2012

Lazarus (freepascal), acceso a Oracle

 ACCESO A ORACLE DESDE LAZARUS (FREE PASCAL):

Desarrollar en Lazarus tiene un grave problema: Hoy en día se utiliza Google como herramienta de documentación para el desarrollo de aplicaciones. En el caso de Lazarus no hay más remedio ya que no hay ninguna ayuda integrada en el IDE. Sin embargo en Internet no hay muchos ejemplos de código freePascal cuando toca hacer algo en el entorno de trabajo (conexión a Oracle por ejemplo).

Digo esto en comparación con otros lenguajes o plataformas como C# o VB.NET por ejemplo. En estos casos el problema suele ser las diferencias que hay entre los diferentes framework, pero ese es otro asunto.

 1.-Forma gráfica: añadir control TORACLECONNECTION de la pestaña SQLdb de la barra de herramientas.

El problema es que no hay una ayuda clara para saber lo que hay que poner en los campos principales. Esto es lo que yo he necesitado:
  1. En DatabaseName ponemos la entrada TNS del fichero TNSNAMES.ORA del cliente Oracle.
  2. En UserName ponemos el usuario Oracle.
  3. En Password la password de ese usuario Oracle.
y nada más. En cuanto pongamos la propiedad CONNECTED a TRUE veremos si conecta bien o no.

2.-Forma no gráfica de hacer la conexión y una ejecución de una instrucción SQL.

NOTA IMPORTANTE: como antes he metido en control gráfico TORACLECONNECTION, este objeto se ha creado en la carga del formulario. Si no agregamos el control de forma gráfica, tendremos que declara la variable en la zona de VAR, y crearla después del BEGIN:

var
OracleConnection1: TOracleConnection;
...
begin
OracleConnection1 := TOracleConnection.Create(nil);
...



El código fuente para copia-pega:

procedure TForm1.Button1Click(Sender: TObject);
var
  SQLquery1: TSQLQuery;
  SQLtransaction1: TSQLTransaction;
begin
  SQLquery1 := TSQLQuery.Create(nil);
  SQLtransaction1 := TSQLTransaction.Create(nil);
  try
    try
      with OracleConnection1 do begin
           DatabaseName:='instancia.host.es';
           UserName:='xxxxxxx';
           Password:='xxxxxxx';
           Transaction := SQLtransaction1;
      end;
      OracleConnection1.Connected:=true;
      SQLtransaction1.Active:=true;
      SQLquery1.DataBase := OracleConnection1;
      SQLquery1.SQL.Text := 'select * from tabla1';
      SQLquery1.Open;
      SQLquery1.Last;
      ShowMessage (intToStr(SQLquery1.RecordCount));
      SQLquery1.First;
      while not SQLquery1.EOF do
      begin
        ShowMessage (SQLquery1.FieldByName('campo1').AsString);
        SQLquery1.Next;
      end;
    finally
      SQLtransaction1.Free;
      SQLquery1.Free;
      OracleConnection1.Free;
    end;
  except
    on E: Exception do
      writeln(E.message);
  end;
end;

Más información, aunque más orientada a la base de datos Firebird en el wiki de FreePascal, tema: SQLdb Tutorial.

Saludos.