JTagua

Inicio » Delphi

Category Archives: Delphi

Anuncios

Informes parametrizados con Crystal Report + Delphi. (Parametro = JvDBSearchComboBox).

A veces, el valor del parámetro que toma un informe parametrizado desde Delphi, previamente diseñado con Crystal Report, no es libre para el usuario. El usuario se ve obligado a elegir un valor del parámetro que es un campo de una tabla. En este caso, será necesario utilizar el Objeto/Componente “JvDBSearchComboBox” de la paleta de componentes “Jv Data Controls”.

Supongamos que

1) Disponemos de un miembro de especificaciones con extensión .rpt, generado desde el propio Crystal Report, que espera un valor de parámetro (la Nacionalidad) y además disponemos de una tabla denominada tpaises con su datasource denominado dspaises. En este caso, no nos interesa que la entrada del valor del parámetro sea simplemente un TEdit, sencillamente porque el usuario podría introducir unas veces España y otras Spain para intentar hacer lo mismo. Necesitamos condicionar la entrada de la nacionalidad a los propios valores de una tabla que las contiene.

2) Añadimos a la interfaz un componente JvDBSearchComboBox, al que hemos llamado (propiedad name) ParJvDBSCB y para el que la propiedad datasource se fijará a dspaises y la propiedad datafield se fijará a pais.

3) Un botón que, desde su evento click, ejecute el siguiente código:

md.DirxNacionalidad.ReportName:=ExtractFilePath(Application.ExeName)+’RPT\DirxNacionalidad.rpt’;

md.DirxNacionalidad.ParamFields.Items[0].CurrentValue := ParJvDBSCB.Text;

md.DirxNacionalidad.execute;

EXPLICACIÓN:

Tal como puede verse, la primera instrucción fija en términos relativos al ejecutable del proyecto, la localización del archivo generado por Crystal Report (extensión rpt).

La segunda instrucción asigna al valor actual del parámetro de orden cero (el primero) a la propiedad Text del objeto JvDBSearchComboBox, elegido previamente por el usuario desde una ComBoBox donde se presentar todos los valores posibles tomados de la tabla de paises.

Finalmente, el método execute, ejecuta el informe.

Anuncios

Asociación de una información video (.avi) a los registros de una tabla.

Existen ocasiones en las que todo está en contra: La base de datos no admite en un campo de un registro una información video tipo .avi (imágenes animadas), además no encontramos un control de base de datos que pueda representar a dicho campo y mantenerse sincronizado con el scroll en la tabla…

Por ejemplo,

Supongamos una interfaz (a cuyo formato llamaremos fpeliculas) pretenda presentar la información de una tabla de películas (a la que llamaremos tpeliculas), y entre otras informaciones (Director, actores, argumento, fechas diversas, etc) se necesita editar un video de un trailer de dicha película. La base de datos en MsAccess (con sus limitaciones propias). La clave de dicha tabla (a la que llamaremos codigo_pelicula) es un número entero autoincrementado.

En este caso existe una solución artesanal del problema.

1) Colocamos un control TAnimate (al que llamaremos Animate1) con la propiedad Active a False y otro TMediaPlayer (al que llamaremos (MP) con la propiedad AutoOpen a False. Se necesitan estos valores porque desconocemos a priori el nombre del fichero video (.avi) que deseamos presentar. Como es obvio en la propiedad Display del control TMediaPplayer asignaremos el control TAnimate.

2) Creamos una carpeta debajo del ejecutable de la aplicación denominada videos y allí colocaremos los distintos trailers, llamándolos 1.avi, 2.avi, 3.avi, etc… Y como es obvio cada uno de ellos de corresponderán con los trailers de las películas cuya clave es 1, 2, 3 respectivamente.

3) En el módulo de datos (al que hemos llamado md) definiremos a nivel global una variable a la que llamaremos primero de tipo booleano.

4) En el evento Create del módulo de datos escribiremos

Primera:=True;

5) En el evento AfterScroll de la tabla tpelículas escribiremos el siguiente código:

procedure Tmd.tpeliculasAfterScroll(DataSet: TDataSet);
var
fichero : string;
begin
fichero:=dir0+’videos\’+inttostr(md.tpeliculas.FieldByName(‘Codigo_pelicula’).AsInteger)+’.avi’;
if fileexists(fichero) then
begin
if Primera = False then
begin
Upeliculas.fpeliculas.MP.FileName:=fichero;
Upeliculas.fpeliculas.MP.Open;
Upeliculas.fpeliculas.MP.Play;
end
else Primera := False;
end;
end;

Donde:

Upeliculas es la unidad .pas donde se encuentra el formato fpeliculas del proyecto.

  • fichero es una variable de cadena que cada vez que ocurre un scroll en la tabla (avance o retroceso de los registros) apunta a un hipotético fichero avi que contiene, si existe, el trailer de la película cuyos datos se están mostrando en la interfaz.
  • dir0, es una variable local que apunta al ejecutable de la aplicación, y que está definida en la forma dir0:=extractfilepath(Application.exename); dentro del create del módulo de datos.
  • primero, ya explicada, es una variable que la primera vez que se abre la tabla tiene valor True y el resto de las veces mientras nos desplazamos por los registros de la tabla tiene valor False.

6) Para evitar que una vez se esté reproduciendo un trailer para un registro dado siga reproduciéndose con el cambio al registro anterior/posterior, hemos de escribir el siguiente código en el evento beforeScroll de la tabla películas,

procedure Tmd.tpeliculasBeforeScroll(DataSet: TDataSet);
begin
Upeliculas.fpeliculas.MP.Close;
Upeliculas.fpeliculas.Animate1.active:=False;
Upeliculas.fpeliculas.Animate1.Refresh;
end;

De esta manera cada vez que se haga scroll sobre los registros de la tabla lo primero que se hace es cerrar el componente TMediaPlayer, desactivar y refrescar el componente TAnimate.

7) El código anterior, funciona de forma sincronizada desde el segundo registro hasta el final de la tabla y viceversa, pero no funciona para el primer registro, ya que éste no se presenta mediante scroll la primera vez. Para resolver esto, en el evento Activate de la forma fpelículas escribimos:

procedure Tfpeliculas.FormActivate(Sender: TObject);
var
fichero:string;
begin
fichero:=dir0+’videos\’+inttostr(md.tpeliculas.FieldByName(‘Codigo_pelicula’).AsInteger)+’.avi’;
if fileexists(fichero) then
begin
Upeliculas.fpeliculas.MP.FileName:=fichero;
Upeliculas.fpeliculas.MP.Open;
Upeliculas.fpeliculas.MP.Play;
end;
end;

Con esto conseguimos presentar el video del primer registro de la tabla, si existe…

Y esto es todo!!.

Aunque parece farragoso pero es de una lógica sencilla si se sabe interpretar los eventos afterScroll y beforeScroll que se producen en una tabla conforme nos movemos sobre ella.

Existen otras solucione mas rápidas y cómodas, pero mucho me temo que requieren de controles/componentes u objetos propietarios, y muy probablemente motores de bases de datos distintos.

Editor de instalaciones NSIS y HM NIS Edit.

En el desarrollo de aplicaciones, cuando la aplicación está definitivamente terminada, se hace necesario diseñar un programa instalador o setup que permita la distribución de los distintos componentes que integra la aplicación y la instalación rápida y fácil por parte del usuario.

Existen muchas herramientas que permiten hacer esto, unas son de código propietario y otras abierto o libres. Utilizaremos aquí una de código libre y gratuita denominada NSIS, con su editor de script HM NIS Edit.

La descargar de estas herramientas la podemos hacer desde,
http://nsis.sourceforge.net/Main_page y http://hmne.sourceforge.net/ respectivamente.

Una vez descargadas e instaladas en el disco duro, procederemos a elaborar un script de instalación que respete el siguiente diseño:

Suponemos una aplicación que se llama GESAL 1.0, cuyo ejecutable se encuentra en la carpeta GESAL y que tiene varias carpetas:

BD, Base de Datos de MS Access,
RPT, Informes de Crystal Report
HELP, Ficheros de Ayuda

Suponemos igualmente que en la carpeta principal se encuentran dos ficheros de texto, denominados Licencia.txt y leeme.txt, con la correspondiente información.

En la hipótesis anterior, abrimos el editor NIS Edit y aparecerá

Seleccionamos ahora Archivo/Nuevo Script desde el Asistete, y aparecerá

Pulsamos siguiente,

En la pantalla anterior tendremos que cumplimentar los datos que nos solicitan, es necesario introducir estos datos puesto que el programa instalador los utilizará en la presentación de la instalación. La entrada de la página web no es necesaria si no se dispone de ella.

Pulsamos siguiente,

En esta pantalla sólo es necesario indicarle el nombre y dónde se desea que se guarde el ejecutable del instalador setup. Podría además cambiarse el icono del instalador, el lenguaje, la interfaz y el tipo de compresión.

Pulsamos siguiente,

En esta pantalla, elegimos el directorio por defecto donse deseamos instalar la aplicación, permitimos o no al usuario cambiar el directorio de instalación, indicamos dónde se encuentra el fichero de texto que incorpora la Licencia y establecemos la forma en la que el usuario aceptará la licencia.

Téngase presente que la variable interna $PROGRAMFILE apunta a C:\Archivos de Programa
Pulsamos ahora siguiente,

En esta pantalla y siguiendo el supuesto, tendremos que añadir a la carpeta “principal” tres archivos: El ejecutable, el readme y la licencia.

Es decir:

Crearemos ahora la carpetas BD, en la que se ha incluido la base de datos correspondiente,

Comprobamos que la base de datos Ms Access (archivo con extensión mbd) se instsla en $INSTDIR\BD.

Crearemos después la carpeta RPT, en la que hemos incluidos los distintos informes de Crystal Report,Comprobamos que los archivos de extensión rpt serán copiados en la carpeta $INSTDIR\RPT

Pulsamos ahora Siguiente,

En esta pantalla se definen los iconos, el directorio del menu de inicio y los accesos directos.

Pulsamos siguiente,

En esta pantalla fijamos los parámetros de ejecución , si existen, de la aplicación y el nombre y la localización del fichero leeme.txt

Pulsamos siguiente,

En esta pantalla se fijarán determinadas caracteristicas del programa desinstalador.

Pulsamos siguiente,

Es esta pantalla seleccionamos Guardar script, Convertir rutas de archivos a rutas relativas y compilar script.

Pulsamos siguiente,

En esta pantalla seleccionamos el nombre y directorio donde deseamos guardar el script.

Finalmente, aparece el script Y EL RESULTADO DE LA COMPILACIÓN.

Informes parametrizados con Crystal Report + Delphi. (Parametro = TJvDateEdit).

A veces, la gestión de un informe parametrizado desde Delphi, previamente diseñado con Crystal Report, requiere que la entrada del valor del parámetro se realice a través de un componente que acepte fechas, tal como TJvDateEdit

Por ejemplo, supongamos que tenemos un informe parametrizado que acepta un parámetro de fecha. Supongamos que el campo con el que deseamos comparar pertenezca a la tabla Proyecciones y se llame fechadeproyeccion.

Queremos lanzar un listado parametrizado, de modo que se obtengan sólo los registros de las proyecciones para los que la fecha de proyección sea igual o menor que la fecha entregada en el parámetro.

Para resolver esta cuestión:

1) Disponemos de un miembro de especificaciones con extensión .rpt, generado desde el propio Crystal Report, y al que le hemos llamado InfFechaProyecciones.rpt. Definimos un parámetro de cadena (… no Date, es necesario crearlo como string) en el informe denominado ParFecha y establecemos como formula de selección de los registros la siguiente:

{Proyecciones.fechadeproyeccion} <= DateTimeValue ({?ParFecha})

La función DateTimerValue garantiza que la cadena introducida en el parámetro se convierta a tipo Fecha (Date).

2) Añadirmos al formulario un Objeto/Componente TJvDateEdit al que llamaremos ParFecha, de modo que su propiedad Text tomará como “cadena” en formato DD/MM/AAAA el valor introducido como parámetro.

3) Un botón que, desde su evento click, ejecute el siguiente código:

md.InfFechaProyeccion.ReportName:=ExtractFilePath(Application.ExeName)+’RPT\InfFechaProyeccion.rpt’;

md.InfFechaProyeccion.ParamFields.Items[0].CurrentValue:=ParFecha.Text;

md.DirxNacionalidad.execute;

EXPLICACIÓN:

Tal como puede verse, la primera instrucción fija en términos relativos al ejecutable del proyecto, la localización del archivo generado por Crystal Report (extensión rpt).

La segunda instrucción asigna al valor actual del parámetro de orden cero (el primero) a la propiedad Text dependiendo de la fecha seleccionada en el componente TJvDateEdit.

Finalmente, el método execute, ejecuta el informe.

Informes parametrizados con Crystal Report + Delphi. (Parametro = TComboBox).

A veces, la gestión de un informe parametrizado desde Delphi, previamente diseñado con Crystal Report, requiere que la entrada del valor del parámetro se realice a través de un componente TComboBox.

Por ejemplo, supongamos que tenemos un informe parametrizado que acepta un parámetro de cadena con una de las siguiente entradas (Spain, Russia, United Kingdom, United States), y que se corresponde con cuatro nacionalidades posibles.

Para resolver esta cuestión:

1) Disponemos de un miembro de especificaciones con extensión .rpt, generado desde el propio Crystal Report, y al que le hemos llamado DirxNacionalidad.rpt

2) Añadirmos un Objeto/Componente TComboBox al que llamaremos ParNacCombo y para el que la propiedad Items tiene los cuatro valores arriba enumerados, y que se tomarán como posibles valores del parámetro. Fijaremos la propiedad ItemIndex en 0 para indicar que la caja tendrá seleccionado el primer elemento (índice cero).

3) Un botón que, desde su evento click, ejecute el siguiente código:

md.DirxNacionalidad.ReportName:=ExtractFilePath(Application.ExeName)+’RPT\DirxNacionalidad.rpt’;

md.DirxNacionalidad.ParamFields.Items[0].CurrentValue := ParNacCombo.Items[ParNacCombo.ItemIndex];

md.DirxNacionalidad.execute;

EXPLICACIÓN:

En el ejemplo anterior al objeto/Componente TComboBox le he llamado pParNacCombo, el miembro rpt se llama DirxNacionalidad y se encuentra en el directorio RPT desde donde se ejecuta la aplicación.

Tal como puede verse, la primera instrucción fija en términos relativos al ejecutable del proyecto, la localización del archivo generado por Crystal Report (extensión rpt).

La segunda instrucción asigna al valor actual del parámetro de orden cero (el primero) al elemento seleccionado por el usuario de la caja combinada. Téngase presente que los elementos de la caja están indexados y que el valor entero asignado a la propiedad ItemIndex coincide siempre con el elemento seleccionado por el usuario.

Finalmente, el método execute, ejecuta el informe.

Informes parametrizados con Crystal Report + Delphi. (Parametro = TEdit).

Para gestionar un informe parametrizado desde Delphi, previamente diseñado con Crystal Report, es necesario:

1) Disponer de un miembro de especificaciones con extensión .rpt, generado desde el propio Crystal Report.

2) Un campo TEdit que reciba el valor concreto que tomará el parámetro.

3) Un botón que , desde su evento click, ejecute el siguiente código:

md.DirxNacionalidad.ReportName:=ExtractFilePath(Application.ExeName)+’RPT\DirxNacionalidad.rpt’;

md.DirxNacionalidad.ParamFields.Items[0].CurrentValue := pInforme.Text;

md.DirxNacionalidad.execute;EXPLICACIÓN:

En el ejemplo anterior al objeto/Componente TEdit le he llamado pInforme, el miembro rpt se llama DirxNacionalidad y se encuentra en el directorio RPT, desde donde se ejecuta la aplicación.

 

Tal como puede verse, la primera instrucción fija en términos relativos al ejecutable del proyecto, la localización del archivo generado por Crystal Report (extensión rpt).

La segunda instrucción asigna al valor actual del parámetro de orden cero (el primero) a la propiedad Text del objeto TEdit, introducido previamente por el usuario.

Finalmente, el método execute, ejecuta el informe.

Instalación componentes Crystal Report.

Crystal Report es un generador de Informes diseñado para trabajar con una gran variedad de motores de bases de datos tales como Sybase, IBM DB2, Ingres, Microsoft Access, Microsoft SQL Server, MySQL, Interbase , Oracle, Btrieve, así como otras fuentes de datos tales Microsoft Excel, Text files, XML files, Lotus Notes, Microsoft Exchange , Novell GroupWise o datos accesibles mediante web service, ODBC, JDBC o OLAP.

Cualquiera que sea el origen y naturaleza de los datos, se requiere, mientras se desarrolla la aplicación, tener instalado Crystal Report en el sistema. Con ayuda de dicha herramienta generaremos un informe cuyas especificaciones terminarán en un fichero o archivo de extensión rpt.

Las especificaciones de un informe (.rpt) generado con Crystal Report pueden ser manipuladas desde Delphi a través de una serie de componentes que habrá que incorporar a la “Paleta de Componentes”.

Para el caso concreto de Crystal Report 10, se necesita el archivo CrystalVCL10.zip, el cual, contiene los componentes TCrpe y TCrpeDS. Con ayuda de estos objetos/componentes podemos ver por pantalla en nuestros proyectos los informes previamente diseñados con Crystal Report, podemos lanzarlo a la impresora, o exportarlos a formatos tales como pdf , Excel, txt o csv.

Instalación.

Si descomprimimos CrystalVCL10.zip, veremos un archivo readme.txt donde se describen las instrucciones de instalación…

En forma resumida, los pasos a seguir son los siguientes:

a) Comprueba primero que no están instalados previamente los componentes que queremos instalar, para ello, inicia Delphi y comprueba que en la paleta de componentes no aparece en la pestaña “Data Access” los componentes TCrpe y TCrepD5.

b) Cierra todo (Close All) en Delphi, y pulsa “Project” y luego ” Options”. Localiza “Search path” pulsando previamente sobre “Directories/conditionals”. En esa caja de texto hay que introducir el directorio donde se encuentra la carpeta Delphi, resultado de descomprimir CrystalVCL10.zip. Cierra finalmente la caja de diálogo.

c) Ve ahora a la opción File/Open y carga el archivo “dcl7cr10.dpk”, (ojo con la extensión, pues los miembros dpk son componentes de terceros ), que se encuentra como cabe esperar en, por ejemplo, C:\componentes2\CrystalVCL10\Delphi.

d) Pulsa View/Project Manager, y comprobarás que el “paquete” anterior está compuesto por un gran número de unidades con extensión pas.

e) Haz click ahora con el botón derecho sobre el miembro “dcl7cr10”, verás que aparece el menú contextual. Para compilar hacer click en la opción “Compile”.

f) Cuando termine, haz click en “Install” en el mismo menú contextual. Si todo va bien aparecerá una informativa indicando que se han instalado los componentes TCrpe y TCrpeDS. Podrás localizar estos componentes en la pestaña “Data Access” de la Paleta de Componentes.

g) Finalmente, hacemos File/Close All y salvamos los cambios. Los componentes a partir de este momento nos permitirán gestionar los informes rpt generados con Crystal Report.

NOTA FINAL: Como es obvio, la distribución de las aplicaciones a nuestros clientes no requerirá de Crystal Report, sólo un runtime de libre distribución.

Interioridades de TDBNavigator.

A veces, cuando se usa el objeto TDBNavigator, es necesario averiguar qué botón a pulsado el usuario con objeto de ejecutar cierto código, amén del código propio de dicho botón. Para poder capturar/detectar el botón pulsado sugiero se emplee un código similar a éste:

procedure TForm1.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);
var
BtnName: string;
begin

case Button of
nbFirst : BtnName := ‘nbFirst’;
nbPrior : BtnName := ‘nbPrior’;
nbNext : BtnName := ‘nbNext’;
nbLast : BtnName := ‘nbLast’;
nbInsert : BtnName := ‘nbInsert’;
nbDelete : BtnName := ‘nbDelete’;
nbEdit : BtnName := ‘nbEdit’;
nbPost : BtnName := ‘nbPost’;
nbCancel : BtnName := ‘nbCancel’;
nbRefresh: BtnName := ‘nbRefresh’;
end;

MessageDlg(BtnName + ‘ button clicked.’, mtInformation, [mbOK], 0);

end;

Por otro lado, cada botón puede sustituirse por el método asociado a la tabla, esto es:

Tabla.First; //Sitúa el cursor de la Tabla en primera posición.
Tabla.Prior; //Sitúa el cursor de la Tabla en la posición Anterior.
Tabla.Next; //Sitúa el cursor de la Tabla en la posición Posterior.
Tabla.Last; //Sitúa el cursor de la Tabla en la última posición.
Tabla.bInsert; //Sitúa la tabla en Inserción.
Tabla.Delete; //Elimina el registro actual.
Tabla.Edit; //Sitúa la tabla en Edición.
Tabla.Post; //Ejecuta finalmente la operación pendiente.
Tabla.Cancel; //Cancela una operación pendiente.
Tabla.Refresh; //Refresca la tabla, sincroniza la tabla con los controles.

De esta forma podría sustituirse el objeto TDBNavigator por varios botones (TButton), de modo que cada uno de ellos realice la operación deseada sobre la tabla.

Pestaña saltarina!!

Resulta que cuando ejecuto el proyecto y voy a una interfaz que contiene un objeto TPageControl con varias pestañas (Ficha, Rejilla, Consultas), unas veces me presenta por primera vez la pestaña Ficha, en otras ocasiones me presenta la pestaña Rejilla y en otras ‘caprichosamente’ me presenta la pestaña Consultas.

Lo dicho!!…La pestaña Saltarina!!.

Bueno, la razón de esto es la siguiente:

Delphi, en ejecución, presenta la pestaña de un objeto hijo de TPageControl dependiendo de la última pestaña (TTabSheet) que se actualizó en tiempo de diseño. Por ello parece que salta!!. Es decir, si en tiempo de diseño me voy a Consultas para diseñar o arreglar algo, será ésta la pestaña que aparezca en tiempo de ejecución. Si un rato después, me voy a Ficha y arreglo algo, en ejecución me presentará Ficha, etc…

¿Qué hago para arreglar esto?:

Para arreglar esto colóquese la siguiente instrucción en el evento OnActivate de cada forma donde aparezca esta cuestión:

PageControl.ActivePageIndex := 0;

Como es natural, el objeto PageControl en cada caso se llamará de una y otra forma.

Explicación:

Con la instrucción anterior le estamos indicando al proyecto que cuando se active la interfaz, presente la pestaña cuyo orden es el cero, es decir, la primera que aparece por la izquierda, es decir, la pestaña Ficha. Esto es así porque la referencia a cada una de las pestañas puede hacerse como en un array con un índice (número entero desde 0, hasta el número total de pestañas que es exactamente la propiedad PageCount del objeto TPageControl.).

Otra forma de hacer esto cuando no conocemos el orden que ocupa la pestaña, entre todas ellas, pero sí conocemos el nombre (propiedad name) de la pestaña, sería:

PageControl.ActivePage := Propiedad Name de la pestaña que quiero activar;

De esta manera se le acaba el baile a la pestaña!!.

Funciones de conversion de cadena.

Function Format: Rich formatting of numbers and text into a string
Function StringToWideChar: Converts a normal string into a WideChar 0 terminated buffer
Function StrToCurr: Convert a number string into a currency value
Function StrToDate: Converts a date string into a TDateTime value
Function StrToDateTime: Converts a date+time string into a TDateTime value
Function StrToFloat: Convert a number string into a floating point value
Function StrToInt: Convert an integer string into an Integer value
Function StrToInt64: Convert an integer string into an Int64 value
Function StrToInt64Def: Convert a string into an Int64 value with default
Function StrToIntDef: Convert a string into an Integer value with default
Function StrToTime: Converts a time string into a TDateTime value