Agregando reporteador a Delphi 10.2 Starter

Hola amigos,

Como hemos visto en los artículos anteriores, la Edición Delphi 10.2 Starter no cuenta con algunos componentes importantes para el desarrollo de aplicaciones y una de estas limitaciones es que no dispone de la posibilidad de generar reportes, por tal razón, comencé a investigar si existía algún componente que nos permitiera obtener reportes en nuestras aplicaciones y que además se pudiera instalar en ésta Edición de Delphi 10.2 Starter.

Intenté instalar algunos reporteadores conocidos sin éxito ya que éstos no tenían compatibilidad con Delphi 10.2 Starter, finalmente encontré una biblioteca llamada Virtual Print Engine (VPE) en su edición Community la cual instalé sin problemas ya que no tiene dependencia con componentes de Delphi y además sigue la misma filosofía ya que ésta biblioteca tiene el mismo concepto de Delphi Starter que es el principo de equidad el cual menciona que si utilizas la biblioteca para generar ganancias, les gustaría que se comprara la versión de pago lo cual me parece por demás aceptable.

La edición Community de VPE al ser gratuita también tiene sus limitaciones pero después de instalarlo y hacer algunas pruebas de concepto puedo asegurarles que es mas que suficiente para crear cualquier tipo de documento y exportarlo a PDF.

Para éste artículo requerimos de descargar el instalador de Report Engine and PDF Library, la versión que encontré disponible para éste tutorial es para Delphi XE2, sin embargo, no tuve problemas para instalarlo y utilizarlo en Delphi 10.2 Starter.

Al terminar la descarga procederemos a instalar la versión de 32 bits, recuerden que Delphi Starter solo tiene soporte para la arquitectura de 32bits y no para arquitectura de 64bits.

Ejecutamos el programa vpec32.exe el cual instalará el motor de impresión en nuestra maquina.

Agregar el componente a Delphi es muy fácil, solo cargamos el proyecto VpevclXe2.dproj en nuestro IDE lo compilamos y finalmente lo instalamos. El componente se instalará en el grupo System con el nombre TVPEngine como pueden observar en la siguiente imagen.

Nota 1: Antes de compilar deberá agregar el Path del componente en las opciones de Delphi en Tools –> Options — Delphi Options –> Library  –> Library Path como se observa en la siguiente imagen.

Nota 2: Si al compilar les genera el siguiente error:

[MakeDir Error] Unable to create directory «.\Win32\Debug\». Access to the path ‘.\Win32\Debug\’ is denied.
Failed

Deberán ejecutar Delphi con permisos de Administrador.

Ya estamos listos para comenzar a experimentar con éste nuevo componente, para ello vamos a abrir el proyecto que hemos estado desarrollando en ésta serie y vamos a hacer algunos cambios a la interfáz gráfica que me parecen adecuados.

Vamos a eliminar los componentes TDBGrid y TDataSurce de nuestra forma ya que no serán necesarios y agregamos un TButton y el nuevo componente TVPEngine.

Usted decida como quiere ver su interfáz gráfica, en mi caso se verá de la siguiente forma:

Antes de continuar les diré que el concepto del Virtual Printer Engine hace que no solo sea un simple reporteador sino un motor de informes para crear dinámicamente cualquier tipo de documento ya sea simple o complejo. La disposición de objetos me recordó viejos tiempos donde todo lo hacíamos a mano (me ha traido gratos recuerdos), sin embargo, a pesar de que en apariencia no se vea «tan profesional» nos proporciona el control total de como queremos mostrar la información .

El proceso para generar un informe es muy simple,

  • Se abre el TPVEngine
  • Se colocan los objetos (texto, imagen, lineas, etc) en las coordenadas deseadas,
  • Se muestra y se imprime o se genera un archivo PDF
  • Se cierra elTPVEngine.

Nota importante: En la edición Community la cual es gratuita, no se tiene la posibilidad de imprimir los documentos desde código, primero se tiene que visualizar en pantalla y después se podrá mandar a imprimir desde su visor, las ediciones de pago si que tienen mayores caracterìsticas.

Ya estamos listos para escribir código. Nuestra ventana tiene dos botones nuevos, uno para generar el documento en pantalla (Vista Previa) y el otro para exportar la información en un archivo PDF (Exporta a PDF).

Como ya les comenté el proceso es muy sencillo y lo vamos a hacer por separado para cada uno de los botónes con el objeto de que se tenga más comprensión del mismo.

Generamos la consulta de los tipos de cambio en un rango de fechas presionando el botón Vista Previa:

Se ejecuta el siguiente proceso:

  • Abrimos la consulta pasando el rango de fechas donde deseamos obtener.
  • Si se encuentra información, se genera el reporte.
    • Se genera el encabezado
    • Se genera el detalle de la información
  • Se muestra la Vista Previa del reporte
  ZQuery1.Close;
  ZQuery1.ParamByName('ini').asString := FormatDateTime('yyyy-mm-dd',dtpInicial.Date);
  ZQuery1.ParamByName('fin').AsString := FormatDateTime('yyyy-mm-dd',dtpFinal.Date);
  ZQuery1.Open;

  if not ZQuery1.IsEmpty then
  begin
    generaReporte;
    Report.Preview;
  end;

  ZQuery1.Close;
end;

En el procedimiento generaReporte se encuentra el código para la impresión de la información enmcabezado y detalle de la información.

procedure TForm1.GroupHeader(Fecha: String);
var
   y: double;
begin
  Report.TextAlignment := ALIGN_LEFT;
  y := Report.Print(1.5, Report.nBottom + 0.2, Format('[N S 14 C Blue]%s', [Fecha]));
  y := y + 0.1;
  Report.Print(1.5, y, '[S 10 C Purple]Clave');
  Report.Write(3.5, y, 6, VFREE, '[R]Tipo de Cambio');
  Report.Write(6.5, y, 19.5, VFREE, '[L]Descripción');
end;

procedure TForm1.DetailLine(color: TColor; Clave: String; TC:Real; Descrip: String);
var
  y: double;
begin
  y := Report.nBottom;
  Report.BkgMode := VBKG_SOLID;
  Report.BkgColor := color;
  Report.PenColor := color;
  Report.Box(1.5, y, 19.5, LineHeight+0.3);
  Report.BkgMode := VBKG_TRANSPARENT;

  Report.WriteBox(1.5, y, -4, LineHeight+0.3, Format('[S 7 C Black L]%s', [Clave]));
  Report.TextAlignment := ALIGN_RIGHT;
  Report.WriteBox(3.5, y, 6, LineHeight+0.3, Format('%4.5n', [TC]));
  Report.TextAlignment := ALIGN_LEFT;
  Report.WriteBox(6.5, y, 19.5, LineHeight+0.3, Format('%s', [Descrip]));
end;

procedure TForm1.generaReporte;
var
  I: integer;
  y: double;
  color: TColor;
  FechaCorte: TDateTime;
begin
  if Report.IsOpen then Report.CloseDoc;
  Report.OpenDoc;
  Report.RenderPrintBox(0, 0, '[S 14 C Black]x');
  LineHeight := -Report.nRenderHeight;
  Report.AutoBreakMode := AUTO_BREAK_NO_LIMITS;
  Report.SetPen(0.05, PS_SOLID, COLOR_BLACK);
  Report.Picture(1.5, 1.0, 8.5, 3.0, 'Imagenes\DenM.bmp');
  Report.WriteBox(9.5, 2.0, 19.5, 3, '[N S 9 CE I C Black BC Gray TO]Tipos de Cambio del ' +
                   FormatDateTime('dd "de" mmmm "de" yyyy',ZQuery1.ParamByName('INI').AsDate) + ' al ' +
                   FormatDateTime('dd "de" mmmm "de" yyyy',ZQuery1.ParamByName('FIN').AsDate) );
  y := Report.nBottom + 1;
  Report.Line(1.5, y, 19.5, y);
  Report.nBottom := y + 0.1;
  GroupHeader(FormatDateTime('d "de" mmmm "de" yyyy', ZQuery1.FieldByName('FECHA').AsDateTime));
  FechaCorte := ZQuery1.FieldByName('FECHA').AsDateTime;

  for I := 0 to ZQuery1.RecordCount-1 do
  begin
    if FechaCorte <> ZQuery1.FieldByName('FECHA').AsDateTime then
    begin
      GroupHeader(FormatDateTime('d "de" mmmm "de" yyyy', ZQuery1.FieldByName('FECHA').AsDateTime));
      FechaCorte := ZQuery1.FieldByName('FECHA').AsDateTime;
    end;
    if I mod 2 = 0 then
       color := COLOR_GRAY
    else
       color := COLOR_LTGRAY;
    DetailLine(color, ZQuery1.FieldByName('Clave').AsString,
	                  ZQuery1.FieldByName('TipCamb').AsFloat,
					  ZQuery1.FieldByName('Descripcion').AsString);
    ZQuery1.Next;
  end;

  Report.PageBreak;
  Report.SetFont('Arial', 10);
  Report.BkgMode := VBKG_SOLID;
  Report.BkgColor := clRed;
end;

Las funciones que se utilizan cuentan con toda la información necesaria para «pintar» la información, a continuación estudiaremos algunas.

Report.RenderPrintBox(0, 0, ‘[S 14 C Black]x’);

Se genera el espacio de trabajo desde el punto [0,0] , (S)tamaño de letra 14 y0(C)olor Negro.

Report.SetPen(0.05, PS_SOLID, COLOR_BLACK);

Asignamos el estilo de la pluma con espesor de 0.5, (PS)estilo sólido y (C)olor Negro.

Report.Picture(1.5, 1.0, 8.5, 3.0, ‘Imagenes\DenM.bmp’);

Con éste método se inserta la imagen DenM.bmp en la posición [1.5,1.0] [8.5,3.0].

Report.WriteBox(9.5, 2.0, 19.5, 3, ‘[N S 9 CE I C Black BC Gray TO]TEXTO’);

Se imprime un texto libre a partir de las cordenadas [9.5,2.0] [19.5,3.0] pero además se le indica las propiedades con las que será mostrado, (N) le indica que no guarde ésta configuración para los demás textos, (S) tamaño de letra 9, (CE)ntrado, fuente (I)talica, (C)olor Negro y (BC)Fondo Gris (TO)Sólido

Al dar clic al botón de Vista Previa el programa nos mostrará el reporte como se ve en la siguiente imagen:

Una vez que tenemos la Vista Previa podremos imprimir el documento y es que la edición Community de VPE no permite enviar a impresión desde código y solo puede hacerse desde la Vista Previa, eso y mucho mas se podrá hacer si se adquiere una de las versiones de pago.

Ahora vamos a crear un archivo PDF con el código asignado al botón Exporta a PDF.

En éste botón se ejecuta el siguiente proceso:

  • Abrimos la consulta pasando el rango de fechas donde deseamos obtener.
  • Si se encuentra información, se genera el reporte.
    • Se genera el encabezado
    • Se genera el detalle de la información
  • Se exporta la información a un archivo PDF
procedure TForm1.Button4Click(Sender: TObject);
begin
  ZQuery1.Close;
  ZQuery1.ParamByName('ini').asString := FormatDateTime('yyyy-mm-dd',dtpInicial.Date);
  ZQuery1.ParamByName('fin').AsString := FormatDateTime('yyyy-mm-dd',dtpFinal.Date);
  ZQuery1.Open;

  if not ZQuery1.IsEmpty then
  begin
    generaReporte;
    ExportDocumentNoAsk(Report, ExtractFilePath(Application.ExeName) + 'Report_' +
                                FormatDateTime('yyyymmdd_hhnnss', now) + '.pdf');
  end;

  ZQuery1.Close;
end;

Éste proceso creará el archivo PDF y posteriormente nos lo mostrará, ésto se genera en el procedimiento ExportDocumentNoAsk(). Éste procedimiento sustituye al Visor de reportes del botón anterior.

procedure TForm1.ExportDocumentNoAsk(Doc: TVPEngine; FileName: String);
begin
   if Doc.WriteDoc(FileName) then
   begin
     MessageDlg('Archivo PDF "' + FileName + '" creado satisfactoriamente.',
                 mtInformation, [mbOk], 0);
     ShellExecute(0, nil, PCHAR(Filename), nil, nil, SW_SHOWMAXIMIZED);
   end
   else begin
          MessageDlg('Error creating PDF file "' + FileName + '"!' + #10 +
                     'Possible reasons:' + #10 +
                     ' - the file is open in Acrobat Reader' + #10 +
                     ' - hard disk full' + #10 +
                     ' - no access rights to the folder' + #10 +
                     ' - out of memory' + #10 +
                     ' - export module missing', mtInformation, [mbOk], 0);
   end;
end;

Al terminar nos mostrará el archivo PDF creado como se ve en la imagen siguienre:

Hay muchas otras funciones, procedimientos que pueden estudiarse en el manual de control de referencia

Hasta aquí llegamos con la tercera entrega de la serie en la cual hemos abarcado solo tres características de uso común en cualquier aplicación (Consumo de webService, Acceso a Base de Datos y Generación de Reportes) y que la edición Starter de Delphi 10.2 no tiene disponibles.

Como siempre, espero que ésta información sea de su agrado pero sobre todo de utilidad. Por supuesto que el código presentado en todos mis artículos son hechos de la forma más básica posible con la intención de que sea fácil de entender por aquellos que están dando sus primeros pasos y nutrida por los grandes maestros que nos visitan.

Solo me resta decir que sigo investigando que mas se puede hacer, si alguien tiene alguna idea que quieran que se realice, con gusto estudiaremos si es posible desarrollarla con Delphi 10.2 Starter.

Hasta la próxima


Todo el código escrito aquí es de libre descarga y utilización solo te pido, si te parece correcto, que menciones su origen y claro cualquier mejora que le hagas publicala que se agradecerá enormemente.

Muchas gracias.

Acceso a base de datos SQLite desde Delphi Starter

Hola amigos,

En ésta entrada vamos a realizar la conexión con una base de datos SQLite utilizando Delphi Starter Edition, versión 10.2 Tokyo y como ya se habrán dado cuenta, ésta edición de Delphi no cuenta con los componentes necesarios para la conexión a bases de datos, sin embargo, si tenemos la posibilidad de instalar componentes de terceros para poder acceder a motores de base de datos y expandir las características de nuestra herramienta de desarrollo.

Los componentes que utilizaremos en éste tutorial son los componentes ZEOS que nos permitiran dar continuidad a ésta serie aprovechando las facilidades que nos ofrece Delphi Starter Edition.

Para realizar ésta entrada utilizaremos la aplicación que desarrollamos en el artículo anterior «Consumir un servicio web con Delphi 10.2 Starter y cURL« donde obtenemos información del tipo de cambio del día del peso mexicano contra monedas de otros países.

Una vez que obtenemos dicha información tendrémos la capacidad de almacenarla para efectos de mantener un histórico de «paridades» y poder consultar el valor de una moneda en un día determinado.

Para poder llevar a cabo éste tutorial necesitamos descargar el componente de acceso base de datos ZEOS el cual pueden descargar del siguiente enlace: ZeosLib versión 7.2.1 Release Candidate

El motor de base de datos que usarémos será SQLite donde crearemos dos tablas y una vista para utilizarlas en nuestra aplicación, dicha base de datos estará incluida en los archivos de descarga al final de éste tutorial, sin embargo, si deseas crearla tu mismo se entregarán los DDL para que las generes con el administrador SQLite de tu preferencia, si no conoces alguno puedes descargar SQLite Studio Database Manager que me parece un muy buen administrador.

Comenzaremos por instalar los componentes ZEOS versión 7.2.1 rc, el paquete que se usará para Delphi Starter es el contenido en el directorio DelphiXE10.

Carga el proyecto ZeosDbo.bpg en Delphi y compila todos los bpl’s en el siguiente orden:

• ZCore.bpl
• ZParseSql.bpl
• ZPlain.bpl
• ZDbc.bpl
• ZComponent.bpl

Para que puedan compilar los BPL’s es necesario agregar los siguientes directorios a la ruta de las librerias/bibliotecas que se localiza en el menu Tools -> Options -> Delphi Options -> Library -> Library Path.

C:\Compartidos\Starter\ZEOSDBO-7.2.1-rc\packages\DelphiXE10;
C:\Compartidos\Starter\ZEOSDBO-7.2.1-rc\src\component;
C:\Compartidos\Starter\ZEOSDBO-7.2.1-rc\src\dbc;
C:\Compartidos\Starter\ZEOSDBO-7.2.1-rc\src\parsesql;
C:\Compartidos\Starter\ZEOSDBO-7.2.1-rc\src\plain;
C:\Compartidos\Starter\ZEOSDBO-7.2.1-rc\src\Core

Una vez que compilamos correctamente el proyecto ZeosDbo aparecerá el grupo Zeos Access en la paleta de herramientas como se muestra en la siguiente imagen:

El siguiente paso es la creación de la base de datos SQLite que utilizaremos en ésta sección y como les comenté pueden usar la base de datos que está incluida en las descargas al final de éste tutorial o pueden crearla con el Lenguaje de Definición de Datos (DDL)  desde cualquier Administrador SQLite.

--
-- File generated with SQLiteStudio v3.1.1 on mar may 30 21:19:36 2017
--
-- Text encoding used: System
--
PRAGMA foreign_keys = off;
BEGIN TRANSACTION;

-- Table: TC_CATALOGO
DROP TABLE IF EXISTS TC_CATALOGO;

CREATE TABLE TC_CATALOGO (
    ID          INTEGER      NOT NULL
                             PRIMARY KEY AUTOINCREMENT,
    CLAVE       STRING (20)  NOT NULL,
    DESCRIPCION STRING (200) 
);


-- Table: TC_HISTORICO
DROP TABLE IF EXISTS TC_HISTORICO;

CREATE TABLE TC_HISTORICO (
    ID      INTEGER        NOT NULL,
    FECHA   DATE           NOT NULL,
    TIPCAMB DECIMAL (7, 4),
    PRIMARY KEY (
        ID,
        FECHA
    )
);


-- View: TC_LISTADO
DROP VIEW IF EXISTS TC_LISTADO;
CREATE VIEW TC_LISTADO AS
    SELECT CAT.CLAVE,
           HIST.FECHA,
           HIST.TIPCAMB,
           CAT.DESCRIPCION
      FROM TC_HISTORICO HIST
           INNER JOIN
           TC_CATALOGO CAT ON CAT.ID = HIST.ID;


COMMIT TRANSACTION;
PRAGMA foreign_keys = on;

Despues de crear las tablas vamos a inicializar el catálogo de monedas para que se tenga la información necesaria para enlazar la información que vamos a recibir del Servicio Web de Banxico.

INSERT INTO TC_CATALOGO (DESCRIPCION,CLAVE,ID)
VALUES	('Tipo de cambio pesos por dólar E.U.A. Fecha de liquidación.','DLL01',1),
		('Tipo de cambio Pesos por dólar E.U.A. Fecha de determinación (FIX)','DLL02',2),
		('Cotización de las divisas que conforman la canasta del DEG Respecto al peso mexicano Euro','EURO',3),
		('Cotización de la divisa Respecto al peso mexicano Dólar Canadiense','DLLCA',4),
		('Cotización de las divisas que conforman la canasta del DEG Respecto al peso mexicano Yen japonés','YEN',5),
		('Cotización de las divisas que conforman la canasta del DEG Respecto al peso mexicano Libra esterlina.','LIBRA',6);

En éste momento ya tenemos los componentes de acceso a base de datos y la base de datos listos, ahora comenzaremos a dar forma a nuestro proyecto.

Abra el proyecto wsStarter.dproj que se creo en el tutorial anterior (Si no lo has creado, puedes descargarlo siguiendo éste enlace).

Agregue los siguientes componentes a la forma principal.

• TButton
• TDataSource;
• TDateTimePicker
• TDBGrid
• TZConnection;
• TZQuery;

Después de organizar a tu gusto los componentes que se agregaron ya tendremos nuestra forma similar a la siguiente imagen:

Configuramos la conexión en el componente ZConnection1  asignando la ruta de la base de datos y el protocolo del motor de la base de datos que vamos a usar, en éste caso sqlite-3.

Ésta configuración de la base de datos está en tiempo de diseño pero lo recomendable es hacerlo en tiempo de ejecución ya que la base de datos puede ser colocada en cualquier lugar ya sea en la misma máquina o en otra máquina de la red. Para configurarla en tiempo de ejecución pueden hacer lo siguiente:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ZConnection1.Database := ExtractFilePath(Application.ExeName) + 'base\TipoCambio.sqlite3';
end;

(También puede ser a través de la lectura de un archivo INI, XML o el mismo registro de windows, como mejor les parezca.)

Ahora vamos a decidir que vamos a hacer con la información que se reciba del Servicio Web de Banxico. Yo he decidido mostrar la información seleccionando la fecha deseada en el componente TDateTimePicker1 y mostrar los tipos de cambio de ese día (si ya se ha descargado), para ello utilizaremos la vista que previamente se creo en la base de datos llamada TC_LISTADO ejecutandola desde el componente ZQuery1 el cual ya debe estar enlazado al DataSource y a su vez el DataSource enlazado al DBGrid.

La consulta es muy simple y  es la siguiente:

select * from TC_LISTADO list
where list.FECHA = :fecha

Ya estamos listos para modifcar el proyecto y acceder a una base de datos. Comenzamos agregando las siguientes unidades a la sección USES de nuestra unidad uXMLclass.pas.

• ZDataset,
• ZAbstractConnection;

Posteriormente agregamos una variable y una propiedad a la clase TRequestResponse para la conexión con la base de datos.

• ZQryTC: TZQuery;

• Fconexion: TZAbstractConnection;

• property conexion: TZAbstractConnection read Fconexion write Fconexion;

Finalmente harémos una modificación al procedimiento TRequestResponse.BuscaTC() para leer el XML de Respuesta obteniendo la Moneda, la Fecha y el Tipo de Cambio y agregando ésta información a nuestra tabla de históricos para consultas posteriores.

function TRequestResponse.buscaTC(xml: IXMLDocument): TStrings;
var
  I: integer;
  nodoData: IXMLNode;
  Linea: string;
  valor: variant;
  moneda: integer;
begin
  Result := TStringList.Create;
  Result.Text := '';
  nodoData := xml.ChildNodes[1].ChildNodes[1];
  if nodoData <> nil then
  begin
    ZQryTC := TZQuery.Create(nil);
    ZQryTC.Connection := Fconexion;
    ZQryTC.SQL.Text := 'INSERT INTO TC_HISTORICO(ID, FECHA, TIPCAMB) ' + #13 +
                       'VALUES(:id, :periodo, :tc) ';
    for I := 0 to nodoData.ChildNodes.Count-1 do
    begin
      if nodoData.ChildNodes[I].NodeName = 'bm:Series' then
      begin
         if pos('FIX',nodoData.ChildNodes[I].Attributes['TITULO']) > 0 then
            ZQryTC.ParamByName('ID').Value := 2
         else
         if pos('Euro',nodoData.ChildNodes[I].Attributes['TITULO']) > 0 then
            ZQryTC.ParamByName('ID').Value := 3
         else
         if pos('Canadiense',nodoData.ChildNodes[I].Attributes['TITULO']) > 0 then
            ZQryTC.ParamByName('ID').Value := 4
         else
         if pos('Yen',nodoData.ChildNodes[I].Attributes['TITULO']) > 0 then
            ZQryTC.ParamByName('ID').Value := 5
         else
         if pos('Libra',nodoData.ChildNodes[I].Attributes['TITULO']) > 0 then
            ZQryTC.ParamByName('ID').Value := 6
         else
            ZQryTC.ParamByName('ID').Value := 1;

         moneda := ZQryTC.ParamByName('ID').Value;

         ZQryTC.ParamByName('PERIODO').AsString :=
                 nodoData.ChildNodes[I].ChildNodes[0].Attributes['TIME_PERIOD'];

         valor := NULL;
         if nodoData.ChildNodes[I].ChildNodes[0].Attributes['OBS_VALUE'] <> '' then
            ZQryTC.ParamByName('TC').AsString :=
                 nodoData.ChildNodes[I].ChildNodes[0].Attributes['OBS_VALUE']
         else
            ZQryTC.ParamByName('TC').Value := valor;

         ZQryTC.ExecSQL;

         Result.Add(Moneda.ToString + #9 +
                    nodoData.ChildNodes[I].ChildNodes[0].Attributes['TIME_PERIOD'] + #9 +
                    nodoData.ChildNodes[I].ChildNodes[0].Attributes['OBS_VALUE'] );

      end;
    end;
    ZQryTC.Free;
  end;
end;

Con el código anterior recorremos los nodos de XLM para obtener la información que necesitamos, la insertamos en la base de datos y finalmente regresamos un informe de lo descargado a la forma principal como se puede observar en las siguientes imagenes:

Pareciera que la información mostrada careciera de sentido, sin embargo, la parte final de éste tutorial es mostrar un listado de los tipos de cambio de una fecha dada utilizando la vista que creamos anteriormente la cual es disparada por la siguiente consulta.

select * from TC_LISTADO
where FECHA = :fecha

Para ejecutar la consulta utilizamos el evento OnClick del  botón [Listado] y escribimos el siguiente código:

procedure TForm1.Button3Click(Sender: TObject);
begin
  ZQuery1.Close;
  ZQuery1.ParamByName('FECHA').Value := DateTimePicker1.Date;
  ZQuery1.Open;
end;

Ya tenemos listo todo y solo presionamos el botón [Listado] para que la información sea presentada en el Grid de nuestra forma como se observa en la siguiente imagen.

Como pueden ver, acceder a una base de datos con Delphi Starter no tiene mayor complicación y las posibilidades que se nos presentan son muchas, solo recuerden, de acuerdo a la licencia de ésta edición de Delphi Starter se nos indica que si logran obtener una ganancia igual o mayor a 1,000 dólares deben de adquirir una versión de pago, los invito a que hagan el esfuerzo, les aseguro que no se arrepentiran.

Y bueno hemos llegado al final de éste tutorial, espero que sea de su agrado y sobre todo que sea de utilidad.

Hasta la próxima


Todo el código escrito aquí es de libre descarga y utilización solo te pido, si te parece correcto, que menciones su origen y claro cualquier mejora que le hagas publicala que se agradecerá enormemente.

Muchas gracias.

Delphi 10.2 Tokio

Hola amigos,

Después de un par de semanas donde tuve algunos problemas con mi sitio, hemos regresado con una nueva imagen y no encontré mejor forma que hablando de la característica más esperada de Delphi.

En efecto, la posibilidad de desarrollar aplicaciones que corran en Linux se ha hecho realidad, se está hablando por todo el mundo y mi bitácora no iba a ser la excepción.

Para poder generar mi primer aplicación he seguido el video tutorial de mi buen amigo Luis Felipe González quien de una forma sencilla y muy didáctica muestra como instalar una máquina virtual con Ubuntu Server 16.04.2 para desarrollar aplicaciones Delphi.

No voy a repetir lo que nuestro amigo amablemente nos ha proporcionado para respetar su trabajo y darle los créditos que merece, así que pueden acceder al video tutorial dando clic en el siguiente enlace:

Delphi 10.2 Tokyo. Configurar el Ambiente Linux usando Ubuntu 16.04.2 LTS

Siguiendo el video tendremos lo necesario para crear nuestra primer aplicación en Linux, sin embargo, ésta entrada mostrará la instalación de Delphi 10.2 Tokio y para poder realizarla he utilizado el Trial que está disponible en la página de Embarcadero y que puedes descargar desde el siguiente enlace Start for free.

Una vez descargado el instalador procedemos a ejecutarlo para iniciar el proceso.

 

 

Para iniciar nos muestra la pantalla de selección de las plataformas que se desean instalar, para éste ejercicio solo he seleccionado Delphi con todas las plataformas disponibles, Windows 64 bits, Windows 32 bits, OS X, iOS, Android y el ya famoso Linux 64 bits.

 

 

Posteriormente tenemos que seleccionar opciones adicionales, para éste ejercicio solo vamos a seleccionar solo unas cuantas, una vez que estén instalado nuestra herramienta podrán seleccionar de nuevo las que se deseen tener instaladas como lo veremos mas adelante.

Damos clic en el botón Install para continuar.

 

 

A continuación nos pide leer cuidadosamente las licencias de cada uno de las dependencias involucradas. Si están de acuerdo con las licencias presione el botón Agree all para continuar.

 

 

Con ésto terminamos el proceso de instalación de la herramienta. Presionamos el botón START WORKING para que se muestre el IDE de Delphi 10.2 Tokio.

 

 

El IDE de Delphi 10.2 Tokio no sufrió cambios aparentes en comparación con Delphi 10.1 Berlín, sin embargo, se reorganizaron algunos elementos del menú para un mejor manejo y una navegación más rápida como lo podemos observar en la siguiente lámina obtenida del Webinar del lanzamiento de Delphi 10.2 Tokio.

 

En éste punto ya tenemos listo nuestro Delphi para comenzar a experimentar, pero antes procederemos a configurar nuestro ambiente de desarrollo que es el que nos permitirá acceder a Linux desde Delphi.

Lo primero que necesitamos es transferir el archivo LinuxPAServer19.0.tar.gz que se localiza en el directorio PAServer de nuestra instalación a Linux utilizando un cliente de ftp, en mi caso Bitvise SSH Client que es el que utilizo como Terminal SSH y FTP.

Ya teniendo nuestro PAServer en Linux procederemos a descompactarlo con la instrucción que nos mostró Luis Felipe en su video, ejecutamos el paserver, no asignamos contraseña y ya tenemos nuestro ambiente de trabajo en linux listo para aceptar llamadas desde Delphi.

tar -xvzf LinuxPAServer19.0.tar.gz

 

 

Solo nos falta crear el perfil de la conexión con el PAServer que está corriendo en la maquina remota Linux, para ello damos clic en el Menu ToolsOptions y seleccionamos la opción SDK Manager, damos clic en el boton Add… y nos pedirá tres datos IP Remota, Puerto y Contraseña, en éste caso la IP de mi Servidor Linux es 192.168.1.67, el puerto es el asignado por el PAServer 64211 y no asigné contraseña. Presionamos el botón de Test Connection. y si se siguió paso a paso el tutorial de Luis Felipe verémos la confirmación de que la conexión con el servidor Linux a sido satisfactoria.

 

 

 

Ya está todo listo para comenzar a escribir código y para ello crearemos un nuevo proyecto de tipo consola dando clic en la opción Create a new project… – Delphi Projects ó a través del Menú File – New – Other – Delphi Projects

 

Asignamos la plataforma de Linux 64-bits, escribimos nuestro mensaje en el bloque correspondiente, ejecutamos y listo, ya hemos generado nuestro primer «Hola Mundo» corriendo en Linux como se puede observar en la siguiente imagen.

 

 

Con ésto hemos terminado éste pequeño ejercicio pero muy esperanzador en cuanto al potencial que tenemos con ésta nueva versión de Delphi.

Quiero finalizar parafraseando a Neil Armstrong.

«Es un pequeño paso para el programador, pero un gran paso para la comunidad»

 

 

 

 

 

 

Hasta la próxima


Primer «vistazo» a RAD Studio XE6

 

RAD_icons2

Ayer 17 de Abril, ya he instalado RAD Studio XE6 y quiero mostrarles mi primer contacto con ésta versión «cero kilometros».

Cabe mencionar que contiene muchos componentes por demás interesantes y requerirá de estudiarlos.

Pues bien, mi primer impresión es que ha tenido cambios a nivel visual, incluyendo desde el instalador del producto hasta el menú del mismo, el cual ya no es el mismo en 3D que estabamos acostumbrados a utilizar, ahora tiene un estilo METROPOLIS, que en lo personal me agrada, no tengo problema por eso, algunos dirían que es igual que Visual Studio, pero bueno, al final el estilo RETRO pareciera que llegó para quedarse.

RADXE6_1

RADXE6

También, incluye muchas funcionalidades y características de actualidad, como lo es la forma Google Glass, aunque poco a poco iremos descubriendo más características, como primer vistazo, no he visto todo por supuesto.

googleGlass

Y bueno, antes de pensar en hacer algo y ver que hace RAD Studio XE6, he tomado uno de sus ejemplos para compilarlo y ejecutarlo en mi teléfono Android. Cabe mencionar que sólo abrí el proyecto SQLite del directorio de ejemplos, el cual permite crear tareas y las almacena en una base de datos SQLite llamada «tasks.s3db», pues bien, ejecuté el proyecto y el resultado fué el siguiente:

tasks

Hasta aquí mi primer contacto con RAD Studio XE6, aunque hay muchas cosas realmente buenas, estoy particularmente interesado en utilizar y aprender Tethering. Ya veremos en las próximas semanas que haremos con todo ésto, son demasiadas cosas por explorar pero poco el tiempo disponible.

Nos leemos.

«Happy Coding»

Construir una App iOS paso a paso

Hola amigos, en ésta ocasión vamos a desarrollar una aplicación para iOS paso a paso, para éste artículo usaremos la interfaz de un iPhone5, pero bien pueden hacerlo para iPhone estándar y/o para iPad.

Antes de comenzar éste tutorial, quiero comentar, que es requisito contar con una MAC o al menos un servicio como el macincloud para poder compilar y ejecutar nuestra aplicación móvil.

Como ya es mi costumbre, vamos a desarrollar un cliente que consuma un Servicio Web pero desde un dispositivo móvil, vamos a tomar el ejemplo que publiqué hace unos meses (Probando Delphi for iOS) del cual no pude hablar más a fondo debido a que aún era un producto beta pero que me sirvió mucho para aprender un poco de ésta nueva característica que cuenta la más reciente versión de Delphi.

Lo primero que vamos a hacer es crear una aplicación Delphi para Móvil con Firemonkey como se muestra en la siguiente imagen:

Acto seguido, Delphi nos muestra una ventana con diferentes  plantillas de aplicaciones móviles con FireMonkey, donde elegiremos para efectos de éste ejercicio, la plantilla que contiene encabezado y pié de página.

Posteriormente y antes de comenzar a desarrollar nuestra aplicación,  Delphi nos muestra un experto que  nos ayudará a configurar el ambiente de desarrollo para la construcción de aplicaciones móviles para iOS, es decir, como configurar la MAC y RAD Studio para trabajar en conjunto.

Pueden seguir éste excelente artículo de mi buen amigo Germán Estévez (Neftalí) para configurar el entorno de trabajo iOS.

Minimizamos o cerramos el experto y tendremos ya nuestra forma lista para comenzar a escribir nuestra primera aplicación móvil para iOS.

Comenzamos por elegir el dispositivo para el cual vamos a desarrollar nuestra aplicación móvil. En mi caso elegí el iPhone5.

También colocamos un texto en el encabezado de nuestra forma, éste ejemplo será un conversor de monedas a través del consumo de un Servicio Web creado por el Banco de México, el cual nos proporciona el tipo de cambio de algunas monedas.

Ahora necesitamos decidir que objetos vamos a colocar en nuestra forma, en mi caso decidí colocar los siguientes:

  • 1 TListBox
  • 7 TListBoxItem’s
  • 2 TListBoxGroupHeader’s
  • 5 TLabel’s
  • 2 TEdit’s

También conseguí 6 banderas de los países que vamos (en éste ejemplo) a disponer de paridad cambiaria contra el peso mexicano.

Después de agregar los objetos y acomodarlos según me pareció adecuado, nos ha quedado como se muestra en la imagen.

  El primer paso es agregar el TListBox a nuestra forma y configuramos las siguientes propiedades:

  • GroupingKind = gsGrouped
  • StyleLookup = transparentlistboxstyle

Damos clic derecho del mouse en el ListBox donde nos mostrará un menú emergente donde seleccionaremos la opción AddItem y agregamos:

  • 7 TListBoxItem’s
  • 2 TListBoxGroupHeader’s

Continuamos agregando imágenes a los TListBoxItem; en éste ejemplo utilizaremos banderas de cada país del cual se tiene paridad cambiaria con el Peso mexicano, damos clic en la propiedad ItemData del TListBoxItem, damos clic en la propiedad BitMap y nos mostrará una ventana donde podrémos seleccionar la imagen que deseamos. También editamos el texto que se va a mostrar en la propiedad Text.

Adicionalmente colocamos los 2 TEdit y las 5 TLabel como se muestra en la imagen siguiente:

El siguiente paso es  generar nuestra clase que consumirá el Servicio Web del Banco de México y que nos proporcionará las paridades o tipos de cambio de las monedas que vamos a utilizar en nuestra aplicación, el WSDL de éste servicio web es el siguiente:

http://www.banxico.org.mx/DgieWSWeb/DgieWS?WSDL

Vamos a utilizar la forma tradicional de importar el WSDL a nuestra aplicación con el importador de WSDL como se muestra a continuación:

Éste importador genera el código necesario para poder consumir el servicioWeb y ya sólo nos resta escribir el código para que nuestra aplicación se conecte y nos muestre las paridades para cada una de las monedas seleccionadas y usarlas para convertir la cantidad de la moneda extranjera al peso mexicano. Por supuesto, ustedes pueden utilizar otro proveedor de paridades para ajustarlo a su moneda.   Ya tenemos todo para comenzar a escribir nuestro código.

Y como todo lo nuevo, hay algunos detalles que hay que tomar en cuenta a la hora de escribir nuestro código,

por ejemplo:

¿Cómo hacer que nuestra aplicación se ajuste en la pantalla para que no se encime en los contoles donde vamos a capturar el monto a convertir?.

La solución la encontré en uno de los ejemplos que vienen con delphi y se llama «ScrollableForm» el cual se encuentra en el directorio «RAD Studio\11.0\Samples\FireMonkeyMobile».

Se requirió de agregar dos componentes más, un TVertScrollBox y un TLayout para poder ajustar la pantalla cuando se intenta escribir en los controles sin que interfiriera el teclado numérico.

 

{******************************************************************************}
{  código para ajustar los objetos cuando se muestra el teclado en la pantalla }
{******************************************************************************}

procedure THeaderFooterForm.RestorePosition;
begin
  VertScrollBox1.ViewportPosition := PointF(VertScrollBox1.ViewportPosition.X, 0);
  Layout1.Align := TAlignLayout.alClient;
  VertScrollBox1.RealignContent;
end;

procedure THeaderFooterForm.UpdateKBBounds;
var
  LFocused : TControl;
  LFocusRect: TRectF;
begin
  FNeedOffset := False;
  if Assigned(Focused) then
  begin
    LFocused := TControl(Focused.GetObject);
    LFocusRect := LFocused.AbsoluteRect;
    LFocusRect.Offset(VertScrollBox1.ViewportPosition);
    if (LFocusRect.IntersectsWith(TRectF.Create(FKBBounds))) and
       (LFocusRect.Bottom > FKBBounds.Top) then
    begin
      FNeedOffset := True;
      Layout1.Align := TAlignLayout.alHorizontal;
      VertScrollBox1.RealignContent;
      Application.ProcessMessages;
      VertScrollBox1.ViewportPosition :=
        PointF(VertScrollBox1.ViewportPosition.X,
               LFocusRect.Bottom - FKBBounds.Top);
    end;
  end;
  if not FNeedOffset then
    RestorePosition;
end;

procedure THeaderFooterForm.FormCreate(Sender: TObject);
begin
  VertScrollBox1.OnCalcContentBounds := CalcContentBoundsProc;
end;

procedure THeaderFooterForm.FormVirtualKeyboardHidden(Sender: TObject;
  KeyboardVisible: Boolean; const Bounds: TRect);
begin
  FKBBounds.Create(0, 0, 0, 0);
  FNeedOffset := False;
  RestorePosition;
end;

procedure THeaderFooterForm.FormVirtualKeyboardShown(Sender: TObject;
  KeyboardVisible: Boolean; const Bounds: TRect);
begin
  FKBBounds := TRectF.Create(Bounds);
  FKBBounds.TopLeft := ScreenToClient(FKBBounds.TopLeft);
  FKBBounds.BottomRight := ScreenToClient(FKBBounds.BottomRight);
  UpdateKBBounds;
end;

procedure THeaderFooterForm.CalcContentBoundsProc(Sender: TObject;
  var ContentBounds: TRectF);
begin
  if FNeedOffset and (FKBBounds.Top > 0) then
  begin
    ContentBounds.Bottom := Max(ContentBounds.Bottom,
                                2 * ClientHeight - FKBBounds.Top);
  end;
end;
{******************************************************************************}

Scroll Vertical para reajustar la pantalla

Otro detalle era pasar el monto, la bandera y el texto de cada moneda, lo cual fué algo simple de resolver pasando las propiedades al seleccionar la moneda deseada hacia el objeto destino.

 
procedure THeaderFooterForm.lbDolarUSAClick(Sender: TObject); 
begin 
  TC := StringReplace(label1.Text,'

Escribimos el código necesario en el evento OnExit del Edit donde capturamos la cantidad a convertir para que nos muestre el valor en peso de acuerdo a la moneda seleccionada.

 
procedure THeaderFooterForm.Edit2Exit(Sender: TObject);
begin
  valorME := StringReplace(edit2.Text,'

Compilamos y Delphi XE4 hace su trabajo generando todo lo necesario para que nuestra aplicación sea ejecutada en el simulador.

Convertimos dólares a pesos

Convertimos Euros a pesos

Con ésto hemos terminado el primer artículo de una serie que intentará demostrar que se puede desarrollar 4 aplicaciones diferentes utilizando los mismo componentes y el mismo código, espero no defraudarlos 🙂

Los otros tres artículos son:

Happy coding!!!!

Descargas


Si lo deseas puedes descargar el código fuente de ésta entrada, espero sea de utilidad.

Ésta entrada y el código fuente son libres para su uso y publicación, lo único que te pido, si te parece justo, es mencionar la fuente de donde se obtuvo.


Consumir un Servicio Web de terceros

A petición de uno de mis lectores, he creado un pequeño cliente que consume un servicio web de terceros, en éste caso el mismo que usé para mi entrada anterior Probando Delphi for iOS  pero en una aplicación de escritorio.

El proceso es muy simple.

– Creamos una nueva aplicación VCL.

– Importamos el WSDL del Servicio Web en éste caso de Banxico.

Éste importador nos genera una clase con la definición del Servicio Web lista para ser consumida, como lo podemos apreciar en la siguiente imagen.

– Agregamos los objetos que deseamos para que nuestra interfáz gráfica se vea un poco decente 🙂

– Agregamos el código necesario para consumir el método que obtiene el tipo de cambio de las diferentes monedas y ejecutamos nuestra aplicación.

Cabe mencionar que por el poco tiempo que dispongo no pude utilizar el XML Data Binding para crear las clases que representan el esquema del documento XML por lo que tuve que «trabajar» con algo más simple para serializar el XML que nos regresa el Servicio Web.

Enjoy!!!

Nota: Desarrollado con Delphi XE2


Ésta entrada y el código fuente son libres para su uso y publicación, lo único que te pido, si te parece justo, es mencionar la fuente de donde se obtuvo.

Probando Delphi for iOS

Logo Delphi MVP

Como algunos saben, estoy muy involucrado en la creación y consumo de servicios web y desde hace tiempo había querido desarrollar un cliente que consumiera un servcio web desde dispositivos móviles tal y como lo hago en las aplicaciones de escritorio y puedo asegurarles que Delphi for iOS es inigualable, estoy muy entusiasmado por la rapidéz, facilidad y poderío al hacerlo con mi herramienta preferida.

Pues bien, he desarrollado un pequeño cliente para consumir un servicio web que nos proporciona el tipo de cambio de algunas monedas (USD Dólar, Dólar Canadiense, Euro, Yen y Libra Esterlina) con relación al peso mexicano y con ello poder hacer la conversión ya sea de pesos mexicanos a monedas extranjeras o al contrario.

El desarrollo de ésta app fué muy simple.

  • Importamos el wsdl de servicio web, en éste caso del Banco de México (http://www.banxico.org.mx/DgieWSWeb/DgieWS?WSDL)
  • Colocamos los componentes visuales necesarios.
  • Consumimos el método «tiposDeCambioBanxicoRequest» del servicio Web para mostrar los diferentes valores en pesos de las monedas extranjeras.
  • Escribimos las operaciones básicas para realizar la conversión de divisas.
  • Compilamos y ejecutamos la App en el simulador de iPhone instalado en mi MacBook Air.

 

vcl

La App funciona muy bien en el simulador de iPhone, se puede seleccionar la moneda que se deseé y se puede ingresar la cantidad que quieres convertir ya sea en pesos o en la moneda extranjera seleccionada. Como un pequeño detalle, la bandera de la moneda extranjera cambia de acuerdo a la moneda seleccionada en la parte superior.

iOS

Como ven es una App muy básica, pero las opciones son inmensas, por supuesto que no estoy descubriendo el hilo negro, ya hay muchas aplicaciones de éste tipo para dispositivos móviles, sin embargo, como prueba inicial, puedo asegurar que Delphi for iOS no me decepcionó, al contrario, me ha despertado un interés muy fuerte y sólo estoy en espera de que sea liberado.

Por hoy es todo, espero que ésta App les haya sido interesante e ilustrativa como lo fué para mi. Seguiremos probando Delphi for iOS, aún hay muchas cosas que quiero ver y el tiempo es poco 🙂

Hasta la próxima.

Importante: Considere que todo lo que se expresa en ésta publicación es acerca de un producto Beta por lo que los detalles finales pueden llegar a cambiar en el lanzamiento oficial.

Los únicos medios oficiales acerca de éste producto se encuentran en el sitio de embarcadero, puede acceder a los detalles en los siguientes enlaces :

Develop iOS applications with Delphi y en su mapa de ruta.

Ésta entrada sólo intenta mostrar de forma simple y sin entrar en detalles técnicos las facilidades que nos podría proporcionar el nuevo Delphi for iOS

Delphi para iOS. Vista previa.

 

Logo Delphi MVP

Hola amigos, en ésta entrada hablaremos un poco acerca de la vista previa de Delphi para iOS y que nos ha sido mostrada a través del webinar de ayer 27 de Febrero de 2013.

Personalmente estoy muy ansioso de contar con éste tipo de soluciones, tanto para iOS como para Android. En éste webinar se ha mostrado el desarrollo de aplicaciones para iOS y se comenta que para el 3er cuarto de 2013 se tendrá la plataforma para Android.

 

Una de las cosas que me parecieron relevantes y por demás interesantes son los cambios que se han hecho al compilador y que muestro en la siguiente imagen:

 

cambio_Comp

 

También se han agregado algunos componentes nuevos

New_Comp

La presentación me gustó y una de las cosas que se deben aclarar para el desarrollo de aplicaciones iOS es que se necesita una MAC, y no es un requerimiento de Delphi, es una regla de la compañia de la manzana para poder generar dichas aplicaciones.

Yo ya veo maduro el producto y casi listo para ser lanzado al mercado, lo que falta, y se que es el siguiente paso, es generar aplicaciones para Android (asunto del cual estoy realmente ansioso de probar).

Bien por la vista previa, gracias Diego, gracias Fernando y gracias Allison.

 

Nos vemos en la siguiente entrada.

 

The Embarcadero MVP Program

Como se publicó no sólo por ésta bitácora sino por varias más, se inició un programa conocido como «Embarcadero Evangelist Program» ahora éste programa cambia de nombre y oficialmente se llamará «The Embarcadero MVP Program».

Esto ha sido anunciado por Anders Ohlsson en su bitácora The Hacker’s Corner, por supuesto aún se está trabajando con la imagen del programa y con el diseño de una página de lanzamiento oficial del programa.

Se muestra una lista de los actuales miembros del programa y pronto crecerá con algunos compañeros que están en espera de ser confirmados.

Por último Anders Ohlsson abre la convocatoria para que la comunidad postule a más compañeros que son apasionados de las herramientas de Embarcadero y que deberían ser un MVP.

Sólo puedo decir que es un honor estar en la lista al lado de profesionales indiscutibles. 🙂

Seguimos en contacto.