<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9171016160501594940</id><updated>2012-01-20T11:35:11.942+01:00</updated><category term='ADOX'/><category term='cliente servidor'/><category term='wininet.dll'/><category term='xBrowse'/><category term='fivewin'/><category term='res'/><category term='Recursos'/><category term='tInternet'/><category term='rc'/><category term='xBase'/><category term='dbf'/><category term='bielsys'/><category term='GetResources'/><category term='Ezsetup'/><category term='tSplitter'/><category term='actualizacion'/><category term='x'/><category term='LoadString'/><category term='SetResources'/><category term='find'/><category term='CabWiz'/><category term='TreeView'/><category term='tDatabase'/><category term='resource'/><category term='PocketPc'/><category term='hb_zipfile'/><category term='tFtp'/><category term='Harbour'/><category term='hb_unzipfile'/><category term='unzip'/><category term='Letodb'/><category term='zip'/><category term='sort'/><category term='ADO'/><category term='xHarbour'/><title type='text'>BielSys</title><subtitle type='html'>Programación en General. (por Gabriel Maimó "Biel")</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-2541256302519321195</id><published>2009-08-27T12:26:00.020+02:00</published><updated>2009-11-27T18:11:07.156+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='xBase'/><category scheme='http://www.blogger.com/atom/ns#' term='fivewin'/><category scheme='http://www.blogger.com/atom/ns#' term='unzip'/><category scheme='http://www.blogger.com/atom/ns#' term='bielsys'/><category scheme='http://www.blogger.com/atom/ns#' term='x'/><category scheme='http://www.blogger.com/atom/ns#' term='hb_zipfile'/><category scheme='http://www.blogger.com/atom/ns#' term='zip'/><category scheme='http://www.blogger.com/atom/ns#' term='hb_unzipfile'/><title type='text'>Usando ficheros comprimidos ZIP desde Harbour.</title><content type='html'>Como pone en la página web de harbour (&lt;a href="http://www.harbour-project.org/"&gt;http://www.harbour-project.org/&lt;/a&gt;), harbour es software libre 100 % compatible con compiladores Clipper.&lt;br /&gt;&lt;br /&gt;Pero ademas de las funciones Clipper, el compilador ha ido añadiendo una serie de funciones nuevas (todas las que su nombre empieza por HB_... ), que muchas veces desconocemos, y que nos aportan funcionalidad extra.&lt;br /&gt;Estas funciones son usadas escasamente por la comunidad de usuarios, bien porque desconoce su existencia, bien porque la documentación es excasa o nula para poderlas usar.&lt;br /&gt;&lt;br /&gt;En la entrada de hoy vamos a centrarnos sobre dos funciones en concreto, &lt;span style="font-weight:bold;"&gt;HB_ZipFile&lt;/span&gt; y &lt;span style="font-weight:bold;"&gt;HB_UnZipFile&lt;/span&gt;, que nos va a permitir comprimir y descomprimir archivos en formato ZIP.&lt;br /&gt;&lt;br /&gt;HB_ZipFile( cZipName, cFile | aFiles, nLevel, bBlock, lOverRide, cPassWord, lWithPath, lWithDrive, &lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "&gt;pFileProgress&lt;/span&gt; )&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table style="text-align: left; width: 100%;" border="1" cellpadding="2" cellspacing="2"&gt; &lt;tbody&gt;  &lt;/tbody&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;cZipName&lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Nombre del fichero ZIP a crear&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;cFile | aFiles&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Nombre del fichero a comprir o array de ficheros a comprimir. Unidad y Path pueden ser usados.&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;nLevel&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Nivel de compresión. De 0 a 9&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;bBlock&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Code block a ejecutar mientras se comprime&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;lOverRide&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Sobreescribir el fichero si existe.&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;cPassWord&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Password para encriptar el fichero ZIP&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;lWithPath&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Guardar el path si/no&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;lWithDrive&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Guardar la unidad si/no&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;pFileProgress&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Code bloclk para progreso de archvios.&lt;br /&gt;&lt;br /&gt;    &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;tbody&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;HB_UnZipFile( cFile, bBlock, lWithPath, cPassword, cPath, cFile | aFiles, FileProgress )&lt;br /&gt;&lt;br /&gt;&lt;table style="text-align: left; width: 100%;" border="1" cellpadding="2" cellspacing="2"&gt; &lt;tbody&gt;  &lt;/tbody&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;cFile&lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Nombre del fichero a descomprimir&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;bBlock&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Code block a ejecutar a medida que se va descomprimiendo&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;lWithPath&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Permitir crear directorios si es necesario&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;cPassWord&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Contraseña a usar para descomprimir el fichero&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;cPath&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Path donde estraer los ficheros&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;cFile | aFiles&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Nombre de un archivo, o array de nombres de archivos a extraer&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;     &lt;/tr&gt;     &lt;tr&gt;       &lt;td style="vertical-align: top;"&gt;pFileProgress&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;       &lt;td style="vertical-align: top;"&gt;Code block para visualizar progreso de los ficheros&lt;br /&gt;&lt;br /&gt;  &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt; &lt;tbody&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Las dos funciones retorman un valor booleano, informandonos si el proceso a concluido con éxito.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Veamos un primer ejemplo sencillo de comprimir / descomprimir.&lt;br /&gt;&lt;img alt="scr1" src="http://www.ea6dd.com/ftp/bielsys/zip/scr1.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Vamos a complicarlo y elaborarlo un poco mas, en el fondo haremos lo mismo, pero con una barra de evolución tanto para comprimir como descomprimir. Simplemente haremos uso de los parametros adicionales que nos permiten ejecutar codeblocks.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/zip/zip.prg"&gt;&lt;img alt="scr2" src="http://www.ea6dd.com/ftp/bielsys/zip/scr2.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como podeis ver en el fuente, hemos creado dos funciones comprime y descomprime, que son muy sencillas de usar. Comprime recibe dos parámetros, nombre del fichero zip que queremos crear, y array (arreglo) con los ficheros que queremos comprimir. Descomprime recibe como único parámetro el nombre del fichero ZIP a descomprimir. &lt;br /&gt;En el interior de cada una de las funciones creamos un dialogo para visualizar la evolución, y montamos e code block necesario para que se vaya actualizando.&lt;br /&gt;Como visteis al principio existen más parámentros en la función HB_ZipFile y Hb_UnZipFile, se trata de que vayais experimentando con ellos y usando los que os hagan falta. Este ejemplo es un ejemplo básico, pero creo que cubre las necesidades más comunes de compresión y descompresión.&lt;br /&gt;&lt;br /&gt;Existen una serie de funciones adicionales para manejo de ficheros Zip, pero os las dejo para que vosotros mismos las investigueis, en descomprime por ejemplo hacemos uso de &lt;span style="font-style:italic;"&gt;hb_GetFilesInZip&lt;/span&gt; ,para determinar el número de archivos contenidos en el fichero comprimido.&lt;br /&gt;&lt;br /&gt;Ya habeis visto que no es nada complicado, si solo quereis comprimir / descompriir, con dos funciones y usando dos parámetros ya lo esta listo. &lt;br /&gt;&lt;br /&gt;El último escollo, pero también importante, es linkar las librerías adecuadas para poder hacer uso de las funciones de manejo de ficheros ZIP.&lt;br /&gt;Las librerias a ñadir a vuestro proyecto son:&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;hbZiparc.lib&lt;br /&gt;hbmzip.lib&lt;br /&gt;hbzlib.lib&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/zip/zip.prg"&gt;Descargar fuentes&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Espero que os sea de utilidad, saludos desde Mallorca.&lt;br /&gt;Biel Maimó&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-2541256302519321195?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/2541256302519321195/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=2541256302519321195' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/2541256302519321195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/2541256302519321195'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2009/08/usando-ficheros-comprimidos-zip-dede.html' title='Usando ficheros comprimidos ZIP desde Harbour.'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-7668933867048425408</id><published>2009-04-06T15:43:00.011+02:00</published><updated>2009-04-06T16:49:26.106+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='fivewin'/><category scheme='http://www.blogger.com/atom/ns#' term='actualizacion'/><category scheme='http://www.blogger.com/atom/ns#' term='Recursos'/><category scheme='http://www.blogger.com/atom/ns#' term='rc'/><category scheme='http://www.blogger.com/atom/ns#' term='res'/><category scheme='http://www.blogger.com/atom/ns#' term='resource'/><title type='text'>Actualización automática de aplicaciones</title><content type='html'>En la entrada anterior publique un sistema para realizar actualizaciones de nuestras aplicaciones via FTP. Hoy seguiremos hablando del tema, y le daremos otra vuelta de tuerca.&lt;br /&gt;&lt;br /&gt;Para actualizar nuestra aplicación usábamos un pequeño programa “ActVer”, que se encargaba de renombrar y lanzar la ejecución de nuestra aplicación.&lt;br /&gt;&lt;br /&gt;Al realizar este programa en [x]Harbour, nos queda de un tamaño bastante considerable teniendo en cuenta lo poco que hace, eso es debido a que como poco cualquier ejecutable Harbour se lleva dentro la maquina virtual. &lt;br /&gt;Para mejorar el tamaño crearemos una versión de ActVer, pero escrita en C, con lo que pasaremos de los 1,46 MB de la versión de harbour a los 16 KB de la versión compilada en C (1,519,616 bytes menos).&lt;br /&gt;&lt;br /&gt;Ademas para no tener que distribuir dos ejecutables, embeberemos ActVer.exe dentro de nuestra aplicación, concretamente en el fichero de recursos, y lo extraeremos solo en el momento que sea necesario actualizar nuestra aplicación.&lt;br /&gt;&lt;br /&gt;El codigo de ActVer.C queda de la siguiente manera.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;#include "stdio.h"&lt;br /&gt;#include "windows.h"&lt;br /&gt;&lt;br /&gt;int main( int argc, char *argv[])&lt;br /&gt;{&lt;br /&gt;    Sleep(700);&lt;br /&gt;    DeleteFile( argv[1]);&lt;br /&gt;    rename( "tmp.exe",argv[1]);&lt;br /&gt;    WinExec(argv[1],1);&lt;br /&gt;    return EXIT_SUCCESS;&lt;br /&gt;}&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Ahora vamos a insertarlo dentro de nuestra aplicación, para ello añadimos la siguiente linea en nuestro fichero de recursos, xxxxx.RC &lt;br /&gt;&lt;br /&gt;ACTVER RCDATA "ActVer.exe"&lt;br /&gt;&lt;br /&gt;RCDATA nos permite insertar directamente datos binarios en nuestro ejecutable (graficos, otros exe, …)&lt;br /&gt;&lt;br /&gt;Con esta linea, la siguiente vez que compilemos nuestra aplicación, actver quedara incrustado dentro de nuestro programa, ahora solo nos hace falta el poder extraerlo, cosa que haremos con el siguiente código (también en c).&lt;br /&gt;&lt;br /&gt;Insertamos el código de la función en c, en nuestro fuente prg Harbour.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;#pragma BEGINDUMP&lt;br /&gt;#include "Windows.h"&lt;br /&gt;#include "hbApi.h"&lt;br /&gt;HB_FUNC( RESTOFILE )&lt;br /&gt;{&lt;br /&gt;   HRSRC res=FindResource(NULL,"ACTVER",RT_RCDATA);&lt;br /&gt;   LPDWORD bytesWritten;&lt;br /&gt;   int size=SizeofResource(NULL,res);&lt;br /&gt;   HGLOBAL hRes=LoadResource(NULL,res);&lt;br /&gt;   unsigned char *pRes=(unsigned char *)LockResource(hRes);&lt;br /&gt;   HANDLE hFile=CreateFile("ACTVER.EXE",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);&lt;br /&gt;   WriteFile(hFile,pRes,size,&amp;bytesWritten,NULL);&lt;br /&gt;   CloseHandle(hFile);&lt;br /&gt;}&lt;br /&gt;#pragma ENDDUMP&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Y con esto ya veis que es muy sencillo el incorporar ficheros binarios en nuestro EXE, esta es una posible utilidad, pero seguro que le encontrareis alguna otra.&lt;br /&gt;&lt;br /&gt;Para que el PRG de nuestro anterior hilo incorpore esta funcionalidad, debemos añadir el codigo antes citado, y realizar una llamada a la función ResToFile() en la linea anterior a WinExec.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/updftp2/UpdFtp2.prg"&gt;UpdFtp2.prg&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/updftp2/actver.c"&gt;ActVer.c&lt;/a&gt;&lt;/nresid&gt;&lt;/hinst&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/updftp2/UpdFtp2.zip"&gt;UpdFtp2.zip contiene UpdFtp2.exe&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/updftp2/ActVer.rc"&gt;ActVer.rc&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/updftp2/ActVer.Exe"&gt;ActVer.Exe&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-7668933867048425408?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/7668933867048425408/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=7668933867048425408' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/7668933867048425408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/7668933867048425408'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2009/04/actualizacion-automatica-de.html' title='Actualización automática de aplicaciones'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-6700806759225688810</id><published>2009-02-06T11:03:00.023+01:00</published><updated>2009-02-13T08:41:36.764+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wininet.dll'/><category scheme='http://www.blogger.com/atom/ns#' term='Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='xBase'/><category scheme='http://www.blogger.com/atom/ns#' term='fivewin'/><category scheme='http://www.blogger.com/atom/ns#' term='actualizacion'/><category scheme='http://www.blogger.com/atom/ns#' term='tInternet'/><category scheme='http://www.blogger.com/atom/ns#' term='tFtp'/><category scheme='http://www.blogger.com/atom/ns#' term='xHarbour'/><title type='text'>Actualización automatica de aplicaciones via FTP</title><content type='html'>&lt;img alt="updftp01" src="http://www.ea6dd.com/ftp/bielsys/uptftp/updftp01.jpg" border="0" /&gt;&lt;br /&gt;En esta entrada del blog vamos a diseñar un sistema para automatizar las actualizaciones de las versiones de nuestros programas.&lt;br /&gt;Para ello, necesitaremos disponer de un servidor FTP. El motivo de usar un servidor FTP, es que nos va a permitir tanto una solución vía intranet como Internet.&lt;br /&gt;&lt;br /&gt;Vamos a explicar la teoría de este sistema, y después iremos con la practica y el código fuente.&lt;br /&gt;&lt;br /&gt;1º Dispondremos de un servidor FTP, en el cual montaremos una estructura de carpetas, donde el nombre de la carpeta, será el de la aplicación, y dentro de esta carpeta alojaremos la última versión de nuestro programa ejecutable.&lt;br /&gt;&lt;br /&gt;2º Especificaremos a nuestro programa, la información necesaria para poderse conectar al servicio FTP( ip, usuario,...), con esa información se conectara, y comprobara la antigüedad del fichero alojado en el servidor, la comparara con él mismo, y si la versión del FTP es más nueva, procedera a la descarga del fichero ejecutable, en un fichero temporal en nuestra unidad local.&lt;br /&gt;&lt;br /&gt;3º Si había actualizaciones para descargar, y la descarga se ha completado con éxito, ejecutaremos otro proceso, que borrara la versión antigua, re nombrara y lanzara su ejecución.&lt;br /&gt;&lt;img alt="updftp01" src="http://www.ea6dd.com/ftp/bielsys/uptftp/updftp02.jpg" border="0" /&gt;&lt;br /&gt;Y con esto ya tendremos actualizado nuestro programa. Viendo la teoría, no parece muy complicado ;-)&lt;br /&gt;&lt;br /&gt;Esta solución, la tengo implementada como parte de una clase (tAppl), que utilizo en todas mis aplicaciones, aquí para poderos poner un ejemplo auto contenido, y no complicarnos explicando la creación de las clases, lo realizaremos con funciones, aunque luego el lector lo podrá adaptar a una clase o de la manera que le parezca mas cómoda para su forma de trabajo.&lt;br /&gt;&lt;br /&gt;Nuestra aplicación, empezara definiendo la dirección del servidor FTP, y la carpeta donde comprobar el fichero a actualizar, seguidamente ejecutaremos la función ChkUpdFtp, y aquí se bifurcara, dependiendo de si hay que actualizar o no.&lt;br /&gt;&lt;img alt="Funcion Main" src="http://www.ea6dd.com/ftp/bielsys/uptftp/src01.jpg" border="0" /&gt;&lt;br /&gt;Veamos ahora la función(ChkUpdFtp) encargada de determinar si existen versiones nuevas de nuestro programa, para ello utilizaremos las clases tInternet y fFtp. &lt;br /&gt;Lo primero que haremos será comprobar si disponemos de los parámetros necesarios para conectarnos, y si existe el programa ActVer(mas adelante veremos su código fuente)  que será el encargado de renombrar y relanzar nuestro programa. Pasado este primer filtro, pasamos a intentar realizar la conexión con el FTP,  si dicha conexión tiene éxito, solo nos resta comprobar las fecha y hora de creación de los archivos y determinar si debe o no actualizarse, en caso de que se deba actualizar llamaremos a la función Actualiza.&lt;br /&gt;&lt;img alt="Funcion Main" src="http://www.ea6dd.com/ftp/bielsys/uptftp/src02.jpg" border="0" /&gt;&lt;br /&gt;En este proceso usamos funciones que no vamos a comentar su funcionamiento, simplemente os incluyo su codigo fuente (prg y C). ( TimeToSec, FileTimes, FileSize ) O bien podeis utilizar alguna alternativa vuestra si en vuestro set de funciones ya las teneis definidas.&lt;br /&gt;&lt;br /&gt;La función actualiza, es la encargada de descargar el nuevo fichero ( GetFile ), y visualizar en pantalla una barra de evolución de la descarga .&lt;br /&gt;&lt;img alt="Funcion Main" src="http://www.ea6dd.com/ftp/bielsys/uptftp/src03.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Al llegar a este punto, si la función Actualiza nos devuelve verdadero, significará que ya tenemos descargado nuestra nueva versión en la carpeta local, solo debemos cerrar la versión actual, e invocar ActVer que se encargará de borrar la versión anterior, y renombrar el fichero que acabos de recibir, y posteriormente ejecutarlo.&lt;br /&gt;&lt;br /&gt;Veamos el sencillo código de ActVer.exe, recibe como parámetro el fichero a actualizar,  borra la versión anterior, renombra y ejecuta.&lt;br /&gt;&lt;img alt="ActVer" src="http://www.ea6dd.com/ftp/bielsys/uptftp/src04.jpg" border="0" /&gt;&lt;br /&gt;Y con esto ya tenemos implementado nuestro sistema de actualizacion via Ftp de nuestras aplicaciones.&lt;br /&gt;Dos cosas importantes a tener en cuenta si vuestro servidor de FTP es LINUX, los nombre de ficheros, en linux son case sensitive, y la hora de creacion del fichero se guarda en UTC.&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/uptftp/updftp.prg"&gt;UpdFtp.prg&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/uptftp/actver.prg"&gt;ActVer.prg&lt;/a&gt;&lt;/nresid&gt;&lt;/hinst&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/uptftp/updftp.zip"&gt;UpdFtp.exe y ActVer.exe&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Nota: me comentan que al compilar con xHarbour falta la función HB_IsChar, simplemente sustituir HB_ISCHAR( cTime ) por ValType(cTime)=='C'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-6700806759225688810?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/6700806759225688810/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=6700806759225688810' title='8 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/6700806759225688810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/6700806759225688810'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2009/02/actualizacion-automatica-de.html' title='Actualización automatica de aplicaciones via FTP'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-8738367447744971757</id><published>2008-11-25T12:20:00.008+01:00</published><updated>2008-11-25T17:21:15.671+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='fivewin'/><category scheme='http://www.blogger.com/atom/ns#' term='SetResources'/><category scheme='http://www.blogger.com/atom/ns#' term='Recursos'/><category scheme='http://www.blogger.com/atom/ns#' term='LoadString'/><category scheme='http://www.blogger.com/atom/ns#' term='GetResources'/><title type='text'>Multi Idioma con [x]Harbour + FiveWin</title><content type='html'>   En esta ocasión vamos a implementar un sistema multi idoma, basado en DLL de recursos. Esto os podrá servir para distribuir vuestras aplicaciones en diferentes países, o en un mismo país con diferentes idiomas. En Baleares al igual que en otras comunidades autonomas  de España, existen dos idiomas cooficiales, Castellano y Catalán. Es habitual, y sobre todo en organismos públicos que soliciten las aplicaciones en multi-idioma, o directamente traducidas al Catalán.&lt;br /&gt;&lt;br /&gt;Para solventar este problema, sin que tengamos que modificar los fuentes de nuestra aplicación, ni debamos mantener varias versiones en paralelo, lo que haremos sera mantener tantas DLL de recursos como idiomas queramos disponer en nuestra aplicación. &lt;br /&gt;&lt;br /&gt;Para ello contaremos con una DLL de recursos vaciá ( &lt;a href="http://www.ea6dd.com/ftp/bielsys/multilng/vacio.dll"&gt;vacio.dll&lt;/a&gt; ), que usaremos como base,  e iremos introduciendo los diálogos, y crearemos un "string table" con los mensajes que utilicemos en nuestra aplicación. (Para editar las DLL usaremos un editor de recurso cualquiera, en nuestro caso el que viene integrado con PellesC)&lt;br /&gt;&lt;img alt="editor de recursos" src="http://www.ea6dd.com/ftp/bielsys/multilng/recursos1.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;La tabla de cadenas tiene un formato parecido al siguiente, un código y su mensaje asociado. Desde nuestro programa iremos recuperando las cadenas de texto por su numero de código.&lt;br /&gt;&lt;img alt="String Table" src="http://www.ea6dd.com/ftp/bielsys/multilng/recursos2.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;La idea es al principio de la aplicación cargar la DLL que queramos según el idioma seleccionado, y automáticamente tendremos los diálogos y cadenas de texto en el idioma deseado.&lt;br /&gt;La carga de la DLL deseada la hacemos mediante la función  SetResources( via de acceso + nombre de fichero.dll), el nombre y la via de acceso puede estar guardada por ejemplo en el registro de windows, un fichero ini, o directamente solicitar la elección del idioma por parte del usuario.&lt;br /&gt;&lt;br /&gt;En su día tuve la idea de usar Shell.Applucattion y las extensión de NTF, para grabar junto a la DLL la descripción del idioma, pero resulto ser un fiasco, debido a que solo funciona con NTF, y en instalaciones con FAT32 no funciona, y ademas al comprimir o hacer paquetes de instalación, se pierde la información adicional de los ficheros, a modo de curiosidad, y para el que quier ver los fuentes y el manejo de Shell.Application, aquí os dejo los &lt;a href="http://www.ea6dd.com/ftp/bielsys/multilng/getlng.prg"&gt;fuentes&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Recapitulando, al iniciar el programa, cargamos la DLL de recusos deseada&lt;br /&gt;Ejemplo:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt; oAppl:cLng:=GetLng() //Funcion que recupera el idioma&lt;br /&gt;SetResources(oAppl:cDirLocal+"Resource\ppcinst"+oAppl:cLng+".dll")&lt;br /&gt;oAppl:hDll:=GetResources()&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Los diálogos, ya los tenemos traducidos directamente en el diseño del recurso.&lt;br /&gt;Para recuperar las cadenas de texto, usaremos la función  LoadString(hDll&lt;hinst&gt;, nResid &lt;nresid&gt;), le debemos pasar dos parametros, el primero es el handler del modulo que contiene las cadenas de texto, y el segundo el codigo de la cadena que quermos cargar.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt; LoadString( oAppl:hDll, 10001 )&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para hacerlo más fácil de leer y manejar, os recomiendo crear un fichero CH para incluir en vuestro programa, a modo de diccionario, donde iremos definiendo un texto mas legible asociado a la función y código de cadena a recuperar.&lt;br /&gt;&lt;br /&gt;&lt;img alt="include" src="http://www.ea6dd.com/ftp/bielsys/multilng/include.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;De esta forma por ejemplo visualizar un mensaje avisando de que la aplicación ya esta en ejecución pasaría de un críptico&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;MsgStop( LoadString( oAppl:hDll, 10001 ) )&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;a&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;MsgStop(TXT_EXERUNNING)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;bastante mas descriptivo.&lt;br /&gt;&lt;br /&gt;Aquí os pongo un pequeño ejemplo para ver el funcionamiento de lo descrito anteriormente.&lt;br /&gt;&lt;img alt="prgmultilng" src="http://www.ea6dd.com/ftp/bielsys/multilng/prgmultilng.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/multilng/multilng.prg"&gt;MultiLng.prg&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/multilng/multilng.zip"&gt;MultiLng.zip&lt;/a&gt;&lt;/nresid&gt;&lt;/hinst&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-8738367447744971757?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/8738367447744971757/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=8738367447744971757' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/8738367447744971757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/8738367447744971757'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/11/multi-idioma-con-xharbour-fivewin.html' title='Multi Idioma con [x]Harbour + FiveWin'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-377199914575224140</id><published>2008-11-21T15:46:00.003+01:00</published><updated>2008-11-21T17:27:45.262+01:00</updated><title type='text'>Un año de vida del Blog</title><content type='html'>Como pasa el tiempo, parece que fue ayer mismo cuando escribí la primera entrada de este blog, y ya ha pasado mas de un año desde esa primera entrada.&lt;br /&gt;&lt;br /&gt;Desgraciadamente, y por falta de tiempo no he podido escribir todo lo a menudo que hubiera deseado, pero el tiempo disponible es finito, y el blog de momento no nos da de comer ;-).&lt;br /&gt;En un primer momento pensaba escribir mucho mas sobre ADO, pero la realidad es que el trabajo es el que marca un poco el rumbo y la tendencia de este blog, y se alimenta de las investigaciones personales que tengo que ir realizando en base a los requerimientos de los proyectos que este desarrollando.&lt;br /&gt;&lt;br /&gt;El tema ADO no queda abandonado, pero si un poco aparcado, de todas formas en este periodo, han ido apareciendo muchos buenos aportes sobre ADO y xBase (ADOBASE, SQLWIN, ...) y en el foro no estamos tan huérfanos de información como antaño.&lt;br /&gt;&lt;br /&gt;En este año, el número de visitas,y comentarios ha ido creciendo progresivamente, aunque no es un volumen bestial, si me alegra el ver que va en aunmento, y ademas cuenta con lectores fieles. Como digo, eso me alegra, y ademas es el motor y el combustible necesario para animarme a seguir escribiendo.&lt;br /&gt;&lt;br /&gt;Pues nada mas, simplemente agradeceros a todos vuestra lectura, comentarios, desear que os haya sido de utilidad, y espero seguir contando con vuestra visitas.&lt;br /&gt;&lt;br /&gt;Un abrazo. Y hasta la proxima entrada, que será muy pronto e ira de multi-idioma con xHarbour y DLL de recursos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-377199914575224140?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/377199914575224140/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=377199914575224140' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/377199914575224140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/377199914575224140'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/11/un-ao-de-vida-del-blog.html' title='Un año de vida del Blog'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-8011568921769670744</id><published>2008-09-10T12:40:00.016+02:00</published><updated>2008-09-10T17:40:14.592+02:00</updated><title type='text'>Reunión xBase en Barcelona</title><content type='html'>A diferencia de todas las entradas previas, esta no os va a aportar ningún código fuente, ni ninguna explicación de como hacer tal cosa,... En este caso esta entrada es puramente bloguera, y para contaros un poco mi vida. Jaja intentare no ser muy pesado;-)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;El mes pasado, y a iniciativa de Carlos Aubia, hicimos una mini reunion en Barcelona. La idea inicial salio de este mismo blog, y del hecho que tanto a Carlos como a mi nos apetecia, conocernos y compartir conocimientos e inquietudes(hasta la fecha solo habíamos cruzado varios mails, y comentarios en los foros).&lt;br /&gt;&lt;br /&gt;Todo fue muy rápido, decidir lugar, buscar ofertas de vuelos para fijar fecha, y listo. Decidí viajar yo, ya que al vivir en Mallorca, tengo derecho a descuentos del 50% en vuelos para paliar el hecho de nuestra insularidad.&lt;br /&gt;&lt;br /&gt;Sobre la marcha pensamos que si nos juntásemos unos cuantos, pues mucho mejor y decidimos invitar a unos pocos amigos.&lt;br /&gt;La verdad que ante lo precipitado de la reunion, no pensabamos que fuese a apuntarse nadie, y tampoco se trataba de hacer una macro convocatoria. Al final los asistentes fuimos Carles Aubia, Carlos Mora, Rafa Carmona, Andres Gonzalez, y el que suscribe.&lt;br /&gt;Lo primero de todo, dar las gracias a nuestro anfitrión (Carles) y a su empresa (Bayer), por poner a nuestra disposición tan magnificas instalaciones.&lt;br /&gt;&lt;img alt="EuroServices Bayer (Sant Joandespi)" src="http://www.ea6dd.com/ftp/bielsys/bcn08/Bayer.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Fuimos llegando a Sant Joandespi, por diferentes medios, mención especial Carlos y Andrés que se pegaron una panzada importante de autobus. A los pies del edificio de Bayer nos conocimos todos, era una situación peculiar, pues todos nos conocíamos por el cyberspacio, pero salvo excepciones, nunca nos habiamos visto en persona. (Carles conoía a Rafa, Rafa a Carles y a Carlos, Andres me conocía a mi).&lt;br /&gt;&lt;br /&gt;Hechas las presentaciones, y acreditaciones, subimos a la sala de reuniones que Carles tenía reservada, y empezamos la reunión. No habíamos fijado un orden, ni unos temas concretos para hablar, puesto que la idea inical era el vernos Carles y yo. La verdad es que para una próxima reunión, quizas sea interesante el preparar un guion y unos temas prefijados.&lt;br /&gt;&lt;br /&gt;Estuvimos hablando de muchísimas cosas, imposible resumirlas en esta entrada. Compartimos las formas de trabajo, como afrontar los problemas en el desarrollo, viendo los desarrollos propios de cada uno, hablando del pasado, del presente, del futuro de xBase, de cual creemos es el camino a seguir,bueno un sin fin de cosas.&lt;br /&gt;&lt;br /&gt;Entre las cosas que vimos, enumero unas cuantas:&lt;br /&gt;&lt;br /&gt;- Entorno de desarrollo, vimos y comentamos el funcionamiento de xMate y de uStudio&lt;br /&gt;&lt;br /&gt;- LetodDB y ADS, letoDB es un tema de moda últimamente, y ADS es un clasico y una realidad para acceso C/S contra DBF, estuvimos haciendo unas pruebas con ADS usando xBrowse contra un servidor remoto en Lisboa.&lt;br /&gt;&lt;br /&gt;- Por supuesto no podía faltar Internet, se comentaron experiencias con SOAP, y una implementación de CGI con xBase.&lt;br /&gt;&lt;br /&gt;- Linux, compilación multiplataforma, gestión de eventos y forma de procesar los mensajes del SO.&lt;br /&gt;&lt;br /&gt;- Control de versiones, uso de  SVN.&lt;br /&gt;&lt;br /&gt;- Pocket PC, conexión vía GPRS y envio de datos via FTP&lt;br /&gt;&lt;br /&gt;- Editor de pantallas, uso de recursos. Diferenntes maneras de afrontar el problema de no tener un IDE, ni un editor de pantallas mas completo en el cual poder asignar mas propiedades a los objetos. &lt;br /&gt;&lt;br /&gt;Y seguro que se me escapan, ya en contactos más individualizados se estuvieron comentando otros cosas, aplicar temas de windows a controles, uso de FreeImage, capturar métodos y propiedades de componentes ActiveX, WMI, ...&lt;br /&gt;&lt;img alt="Meeting Room" src="http://www.ea6dd.com/ftp/bielsys/bcn08/foto6.jpg" border="0" /&gt;&lt;br /&gt;&lt;em&gt;De izq a drch, de pie Carles Abuia, Rafa Carmona"thefull", Andrés Gonzalez, sentados yo mismo, Carlos Mora.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;De la reunión saque algunas conclusiones:&lt;br /&gt;&lt;br /&gt;- Que la gente tiene ganas de hacer reuniones, charlar, compartir, ver lo que hacen el resto con las mismas herramientas. Tenemos la intención firme de montar una reunion nacional de usuarios, posiblemente en Madrid, de ello ya informaremos cuando lo tengamos perfilado.&lt;br /&gt;&lt;br /&gt;- Que aunque el grupo de usuarios de xBase esta más bien en declive, sigue habiendo grandes profesionales trabajando en este entorno, y me siento afortunado de haber podido conocer y compartir un dia con unos cuantos craks de este entorno.&lt;br /&gt;&lt;br /&gt;- Todos trabajamos con la librería FiveWin, aunque también casi todos, hemos probado o probamos otras GUI existentes (vease Xailer, MiniGui, ...), es un sentimiento común que aunque no nos es estrictamente necesario, un IDE le vendria muy bien.&lt;br /&gt;&lt;br /&gt;-Esto no es una conclusión, más bien dudas, hacia donde ira Harbour cuando el objetivo incial de compatibilidad y estabilidad esten cumplidos. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Y eso es todo, no quiero alargarme más, pues todo un día de reunión da mucho de si. &lt;br /&gt;&lt;img alt="Fin reunion" src="http://www.ea6dd.com/ftp/bielsys/bcn08/foto9.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Espero veros a todos en la próxima reunión, que se celebrará ... (pendiente fecha y luggar)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-8011568921769670744?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/8011568921769670744/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=8011568921769670744' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/8011568921769670744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/8011568921769670744'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/09/reunin-xbase-en-barcelona.html' title='Reunión xBase en Barcelona'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-83160730947084855</id><published>2008-07-08T11:09:00.018+02:00</published><updated>2008-07-18T07:54:14.235+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='xBase'/><category scheme='http://www.blogger.com/atom/ns#' term='Letodb'/><category scheme='http://www.blogger.com/atom/ns#' term='cliente servidor'/><category scheme='http://www.blogger.com/atom/ns#' term='dbf'/><category scheme='http://www.blogger.com/atom/ns#' term='xHarbour'/><title type='text'>LetoDB (RDD cliente servidor para [x]Harbour)</title><content type='html'>Hasta ahora la mayoría de entradas de este bloc, hacen referencia al acceso a datos mediante el uso de ADO, como alternativa al uso clásico de los ficheros DBF.&lt;br /&gt;&lt;img alt="LetoDB" src="http://www.ea6dd.com/ftp/bielsys/letodb1/letodb.jpg" border="0" /&gt;&lt;br /&gt; En esta nueva entrada, nos vamos a quedar en medio de la dos tecnologías, y hablaremos de un proyecto Open Source creado por Alexander S. Kresin,  llamado LetoDB. &lt;br /&gt;&lt;br /&gt; LetoDB, es un servidor de base de datos multi plataforma(Windows y Linux), escrito en Harbour y que nos permite trabajar con ficheros DBF e indices CDX o NTX. Se implementa como un RDD de harbour, y por tanto la forma de usarlo es prácticamente igual que usar DBFs de toda la vida, solo nos harán falta unas pocas instrucciones para realizar la conexión al servidor. &lt;br /&gt; &lt;br /&gt; LetodDB se divide en dos partes fundamentales, el servidor (letodb.exe) y la parte cliente (rddleto.lib). También se incluye un programa de consola, que nos permite monitorizar el estado del servidor.&lt;br /&gt; Aunque el tema es amplio y habría mucho que comentar sobre la implementación del servidor, el uso de multihilos, etc, como siempre intentare ser eminentemente práctico, y que de una manera rápida y senciilla podáis probar ester servidor, y si os interesa el tema vosotros mismos podréis ir profundizando.&lt;br /&gt;&lt;br /&gt; Para empezar nuestras pruebas, deberemos descargarnos una serie de archivos, aunque os los podéis descargar de sourceforge (&lt;a href="http://sourceforge.net/projects/letodb/"&gt;http://sourceforge.net/projects/letodb/&lt;/a&gt; ) y compilarlos con la version que deseeis, aquí os pongo un  enlace para que os podeis descargar un fichero en el que ya estan los ejecutables y la librería listas para usar.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/letodb1/letodb.zip"&gt;Descargar letodb.zip&lt;/a&gt;&lt;br /&gt;Este archivo contiene lo siguiente&lt;br /&gt;Letodb.exe -&gt;Ejecutable del servidor&lt;br /&gt;rddleto.lib -&gt; RDD  (compilado con Harbour 1.0.0RC1(Rev.8835) )&lt;br /&gt;manage.exe -&gt; Consola del servidor.&lt;br /&gt;Una vez tengamos descargado este archivo, podemos crear una carpeta (C:\letoDB por ejemplo), y descomprimimos letodb.zip.&lt;br /&gt;&lt;br /&gt;El servidor de LetoDB, por defecto trabaja sobre el puerto 2812, y el path por defecto es c:\, estos parametros pueden ser modificados mediante el uso del fichero letodb.ini, si no existe este fichero, se utilizaran los valores por defecto, y si existe los tomara del fichero. Debe crearse en la misma carpeta donde se encuentra ubicado letodb.exe.&lt;br /&gt;Ejemplo letodb.ini&lt;br /&gt;&lt;br /&gt;Port = 2812&lt;br /&gt;DataPath =c:/letodb&lt;br /&gt;Logfile = "letodb.log"&lt;br /&gt;Default_Driver = CDX&lt;br /&gt;&lt;br /&gt;Para arranncar el servidor, simplemente ejecutaremos letodb.exe, el servidor no tiene ventana asociada, y solo nos arrancara un proceso en nuestro sistema. Para detener el servidor, ejecutaremos el “letodb stop”. &lt;br /&gt;&lt;img alt="Administrador de tareas" src="http://www.ea6dd.com/ftp/bielsys/letodb1/admintar.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Ahora ya podemos arrancar la utilidad de consola, que nos va a permitir monitorizar nuestro servidor. Para conectarnos al servidor, debemos especificar la IP donde esta letoDb ejecutandos, el port que usamos y pulsar sobre el boton Go. Si lo estamos ejecutando en local sobre nuestro PC, en la dirección pondremos 127.0.0.1 o bien localhost. &lt;img alt="consola LetoDB" src="http://www.ea6dd.com/ftp/bielsys/letodb1/mng1.jpg" border="0" /&gt;&lt;br /&gt;El tercer campo que por defecto tien 2 como valor, son los segundos que tarda en refrescar la información.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Una vez hemos pulsado GO, dispondremos de tres vistas, que podremos ir cambiando pulsando los botones Main, Users, Tables. La información de cada una de estas pantallas es autoexplicativa, en la primera información general del servidor, en Users veremos los usuarios y procedimientos conectados, y en  Tables veremos cada proceso con los ficheros que tiene abiertos.&lt;br /&gt; &lt;img alt="consola Tables" src="http://www.ea6dd.com/ftp/bielsys/letodb1/mng2.jpg" border="0" /&gt;&lt;br /&gt;A estas alturas ya estamos listos para escribir el código fuente que nos permita conectar con el servidor letoDB, y realizar nuestras primeras operaciones cliente servidor usando ficheros DBF.&lt;br /&gt;&lt;br /&gt;El código fuente es el siguiente, y para que funcione tenéis que linkarlo junto con RddLeto.lib, y por supuesto el servidor debe de estar ejecutándose.&lt;br /&gt;&lt;br /&gt;&lt;img alt="Source" src="http://www.ea6dd.com/ftp/bielsys/letodb1/src1.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Como podeis apreciar prácticamente todo son comandos estándar de harbour, el único comando no estándar es el que nos comprueba si tenemos conexión con el servidor, el resto son todos nativos de Harbour. &lt;br /&gt;Observar también que debemos definir la dirección IP y el puerto que uso nuestro servidor LetodDB.&lt;br /&gt;El ejemplo es muy sencillo, todo el código esta comentado y creo que se entiende perfectamente. &lt;br /&gt;Ademas de los visto, letoDB incorpora otras funciones adicionales, pero que ya podréis descubriendo si os interesa este sistema cliente servidor, entre las cosas destacadas comentaros que incorpora control de transaccional ( leto_BeginTransaction(), leto_Rollback(), leto_CommitTransaction()), y que el autor tiene pensado en un futuro implementar procesos almacenados que estarán escritos en Harbour.&lt;br /&gt;&lt;br /&gt;Desde aqui podeis descargar el código fuente, y el ejecutable.&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/letodb1/letosample.zip"&gt;Descargar ejecutable&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/letodb1/source.zip"&gt;Descargar código fuente&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/letodb1/letodb.zip"&gt;Descargar letodb.zip&lt;/a&gt;&lt;br /&gt;Podréis encontrar más información sobre letoDB, y descargaros el proyecto completo con su código fuente en sourceforge (&lt;a href="http://sourceforge.net/projects/letodb/"&gt;http://sourceforge.net/projects/letodb/&lt;/a&gt; )&lt;br /&gt;&lt;br /&gt;Ya que son varios los que me lo habeis pedido, aqui os pongo un fichero .bat y .bc para que podais construir la libreria y el ejecutable del servidor con Harbour(1.0.0RC1)y Borland C 5.5, para versiones anteriores de Harbour no vale, ya que se han  renombrado las libreriras. Estos ficheros asumen el compilador de C en C:\Borland\bcc55\bin y Harbour en c:\harbour. Si los tienes así, copia estos dos archhivos en la carpeta donde te has descargado letoDB(desde sourcefourge)y basta con ejecutar make_b6  desde la linea de comandos(Si quieres asegurarte de limpiar copias antiguas, ejecuta primero make_b6 clean). &lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/letodb1/make_b6.bat"&gt;Descargar make_b6.bat&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/letodb1/makefileb6.bc"&gt;Descargar makefileb6.bc&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gracias a Alex  Kresin, y a todos los que han contribuido en el desarrollo de LetoDB, que nos brinda otra alternativa de acceso a datos para el mundo xBase.&lt;br /&gt;&lt;br /&gt;Saludos desde Mallorca.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-83160730947084855?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/83160730947084855/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=83160730947084855' title='22 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/83160730947084855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/83160730947084855'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/07/letodb-rdd-cliente-servidor-para.html' title='LetoDB (RDD cliente servidor para [x]Harbour)'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-3253305788908990698</id><published>2008-06-18T18:31:00.012+02:00</published><updated>2008-06-19T17:46:33.545+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='CabWiz'/><category scheme='http://www.blogger.com/atom/ns#' term='Ezsetup'/><category scheme='http://www.blogger.com/atom/ns#' term='PocketPc'/><title type='text'>Instalador para Pocket PC</title><content type='html'>&lt;a href="http://www.blogger.com/www.ea6dd.com/ftp/bielsys/ppcinst/ppcinst1.jpg"&gt;&lt;/a&gt;&lt;br /&gt;Hasta la fecha las instalaciones de nuestras aplicaciones para PDA, las esta haciendo de una manera bastante rudimentaria y manual.&lt;br /&gt;Estuve buscando por la red algún buen programa de instalación y que ademas fuera gratuito. No encontrando un software que me satisfaciera al cien por cien, recorde que habia leido en algun post del foro de FiveWin, como hacer ficheros de instalacion para PDA, usando CabWiz y EzSetup (ambos freeware).&lt;br /&gt;&lt;br /&gt;Busque y encontre toda la documentación necesaria, parte en el foro de FiveWin (gracias a Pawel y Carles Aubia), y otra en el MSDN.&lt;br /&gt;&lt;br /&gt;Aunque CabWiz y EzSetup funcionaban bien, la verda es que era algo engorroso el crear las instalaciones. Y aqui empezo este proyecto, se trataba de tener un gestor de scripts de instalación basados sobre CabWiz y EzSetup, pero que ademas fuese sencillo de manejar.&lt;br /&gt;&lt;img alt="Biel6 PPCist" src="http://www.ea6dd.com/ftp/bielsys/ppcinst/ppcinst1.jpg" border="0" /&gt;&lt;br /&gt;Y este el resultado final del instalador, aunque seguro que mejorable en muchos aspectos, para mi cubre las necesidades basicas de instalador.&lt;br /&gt;El funcionamiento es muy sencillo e intuitivo, tenemos los siguientes campos&lt;br /&gt;&lt;strong&gt;Proyecto&lt;/strong&gt;: Es el nombre con el que se guardara el proyecto&lt;br /&gt;&lt;strong&gt;Fichero ejecutable:&lt;/strong&gt;  Es la via de acceso y el nombre del fichero exe de la aplicacion que queremos general el setup.&lt;br /&gt;&lt;strong&gt;Carpeta de datos:&lt;/strong&gt; Es la carpeta que contienes los datos de nuestra aplicación, esta carpeta se creara con el nombre \DATOS y colgara de la carpeta de la aplicación(por ahora no es configurable). Todos los archivos que se encuentren en la ruta se copiaran.&lt;br /&gt;&lt;strong&gt;Proveedor : &lt;/strong&gt;Nombre de nuestara empresa&lt;br /&gt;&lt;strong&gt;Nombre Aplicacion :&lt;/strong&gt; eso&lt;br /&gt;&lt;br /&gt;En la PDA nuestra aplicacion se instalara en la carpeta cuyo nombre sera la concatenacion de Proveedor + Nombre Aplicacion&lt;br /&gt;&lt;br /&gt;Ahora tenemos cinco pestañas.&lt;br /&gt;1&lt;strong&gt;.- Readme&lt;/strong&gt;, texto que aparecera en la primera pantalla del setup&lt;br /&gt;&lt;strong&gt;2.- Eula&lt;/strong&gt;, condiciones de licencia de nuestro software, aparece en la segunda pantalla del setup, y debe aceptarse.&lt;br /&gt;&lt;strong&gt;3.- Carpeta Comun&lt;/strong&gt;, aqui estara nuestro fichero ejecutable, y podemos añadir otros ficheros manualmente.&lt;br /&gt;&lt;strong&gt;4.- Carpeta datos&lt;/strong&gt;, es solo lectura, y veremos que archivos seran copiados en la carpeta datos.&lt;br /&gt;&lt;strong&gt;5.-My Documents&lt;/strong&gt;, Nos permite añadir manualmente archivos que serán copiados en My documents de la PDA.&lt;br /&gt;&lt;br /&gt;Los botones de la barra por orden de aparicion :&lt;br /&gt;Nuevo,Recuperar un proyecto guardado, guardar proyecto actual, generar instalación, salir.&lt;br /&gt;&lt;br /&gt;Cuando puslamos sobre el boton generar instlación, obtendremos como resultado el fichero setup.exe que es el que deberemos ejecutar en nuestro pc con el terminal conectado mediante ActiveSync, e instalara nuestra aplicacion en el Pocket PC. &lt;br /&gt;&lt;img alt="Biel6 PPCist" src="http://www.ea6dd.com/ftp/bielsys/ppcinst/ppcinst2.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;Y con esto creo que esta casi todo explicado, aqui está el link para descargarel programa.&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/ppcinst/setup.exe"&gt;Descargar Setup.exe&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para los usuarios de Windows vista debeis istalar "Centro de dispositivos de Windows Mobile" que viene a ser el sustituto de ActiveSync, lo podeis descargar desde la página de Mircosoft.&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=46F72DF1-E46A-4A5F-A791-09F07AAA1914&amp;displaylang=es"&gt;Centro de dispositivos de Windows Mobile 6.1 para Windows Vista (32-bits)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Espero que os pueda ser util. &lt;br /&gt;Saludos, y hasta la proxima.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-3253305788908990698?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/3253305788908990698/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=3253305788908990698' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/3253305788908990698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/3253305788908990698'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/06/instalador-para-pocket-pc.html' title='Instalador para Pocket PC'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-3958893468764339364</id><published>2008-04-25T12:19:00.010+02:00</published><updated>2008-09-06T10:17:23.080+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='find'/><category scheme='http://www.blogger.com/atom/ns#' term='ADO'/><category scheme='http://www.blogger.com/atom/ns#' term='xBrowse'/><category scheme='http://www.blogger.com/atom/ns#' term='sort'/><title type='text'>Usando origenes de datos ADO y 2</title><content type='html'>Desde febreo no públicaba nada en el blog, y es que el trabajo estos últimos meses ha sido más intenso.&lt;br /&gt;Para esta segunda entrega tenia pensado implemenar al ejemplo que hizcimos en la entrada anterior, autosort por columnas, y busqueda incremental para la descripción.&lt;br /&gt;&lt;br /&gt;El tema del autosort, en la versión actual de FiveWin, xBrowse ya lo incluye nativamente, ademas de DATAS para el manejo del orden, con lo que en realidad no nos sera muy util si estamos usando FiveWin actualizado, y será meramente educativo, aunque si estais en versiones antiguas de FiveWin os permitira implementar esa funcionalidad.&lt;br /&gt;&lt;br /&gt;Para hacer las ordenacines de campos y las busquedas, utilizaremos el Data &lt;strong&gt;Sort&lt;/strong&gt; y el metodo &lt;strong&gt;Find&lt;/strong&gt; del obbjeto RecordSet. El ámbito, serán los registro que formen parte de nuestra consulta SQL, y tiene como ventaja que no genera trafico con el servidor(con una sentenica SQL podriamos conseguir el mimsmo resultado, pero cargariamos proceso al servidor y generariamos tráfico en la red). &lt;br /&gt;&lt;br /&gt;El data &lt;strong&gt;Sort&lt;/strong&gt; ordena uno o varios campos del Recordset de forma ascendente o descendente. Para ello debemos asignar una cadena a esta propiedad con el nombre o nombres de los campos a ordenar, separados por comas e indicar el modo de ordenación mediante las palabras claves ASC o DESC.&lt;br /&gt;&lt;strong&gt;oRs:Sort:="CliDes ASC"&lt;/strong&gt;&lt;br /&gt;&lt;em&gt;Ordenado por el campo CliDes de forma ascendente.&lt;/em&gt;&lt;br /&gt;El metodo &lt;strong&gt;Find&lt;/strong&gt; busca un registro en función de un criterio. Si el criterio se cumple, el registro localilzado pasa a ser el actual, en caso contrario el Recordset se sitúa al final. &lt;br /&gt;Su sintaxys:&lt;br /&gt;&lt;em&gt;oRs:Find( cCriterio, SkipRecords, DireccionBusqueda, Start )&lt;/em&gt; &lt;br /&gt;En el criterio no puede usarse OR ni AND, y solo puede aparecer uno de los siguientes operardores =   &gt;   &gt;=   &lt;   &lt;=   &lt;&gt;   LIKE .&lt;br /&gt;&lt;br /&gt;Pasemos a la acción, vamos a usar practicamente el mismo código que en la entrada anterior, con algunos añadidos.&lt;br /&gt;En la parte donde creamos el fichero MDB, y lo rellenamos con datos de prueba, el campo descripción lo rellenaremos con valores alfabéticos aleatorios para poder probar las busquedas incrementales.&lt;br /&gt; &lt;strong&gt;FOR x:=1 TO 20&lt;br /&gt; cCliDes+=Chr(HB_RandomInt(65,70))&lt;br /&gt; NEXT&lt;br /&gt; oRs:Fields("CliDes"):Value:=cCliDes&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Para poder realizar la busqueda incremental, necesitamos un objeto SAY, y una funcion que realice la busqueda y nos devuelva verdadero o falso según el resultado de la busqueda.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt; oBar := TBar():New(oWndVerMdb,50,45,.T.)&lt;br /&gt; @ 01,10 SAY oSay PROMPT '' SIZE 90,20 OF oBar&lt;/strong&gt;&lt;br /&gt;Creamos una barra, y dentro de la barra colocamos el SAY que visualizara la cadena que estamos buscando.&lt;br /&gt;&lt;br /&gt;Y ahora le indicamos al browse el objeto SAY y la funcion que procesara la busqueda.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;oBrw:bSeek        := { | c | Busca(c,oRs) }&lt;br /&gt;oBrw:oSeek        := oSay&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Y la función encargada de realizar la busqueda es la siguiente.&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo2/Source.zip"&gt;&lt;img alt="Funcion para busqueda" src="http://www.ea6dd.com/ftp/bielsys/adodemo2/busca.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;La función recibe dos parámetros, la cadeana a buscar, y el objeto recordset(podriamos mejorar la función y pasarle como parametro el campo sobre el que queremos hacer la busqueda). Montamos la cadena de busqueda dependiendo de si es el primer caracter tecleado o no, y se lo pasamos al recordset. Buscamos en el campo CliDes que empiece por la cadena que recibimos como parametro mas cualquier otra cosa( LIKE "cadean busqueda"+"*").&lt;br /&gt;Si no es inicio o final de fichero significa que hemos encontrado un regitro, y devolvemos verdadero. &lt;br /&gt; &lt;br /&gt;Con esto ya tenemos implementada la busqueda incremental en el browse. &lt;br /&gt;&lt;br /&gt;Pasemos ahora a añadire la opcion de ordenar los registros cuando pulsamos sobre la cabecera de la columna.&lt;br /&gt;&lt;br /&gt;Despuese de la instruccion SetAdo(), añadimos la siguiente linea, donde le indicamos un codeblock a ejecutar cuando se pulsa con el raton en la cabecera.&lt;br /&gt;&lt;strong&gt;AEval(oBrw:aCols,{|oCol|oCol:bLClickHeader:={|f,c,h,oCol|Ordena(oBrw,oRs,oCol)}})&lt;/strong&gt;&lt;br /&gt;Y la fucion encargada de controlar el orden es la siguiente&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo2/Source.zip"&gt;&lt;img alt="Funcion para sort" src="http://www.ea6dd.com/ftp/bielsys/adodemo2/ordena.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;En esta función casi nos lleva mas trabajo el ir colocando el BMP de la flecha arriba abajo, que realizar la ordenación. Si no visualizamos el BMP Ordena quedaria reducido de la siguiente manera:&lt;br /&gt;&lt;strong&gt;STATIC FUNCTION Ordena(oBrw,oRs,oCol,cFld)&lt;br /&gt;   LOCAL cSort:=oRs:Sort,nLen,nFor&lt;br /&gt;   oRs:Sort:=cFld+IF(At(cFld,cSort)&gt;0,IF(At('ASC',cSort)&gt;0,' DESC',' ASC'),' ASC')&lt;br /&gt;   oRs:Sort:=cFld+Space(1)+oCol:cOrder&lt;br /&gt;   oBrw:GoTop()&lt;br /&gt;RETURN NIL&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;La funcion VerMdb, con las lineas que hemos añadido para la busqueda y la ordenación de columnas, queda de la siguiente manera:&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo2/Source.zip"&gt;&lt;img alt="VerMdb" src="http://www.ea6dd.com/ftp/bielsys/adodemo2/VerMdb.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Desde aqui podeis descargar el código fuente, y el ejecutable.&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo2/Demo.zip"&gt;Descargar ejecutable&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo2/Source.zip"&gt;Descargar código fuente&lt;/a&gt;&lt;br /&gt;Como siempre, espero que os haya resultado amena la lectura, y ademas os pueda ser de utilidad. &lt;br /&gt;Saludos desde Mallorca.&lt;br /&gt;(ADO RecordSet Harbour xHarbour FiveWin oRs.Find oRs.Sort)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-3958893468764339364?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/3958893468764339364/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=3958893468764339364' title='14 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/3958893468764339364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/3958893468764339364'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/04/usando-origenes-de-datos-ado-y-2.html' title='Usando origenes de datos ADO y 2'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-1956052116393441246</id><published>2008-02-18T16:52:00.012+01:00</published><updated>2008-02-19T09:23:59.813+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ADO'/><category scheme='http://www.blogger.com/atom/ns#' term='xBrowse'/><category scheme='http://www.blogger.com/atom/ns#' term='ADOX'/><title type='text'>Usando origenes de datos ADO 1</title><content type='html'>En esta entrada, voy a incluir un ejemplo autocontenido en el que vamos a abrir un origen de datos via ADO, y visualizaremos su contenido en una rejilla (xBrowse).&lt;br /&gt;Para tal efecto, y para que no sea requerimiento tener algun servidor instalado, utilizaremos un fichero MDB (Microsoft Access), dicha base de datos la crearemos dinamicamente desde nuestro código, haciendo uso de los componentes ADOX (Active Data Objects Extension).&lt;br /&gt;Para que fucnione, debemos tener instalado en nuestro ordenador el proveedor de datos Microsoft.Jet.OLEDB.4&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo1/Demo.zip"&gt;Descargar ejecutable&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo1/Source.zip"&gt;Descargar código fuente&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Este programa consta de dos partes, la primera parte donde creamos la base de datos, la tabla, y rellenamos con datos de prueba, que corresponde la siguiente porción de código, la cual no creo que haga falta comentar, puesto que con la lectura y los comentario en el propio código fuente, es autoexplicativo.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo1/Source.zip"&gt;&lt;img alt="Creando la base de datos Demo.mdb" src="http://www.ea6dd.com/ftp/bielsys/adodemo1/scr1.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Como podeis ver creamos un catalogo, despues una tabla, añadimos campos a la tabla, definimos la clave primaria, y finalmente añadimos la tabla al catálogo. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo1/Source.zip"&gt;&lt;img alt="Rellenando con datos de prueba" src="http://www.ea6dd.com/ftp/bielsys/adodemo1/scr2.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;En esta segunda funcion, definimos un objeto connection, creamos un recordset, definimos CursorLocation del lado del cliente (salvo contadas excepciones, siempre los definiremos del lado del cliente), tipo de cursor Dinamico (aqui si que tendremos más juego dependiendo de las operaciones que queramos realizar con los datos), tipo de bloqueo (en este caso optimista), le indicamos cual es el objeto connection que debe usar, y la sentencia SQL a ejecutar.&lt;br /&gt;Una vez abierto, mediante un bucle FOR ... NEXT vamos creando registros de prueba.&lt;br /&gt; &lt;br /&gt;    Cuando ya tenemos creado nuestra base de datos access, lo único que nos resta es visualizar los registros que le hemos incorporado.&lt;br /&gt;Con muy pocas instrucciones podemos ver en pantalla todos los registros, en esta primera entrega, solo visualizaremos los registros no haremos ninguna funcion de mantenimiento, si bien en la fucnion CrtTstDat, ya podeis ver como funciona la mecánica para añadir registros.&lt;br /&gt;&lt;br /&gt;En la función VerMdb, recuperamos todos los datos contenidos en la tabla Cliente, y los visualizamos en un Browse. Con solo diez lineas es suficiente, y eso en parte es gracias al uso del metodo SetAdo(aportación personal donada a FiveTech) de la clase xBrowse que nos crea las columnas y nos configura los codeblock de movimiento (bGoTop, bGoBottom, bSkip, ... )&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ea6dd.com/ftp/bielsys/adodemo1/Source.zip"&gt;&lt;img alt="Visualizar Tabla en rejilla" src="http://www.ea6dd.com/ftp/bielsys/adodemo1/scr3.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Espero que os sea de utilidad, espero vuestros comentarios.&lt;br /&gt;Saludos.&lt;br /&gt;&lt;br /&gt;(ADOX:Catalog ADOX:Table ADOX:Key ADODDB:Connection ADODB:RecordSet tXBrowse SetAdo )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-1956052116393441246?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/1956052116393441246/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=1956052116393441246' title='10 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1956052116393441246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1956052116393441246'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/02/usando-origenes-de-datos-ado-1.html' title='Usando origenes de datos ADO 1'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-1737451896279114774</id><published>2008-01-17T16:13:00.005+01:00</published><updated>2008-05-09T12:09:39.240+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tSplitter'/><category scheme='http://www.blogger.com/atom/ns#' term='TreeView'/><category scheme='http://www.blogger.com/atom/ns#' term='xBrowse'/><title type='text'>TreeView con xBrowse</title><content type='html'>Aunque muchas aplicaciones usan la visualizacion tipo arbol, la verdad es que hasta la fecha nunca lo habia usado en mis programas.&lt;br /&gt;Esta vez tenia muy claro el resultado que queria obtener, pero ni idea de como llegar hasta el.&lt;br /&gt;Queria visualizar un plan de cuentas, con una estructra arbolada a la izquierda y una rejilla con las cuentas a la derecha.&lt;br /&gt;&lt;a href="http://www.ea6dd.com"&gt;&lt;img alt="Tree plan de cuentas" src="http://www.ea6dd.com/ftp/bielsys/treeplactas.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Este es el resultado final, y es justo como deseaba que quedase ;-).&lt;br /&gt;La tabla cta esta formada por los siguientes atributos:&lt;br /&gt;CTA Caracter 8&lt;br /&gt;NOM Caracter 45&lt;br /&gt;&lt;a href="http://imageshack.us/"&gt;&lt;img alt="Image Hosted by ImageShack.us" src="http://img139.imageshack.us/img139/463/tree2eu4.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Y los registros están grabados tal cual se ve en la imagen superior.&lt;br /&gt;&lt;br /&gt;Para conseguir nuestro proposito usaremos un splitter vertical, colocando un objeto TreeView a la izquierda y un xBrowse a la derecha.&lt;br /&gt;Creamos el objeto oTree del tipo TreeView&lt;br /&gt;&lt;strong&gt;oTree:=TTreeView():New(0,0,oWnd,,,,,300)&lt;/strong&gt;&lt;br /&gt;y lo procedmos a rellenearlo con los datos que deseamos, para ello llamos a la función AddMayor, pasandole como parametro el propio objeto oTree, y un array vacio(paso el array desde esta funcion para poder darle algun tipo de uso futuro, ahora mismo no lo uso para nada, y podriamos prescindir de pasar el arraym y crearlo como una variable local en la función AddMayor).&lt;br /&gt;&lt;a href="http://imageshack.us/"&gt;&lt;img alt="Image Hosted by ImageShack.us" src="http://img233.imageshack.us/img233/3779/tree3tr7.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;En esta función uso un indice condicional 'mayor', que solo contiene las cuentas de mayor y no las subcuentas. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Lo que hago es recorrer todo el fichero, e ir agregando nodos al objeto oTree, la forma de agregar varia si estamos en el nodo raiz, o añadimos a uno ya existente. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Si la longitud del contenido del campo cta es 1, estamos en el nodo raiz, añadimos el elemento con el metodo Add del objeto oTree, que devuelve otro objeto del tipo tvItem.&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;oTree:Add(AllTrim(Cta-&gt;Cta)+' '+Cta-&gt;Nom)&lt;br /&gt;&lt;/strong&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;&lt;span style="font-size:100%;"&gt;Mientras que si no estamos en el nodo raiz(long. cta&gt;1), lo que hacemos es utilizar el metodo Add, pero del objeto tvItem correspondiente&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;Buscamos en el array el item que corresponde al valor de cta actaul menos una posicion, y si le añadimos el nuevo elemento con la siguiente instrucción.&lt;br /&gt;&lt;strong&gt;aItems[nPos,2]:Add(AllTrim(Cta-&gt;Cta)+' '+Cta-&gt;Nom,,AllTrim(Cta-&gt;Cta))&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A medida que voy creando los nodos, guardo el objeto tvItem y el valor de Cta en un array. Este array lo utilizo para posicionarme en el nodo correcto mediante la funcion Ascan. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Si os fijais en cada elemento de cada nodo del objeto tree es un objeto tvItem, el objeto tvItem dispone de un data llamado cargo (presente en muchos otros objetos) que esta diseñado para guardar cualquier dato que quiera el programador, en nuestro caso, grabamos el valor del campo Cta, y nos va a servir para hacer un Scope en el browse, a medida que nos vayamos desplazando por el arbol. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;&lt;span style="font-size:100%;"&gt;Para conseguirlo usamos el data bChanged, en el cual colocamos un codeblock que sera evaluado cada vez que haya un cambio en el objeto oTree&lt;/span&gt;, &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.piema.info/"&gt;&lt;img alt="CodeBlock bChanged" src="http://www.ea6dd.com/ftp/bielsys/otreebchg.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Este CodeBlock, recupera el elemento seleccionado del oTree, comprueba que no este vacio el Data Cargo, aplica el scope a la tabla, reposiciona y refresca el objeto browse.&lt;br /&gt;&lt;br /&gt;El resto de trabajo que nos queda es definer el browse y el spliter, que supongo que todos ya sabreis perfectamente como hacerlo.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://imageshack.us/"&gt;&lt;img alt="Image Hosted by ImageShack.us" src="http://img215.imageshack.us/img215/7246/tree5fr6.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Es importante el data nLeft del objeto browse para que quede a la derecha del splitter, y el codeblock bResized de la ventana, para que se reajuste el splitter si cambia el tamaño de la venana.&lt;br /&gt;&lt;br /&gt;Espero que os haya gustado la lectura, y os pueda ser de utilidad, todos los comentarios son bienvenidos.&lt;br /&gt;&lt;br /&gt;(tTreeView tVItem tXBrowse oTree:bChanged SetRDD )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-1737451896279114774?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/1737451896279114774/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=1737451896279114774' title='9 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1737451896279114774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1737451896279114774'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2008/01/treeview-con-xbrowse.html' title='TreeView con xBrowse'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-740532136923291861</id><published>2007-11-19T10:46:00.002+01:00</published><updated>2008-02-19T09:17:15.032+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tDatabase'/><title type='text'>tDataBase, usando tablas como objetos.</title><content type='html'>&lt;a href="http://img143.imageshack.us/img143/2984/tablaev5.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;Puede que pienses que esto no tiene nada que ver con ADO, y en efecto directamente no tiene nada que ver con ADO. En una entrada anterior comentamos que para trabajar con ADO, era necesario conocer algo de SQL, lo que no compentamos es que tambien es necesario manejarse bien con la programación orientada a objetos (POO).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="justify"&gt;En FiveWin está incluida un clase que nos permite manjear las tablas DBF como objetos, eso nos permitiira por una parte probar y tomar soltura en el manejo de propiedades, metodos y ademas es una forma muy eficaz de trabajar. &lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Esta clase nos controla los bloqueos de registro, incorpora un buffer para no modificar directamente sobre el registro, controla si hay cambios en los datos editados, y muchas mas cosas, que nos llevaria bastante trabajo programar a mano. &lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Su uso es muy sencillo, y ahora veremos un pequeño ejemplo.&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;El primer paso, es crear el objeto (instanciar de la clase), abriremos una tabla, por ejemplo de proveedores&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;strong&gt;DBUseArea(.T.,'DBFCDX','PROVEEDOR','PROVEEDOR,.T.,.F.)&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;strong&gt;oDbf := TDataBase():New()&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;ya tenemos creado y funcional nuestro objeto oDbf, disponemos de todos los metodos necesarios para trabajar con una tabla (oDbf:Skip(), oDbf:GoTop(), oDbf:Save(), oDbf:Used(), ...), en la ayuda de fivewin encontrareis todos los metodos disponibles, y en la carpeta Source\clases, podeis consultar el código fuente y ver como funcina internamente.&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Siguiendo con un proceso normal de altas y modificaciones de ficheros, el siguiente paso seria determinar si queremos añadir un registro, o editar el registro actual.&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Si quermos hacer una alta, invocaremos el metodo Blank, que nos dejara el buffer de edición vacio y listo para ñadir un nuevo registro. &lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Por el contrario si queremos editar el registro actual, invocaremos el metodo Load, que cargara el contenido de los campos de la tabla, en el buffer de edición.&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Acto seguido ya podemos visualizar, editar y modificar el contenido de los campos de nuestro objeto, y la forma de referirnos a los campos es &lt;em&gt;nombre de nuestro objeto : nombre del campo&lt;/em&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;strong&gt;@ 10,10 GET oDbf:Codigo&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;strong&gt;@ 12,10 GET oDbf:Nombre ....&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;cuando hayamos introducido todos nuestros datos, si queremos guardarlos actuaremos de la siguiente manera.&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Comprobaremos si realmente se han modificado los datos, y para ello consultamos el valor de oDbf:Modified(), si nos devuelve verdadero, es que hay cambios.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="justify"&gt;Si el registro es una alta, en este momento crearemos el registro (hasta ahora hemos estado trabajando sobre un buffer temporal en memoria).&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;strong&gt;oDbf:Append()&lt;/strong&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;y tanto si es una alta como una edición de un registro existente, grabaremos el contenido del buffer temporal a los campos de la tabla.&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;strong&gt;oDbf:Save&lt;/strong&gt;()&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Sencillo y potente, verdad?. Bueno pues ADO, funciona de una manera muy parecida, cambian los nombres de algunos metodos, pero en el fondo la filosofia de funcionamiento es la misma. &lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div align="justify"&gt;Aqui teneis algunos metodos con la misma funcionalidad tanto en tDatabase como en ADO&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://www.piema.info"&gt;&lt;img src="http://img143.imageshack.us/img143/2984/tablaev5.jpg" border="0" alt="BielSys"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;&lt;table class="forumline" width="100%" cellspacing="1" cellpadding="4" border="0"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;  &lt;td class="row1"&gt;&lt;table width="100%" border="0" cellspacing="0" cellpadding="0"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;br /&gt;     &lt;span class="postbody"&gt;&lt;/span&gt;&lt;table width="90%" cellspacing="1" cellpadding="3" border="0" align="center"&gt;&lt;tr&gt;    &lt;td&gt;&lt;span class="genmed"&gt;&lt;b&gt;Código fuente ejemplo mantenimiento ficha de proveedores usando tDatabase:&lt;/b&gt;&lt;/span&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;   &lt;td class="code"&gt;STATIC FUNCTION EdtPro&amp;#40;lAdd&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;LOCAL oDlg,oDbf,lSave&amp;#58;=.F.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;DEFAULT lAdd&amp;#58;=.F.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;Select Proveedores&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;DATABASE oDbf&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;DEFINE DIALOG oDlg RESOURCE &amp;quot;MANPROVE&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;IF lAdd&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; oDbf&amp;#58;Blank&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;ELSE&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; oDbf&amp;#58;Load&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;ENDIF&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oDlg&amp;#58;SetText&amp;#40;'&amp;#40;'+ProcName&amp;#40;&amp;#41;+'&amp;#41;'+IF&amp;#40;lAdd,' Añadir Proveedores',' Editar ficha proveedor'&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Codprov&amp;nbsp; &amp;nbsp;ID 601 OF oDlg VALID &amp;#123;|oGet|Ajusta&amp;#40;oGet&amp;#41;&amp;#125; WHEN lAdd&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Nombre&amp;nbsp; &amp;nbsp; ID 602 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Nif&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ID 603 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Dir1&amp;nbsp; &amp;nbsp; &amp;nbsp; ID 604 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Dir2&amp;nbsp; &amp;nbsp; &amp;nbsp; ID 605 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Cp&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ID 606 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Provincia ID 607 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Tel1&amp;nbsp; &amp;nbsp; &amp;nbsp; ID 608 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Tel2&amp;nbsp; &amp;nbsp; &amp;nbsp; ID 609 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Movil&amp;nbsp; &amp;nbsp; &amp;nbsp;ID 610 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Fax&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ID 611 OF oDlg&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE GET oDbf&amp;#58;Percon&amp;nbsp; &amp;nbsp; ID 612 OF oDlg&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE BUTTON ID 1 OF oDlg ACTION &amp;#40;oDlg&amp;#58;End&amp;#40;&amp;#41;, lSave &amp;#58;= .T.&amp;#41; // OK&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;REDEFINE BUTTON ID 2 OF oDlg ACTION &amp;#40;oDlg&amp;#58;End&amp;#40;&amp;#41;&amp;#41; // Cancel&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;ACTIVATE DIALOG oDlg CENTERED&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;IF lSave .AND. oDbf&amp;#58;Modified&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; IF lAdd&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;oDbf&amp;#58;Append&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ENDIF&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; oDbf&amp;#58;Save&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;ENDIF&lt;br /&gt;&lt;br /&gt;RETURN NIL&lt;/td&gt; &lt;/tr&gt;&lt;/table&gt;&lt;span class="postbody"&gt;&lt;br /&gt;&lt;br /&gt;_________________&lt;br /&gt;Saludos desde Mallorca&lt;br /&gt;&lt;br /&gt;Biel&lt;br /&gt;&lt;br /&gt;Gabriel Maimó&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;    &lt;/td&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;  &lt;/table&gt;&lt;/td&gt;&lt;br /&gt; &lt;/tr&gt;&lt;br /&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-740532136923291861?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/740532136923291861/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=740532136923291861' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/740532136923291861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/740532136923291861'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2007/11/t.html' title='tDataBase, usando tablas como objetos.'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-5915518048511696214</id><published>2007-11-07T15:05:00.002+01:00</published><updated>2008-02-19T09:15:05.058+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ADO'/><title type='text'>ADO ConnectionString</title><content type='html'>&lt;div style="TEXT-ALIGN: justify"&gt;Al usar ADO, el primer escollo con el que nos vamos a encontrar, es el ConnectionString. Es la&lt;br /&gt;cadena que tenemos que pasarle como parametro al objeto connection, para que se conecte con nuestro servidor de base de datos. Si fallamos en este paso, es imposible que nada nos funcione, por eso es un parametro muy importante, y que debemos especificar correctamente. A tal efecto disponemos de una web en la cual podemos encontrar las cadenas de conexión de la mayoira de servidores &lt;a href="http://www.connectionstrings.com/"&gt;http://www.connectionstrings.com/&lt;/a&gt; Pero tambien diposnemos de otro medio más sencillo y practico con un pequeño programa desarrollado por nosotros mismos, y explotando automatizacion ole y el componente &lt;span style="FONT-WEIGHT: bold"&gt;DataLinks&lt;/span&gt;. La gran ventaja es que podreis probar al momento si la conexión con el servidor se realiza correctamente.&lt;br /&gt;&lt;br /&gt;Aqui teneis el codiggo fuente, como veis son cuatro linea.&lt;br /&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(51,51,255);font-family:arial;font-size:85%;"  &gt;#include "FiveWin.Ch"&lt;br /&gt;FUNCTION main()&lt;/span&gt;&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;span style="COLOR: rgb(51,51,255);font-family:arial;font-size:85%;"  &gt;LOCAL oDataLink := TOleAuto():New("Datalinks"),;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;span style="COLOR: rgb(51,51,255);font-family:arial;font-size:85%;"  &gt;oConn := oDataLink:PromptNew(),; &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;span style="COLOR: rgb(51,51,255);font-family:arial;font-size:85%;"  &gt;cConn:='' &lt;/span&gt;&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;span style="COLOR: rgb(51,51,255);font-family:arial;font-size:85%;"  &gt;cConn:=oConn:ConnectionString &lt;/span&gt;&lt;br /&gt;&lt;span style="COLOR: rgb(51,51,255);font-family:arial;font-size:85%;"  &gt;?cConnRETURN&lt;br /&gt;RETURN NIL&lt;/span&gt;&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;span style="COLOR: rgb(51,51,255);font-family:arial;font-size:85%;"  &gt;FUNCTION RddSys(); RETURN NIL&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Al ejecutar nos aparece la siguiente pantalla&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;.&lt;a href="http://www.blogger.com/www.piema.info"&gt;&lt;img style="BORDER-RIGHT: 0px solid; BORDER-TOP: 0px solid; BORDER-LEFT: 0px solid; WIDTH: 366px; BORDER-BOTTOM: 0px solid; HEIGHT: 462px" alt="Image Hosted by ImageShack.us" src="http://img230.imageshack.us/img230/605/pan1oi5.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;Como podeis ver tenemos cuatro pestañas, en la primera nos aparecen todos los&lt;br /&gt;controladores OLE DB que tenemos instalados en nuestro sistema. &lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;/div&gt;&lt;br /&gt;En la segunda, nos permite seleccionar un acceso a datos via ODBC,&lt;br /&gt;previamente debe de haberse definido el origen de datos en panel de&lt;br /&gt;control, herramientas administrativas.&lt;br /&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://imageshack.us/"&gt;&lt;img alt="Image Hosted by ImageShack.us" src="http://img215.imageshack.us/img215/3184/pan2pv6.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;La pestaña dos varia si elejimos el acceso via OLE DB, presentara el siguiente&lt;br /&gt;aspecto.&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;En esta pantalla debemos especificar, el origen de datos, ubicacion, usuario y contraseña, si procede. &lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;a href="http://imageshack.us/"&gt;&lt;img alt="Image Hosted by ImageShack.us" src="http://img215.imageshack.us/img215/2976/pan4em4.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;Ademas en esta pantalla, disponemos de un boton que nos permite probar la conexion. Si la prueba de conexion es correcta, nos devuelve una ventana con un mensaje de confirmación.&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;a href="http://imageshack.us/"&gt;&lt;img alt="Image Hosted by ImageShack.us" src="http://img215.imageshack.us/img215/6236/pan5ze6.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;Disponemos de dos pestañas adicionales, donde pueden definirse otros parametros, y en la última pestaña donde nos visualiza todos los parametros definidos para la conexón.&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;/div&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;Si pulsamos aceptar, nos aparecera otra ventan visualizando el contenido de la variable cConn,&lt;br /&gt;que es el string que debemos pasar al objeto connection. De esta manera podras definir un connectionString, con todos los parametros necesarios, para el origen de datos que quieras, sin preocuparte por la sintaxis.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://imageshack.us/"&gt;&lt;img alt="Image Hosted by ImageShack.us" src="http://img215.imageshack.us/img215/3660/pan6np8.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Bueno, como siempre espero que os sea de utilidad, y que sigais leyendo el blog de vez en cuando. Un saludo desde Mallorca.&lt;br /&gt;&lt;div style="TEXT-ALIGN: justify"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-5915518048511696214?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/5915518048511696214/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=5915518048511696214' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/5915518048511696214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/5915518048511696214'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2007/11/ado-connectionstring.html' title='ADO ConnectionString'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-1255736378059687003</id><published>2007-11-02T11:58:00.000+01:00</published><updated>2007-11-02T12:30:43.105+01:00</updated><title type='text'>CONEXION A ORIGENES DE DATOS SQL</title><content type='html'>Al comentzar a escribir este blog, me han llegado sugerencias de que escriba sobre el tema ADO, SQL, etc, pues parece es algo que cada dia interesa más a la comunidad xBase.&lt;br /&gt;&lt;br /&gt;En este primera entrada referente al tema SQL, comentare brevente tres de las opciones que disponemos los usuarios xBase(FiveWin) para conectarlos a bases de datos SQL.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;&lt;a href="http://es.wikipedia.org/wiki/Open_Database_Connectivity"&gt;ODBC&lt;/a&gt;&lt;/strong&gt;&lt;span style="font-size:0;"&gt; &lt;/span&gt;(Open Data Base Conectivity). Es el sistema más antiguo con el que contamos, y actualmente en el foro cuenta con algo de mala fama.&lt;br /&gt;Personalmente lo he utilizado, y he conseguido muy buenos resultados. Toda la funcionalidad esta descrita en dos clases de fiveWin, de las cuales disponeis del código fuente. Eso permite el control absoluto del funcionamiento, y ademas la adecuación en caso de necesidad. Una pega en cuanto a seguridad, es que trabaja con ficheros temporales DBF que los crea al vuelo, y carga con los datos obtenidos del servidor. Para conectarnos al servidor de bases de datos, debemos crear un origen de datos ODBC(DSN de sistema normalmente), puede ser creado por programa, aunque no es algo trivial. Algunos instaladores tambien permiten crear origenes de datos ODBC.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;a href="http://es.wikipedia.org/wiki/ADO_(inform%C3%A1tica)"&gt;ADO&lt;/a&gt;&lt;/span&gt; (ActiveX Data Objects), posiblemente este sea el metodo mas potente del que disponemos para atacar a motores de bases de datos, aunque tambien el que va a requerir más conocimientos. En la red podremos encontrar infinidad de documentacion, sobre los objetos ado, sus metodos, propiedades, etc. Para conectarlos al servidor, tenemos que definir una cadena de conexión dentro de nuestro programa, no es necesario definir nada externo a nuestro programa. Para conexion con ADO necesitamos que el motor de base de datos soporte OLE DB, aunque si no lo soporta,  simpre podemos acceder mediante un origen de datos ODBC ya definido. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;div align="left"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;&lt;a href="http://fivetechsoft.com/forums/viewtopic.php?t=6815"&gt;AdoRdd&lt;/a&gt;&lt;/span&gt;,se trata de manejar conexiones via ADO, pero con comandos xBase. Es la última opción que ha aparecido, y es sin duda la mas sencilla de implentar y casi no requiere conocimiento alguno de ADO. De haber existido antes, seguramente es la que hubiera escojido para mis proyectos. Quizas no se llegue al control o rendimiento que se pueda&lt;br /&gt;alcanzar utilizando ADO directamente, pero el coste de implementación y aprencizaje, es mucisimo menor.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div align="left"&gt;&lt;br /&gt;Con cualquiera de las tres opciones, es casi indispensaple unos conocimientos minimos del lenguaje de consulta de datos SQL, y del funcionamiento y diseño de las bases de datos relacionales. Cuanto mas conozcas SQL, mucho mejor.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-1255736378059687003?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/1255736378059687003/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=1255736378059687003' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1255736378059687003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1255736378059687003'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2007/11/conexion-origenes-de-datos-sql.html' title='CONEXION A ORIGENES DE DATOS SQL'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9171016160501594940.post-1986237244434777124</id><published>2007-10-11T17:03:00.002+02:00</published><updated>2008-02-19T09:16:30.951+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Harbour'/><category scheme='http://www.blogger.com/atom/ns#' term='xBase'/><title type='text'>Usando List &amp; Label 12</title><content type='html'>Recientemente en el foro de FiveWin se viene hablando del generador de informes List &amp;amp; Label. Y aunque se comenta que es muy bueno, que funciona muy bioen, etc, la verdad es que no hay hasta la fecha ningún ejemplo funcional para ser usado con FiveWin. Bueno realmente si hay una primera aproximación de Jairo Centeno (gracias), que expone un ejemplo de como usar el generador de informes.&lt;br /&gt;&lt;br /&gt;En esta entrada intentare poner un ejemplo de como usar el diseñador, y otro de lanzar un informe.&lt;br /&gt;&lt;br /&gt;El primer punto a destacar es la filosofía de uso de este generador de informes. Mientras que la mayoria de generadores se basan en la conexion a un origen de datos, LL recibe los datos al momento, y su origen puede ser cualquiera, dejando en manos del programador el envio de datos al reporte.&lt;br /&gt;&lt;br /&gt;La función &lt;strong&gt;DefineData&lt;/strong&gt;, es la encargada de pasar los datos al reporte, tanto para diseño como para impresión. El primer paso es convertir los datos xBase a formato LL, y el segundo definir el campo o la variable dependiendo del valor recibido como parametro en lAsField. El segundo parametro oLl, es un objeto valido LL ya creado.&lt;br /&gt;&lt;br /&gt;Para lanzar el diseñador de informes, llamamos a la funcion &lt;strong&gt;Disenya&lt;/strong&gt; los pasos a seguir son muy simples.&lt;br /&gt;1.- Creamos un nuevo objeto LL &lt;strong&gt;&lt;em&gt;oLl = TActiveX():New( oWnd, "L12.List-Label12_Ctrl_32.1" )&lt;/em&gt;  &lt;/strong&gt;&lt;br /&gt;2.- Ajustamos varias propiedades del objeto LL &lt;br /&gt;3.- Llamamos a la función DefineData, que le enviara los campos al diseñador de informes.&lt;br /&gt;&lt;strong&gt;&lt;em&gt;alias-&gt;( DefineData(.t., oLl) )&lt;/em&gt; &lt;/strong&gt;&lt;br /&gt;4.-Invocamos el diseñador &lt;br /&gt;&lt;strong&gt;&lt;em&gt;oLl:Do("LlDefineLayout",oWnd:hWnd,"Designer",LL_PROJECT_LIST, "informe.lst")&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;Facil y sencillo, ahora manipulamos y diseñamos nuestro informe, y lo guardamos. Ya tenemos listo un informe para ser llamado desde nuestra aplicación.&lt;br /&gt;&lt;br /&gt;Ya tenemos un informe creado, ahora vamos a llamar el informe desde nuestro programa, podeis revisar el código de la función &lt;strong&gt;Imprime&lt;/strong&gt; que teneis más abjo, el funcionamiento es el siguiente:&lt;br /&gt;1.- Creamos un nuevo objeto LL &lt;strong&gt;&lt;em&gt;oLl = TActiveX():New( oWnd, "L12.List-Label12_Ctrl_32.1" )&lt;/em&gt;  &lt;/strong&gt;&lt;br /&gt;2.- Ajustamos varias propiedades del objeto LL (inicio de variables, de campos, immpresora por defecto, ...)&lt;br /&gt;3.- Llamamos a la función &lt;strong&gt;DefineData&lt;/strong&gt;, que le enviara los campos al diseñador de informes.&lt;br /&gt;&lt;br /&gt;Hasta aqui igual que para el diseñador.&lt;br /&gt;&lt;br /&gt;4.- Empezamos la impresión &lt;br /&gt;&lt;strong&gt;&lt;em&gt;&lt;br /&gt;oLl:Do("LlPrintStart",LL_PROJECT_LIST,"Informe.lst",LL_PRINT_PREVIEW)&lt;br /&gt;oLl:DO("llPrint")&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;5.- Montamos un bucle que recorra los registros que queremos imprimir, y para cada registro llamamos la Funcion &lt;strong&gt;DefineData&lt;/strong&gt; (convierte y envia los datos aLL) y &lt;strong&gt;&lt;em&gt;oLl:DO("llPrintFields")&lt;/em&gt;&lt;/strong&gt; que imprime los campos.&lt;br /&gt;&lt;br /&gt;5.- Una vez que hemos terminado los registros que queriamos imprimir, solo nos queda indicarle a LL que ya esta finalizado el listado.&lt;br /&gt;  &lt;strong&gt;&lt;em&gt; oll:DO("llPrintEnd",0)&lt;br /&gt;   oLl:DO("LlPreviewDisplay", "informe.lst", , oWnd:hWnd)&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Esto es un ejemplo muy sencillo, pero espero os aclare un poco el modo de funcionar, para ver con más profundidad todas las funciones y parametros, revisad la ayuda del producto. &lt;br /&gt;En el código fuente incluido, se utiliza una tabla cuyo alias es tmp, y se presupone abierta, y una ventana oWnd tambien se presupone definida, y con scope en las funciones.&lt;br /&gt;En la transformacion de tipos de datos, el formato fecha lo convierto a texto, aunque podria convertirse tambien a formato juliano si quisieramos hacer algún tipo de operación con la fecha dentro del informe.&lt;br /&gt;Nada más, esta es mi primera entrada en el blog, así que espero os guste y os sea de utilidad. En la medida del tiempo disponible ire añadiendo nuevas entradas. &lt;br /&gt;&lt;br /&gt;&lt;table class="forumline" width="100%" cellspacing="1" cellpadding="4" border="0"&gt;&lt;br /&gt;  &lt;tr&gt;&lt;br /&gt;  &lt;td class="row1"&gt;&lt;table width="100%" border="0" cellspacing="0" cellpadding="0"&gt;&lt;br /&gt;   &lt;tr&gt;&lt;br /&gt;    &lt;td&gt;&lt;br /&gt;     &lt;span class="postbody"&gt;&lt;/span&gt;&lt;table width="90%" cellspacing="1" cellpadding="3" border="0" align="center"&gt;&lt;tr&gt;    &lt;td&gt;&lt;span class="genmed"&gt;&lt;b&gt;Código:&lt;/b&gt;&lt;/span&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt;   &lt;td class="code"&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;quot;cmbtll12.ch&amp;quot;&lt;br /&gt;&lt;br /&gt;FUNCTION Disenya&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;LOCAL oLL,oWnd,hJob,cName&amp;#58;='qsl'&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl = TActiveX&amp;#40;&amp;#41;&amp;#58;New&amp;#40; oWnd, &amp;quot;L12.List-Label12_Ctrl_32.1&amp;quot; &amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40; &amp;quot;LlSetOption&amp;quot;, LL_OPTION_MULTIPLETABLELINES, 1&amp;#41;&amp;nbsp; &amp;nbsp; //Permite multiples tablas&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40; &amp;quot;LlDefineFieldStart&amp;quot; &amp;#41; //Limpia buffer de campos&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;DO&amp;#40; &amp;quot;LlDefineVariableStart&amp;quot;&amp;#41;//Limpia buffer de variablesx&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;Tmp-&amp;gt;&amp;#40; DefineData&amp;#40;.t., oLl&amp;#41; &amp;#41;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40;&amp;quot;LlSetPrinterDefaultsDir&amp;quot;,hJob,&amp;quot;C&amp;#58;\Windows\Temp&amp;quot;&amp;#41; //Arranca diseñador&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40;&amp;quot;LlDefineLayout&amp;quot;,oWnd&amp;#58;hWnd,&amp;quot;Designer&amp;quot;,LL_PROJECT_LIST, &amp;quot;log.lst&amp;quot;&amp;#41;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;RETURN NIL&lt;br /&gt;&lt;br /&gt;//------------------------------------&lt;br /&gt;&lt;br /&gt;FUNCTION Imprime&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;LOCAL oLL,oWnd,hJob,cName&amp;#58;='log.lst',cDir&amp;#58;=oAppl&amp;#58;cDirLocal&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl = TActiveX&amp;#40;&amp;#41;&amp;#58;New&amp;#40; oAppl&amp;#58;oWnd, &amp;quot;L12.List-Label12_Ctrl_32.1&amp;quot; &amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40; &amp;quot;LlSetOption&amp;quot;, LL_OPTION_MULTIPLETABLELINES, 1&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40; &amp;quot;LlDefineFieldStart&amp;quot; &amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;DO&amp;#40; &amp;quot;LlDefineVariableStart&amp;quot;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;Tmp-&amp;gt;&amp;#40; DefineData&amp;#40;.t., oLl&amp;#41; &amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40;&amp;quot;LlSetPrinterDefaultsDir&amp;quot;,cDir&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40;&amp;quot;LlPrintStart&amp;quot;,LL_PROJECT_LIST,cName,LL_PRINT_PREVIEW&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oll&amp;#58;DO&amp;#40;&amp;quot;llPrintOptionsDialog&amp;quot;,oAppl&amp;#58;oWnd&amp;#58;hWnd&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;DO&amp;#40;&amp;quot;llPrint&amp;quot;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;Tmp-&amp;gt;&amp;#40;DBGoTop&amp;#40;&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;DO WHILE !Tmp-&amp;gt;&amp;#40;Eof&amp;#40;&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Tmp-&amp;gt;&amp;#40;DefineData&amp;#40;.T.,oLl&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; oLl&amp;#58;DO&amp;#40;&amp;quot;llPrintFields&amp;quot;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Tmp-&amp;gt;&amp;#40;DBSkip&amp;#40;&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;ENDDO&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oll&amp;#58;DO&amp;#40;&amp;quot;llPrintEnd&amp;quot;,0&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;DO&amp;#40;&amp;quot;LlPreviewDisplay&amp;quot;, cName, , oAppl&amp;#58;oWnd&amp;#58;hWnd&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;oLl&amp;#58;DO&amp;#40;&amp;quot;llPreviewDeleteFiles&amp;quot;,cName,cDir&amp;#41;&lt;br /&gt;&lt;br /&gt;RETURN NIL&lt;br /&gt;&lt;br /&gt;//----------------------------------------------&lt;br /&gt;&lt;br /&gt;FUNCTION DefineData&amp;#40;lAsField,oLl&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;LOCAL FldType, FldContent, lExpr,i,DateBuffer&amp;#58;=Replicate&amp;#40;Chr&amp;#40;0&amp;#41;,255&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;//Convierte formato xBase a List &amp;amp; Label&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;FOR i&amp;#58;=1 TO FCount&amp;#40;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; DO CASE&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CASE FieldType&amp;#40;i&amp;#41;=='N'&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldType&amp;#58;=LL_NUMERIC&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldContent&amp;#58;=Str&amp;#40;FieldGet&amp;#40;i&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CASE FieldType&amp;#40;i&amp;#41;=='C'&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldType&amp;#58;=LL_TEXT&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldContent&amp;#58;=Trim&amp;#40;FieldGet&amp;#40;i&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CASE fieldType&amp;#40;i&amp;#41;=='M'&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldType&amp;#58;=LL_TEXT&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldContent&amp;#58;=FieldGet&amp;#40;i&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CASE FieldType&amp;#40;i&amp;#41;=='L'&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldType&amp;#58;=LL_BOOLEAN&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldContent&amp;#58;=IF&amp;#40;FieldGet&amp;#40;i&amp;#41;,'TRUE','FALSE'&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CASE FieldType&amp;#40;i&amp;#41;=='D'&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldType&amp;#58;=LL_TEXT&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;FldContent&amp;#58;=DToC&amp;#40;FieldGet&amp;#40;i&amp;#41;&amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ENDCASE&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; IF lAsField&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40;&amp;quot;LlDefineFieldExt&amp;quot;,FieldName&amp;#40;i&amp;#41;, FldContent, FldType &amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ELSE&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;oLl&amp;#58;Do&amp;#40;&amp;quot;LlDefineVariableExt&amp;quot;, FieldName&amp;#40;i&amp;#41;, FldContent, FldType &amp;#41;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ENDIF&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;NEXT&lt;br /&gt;&lt;br /&gt;RETURN NIL&lt;br /&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/table&gt;&lt;span class="postbody"&gt;  &lt;/table&gt;&lt;/td&gt;&lt;br /&gt; &lt;/tr&gt;&lt;br /&gt; &lt;tr&gt;&lt;br /&gt;  &lt;td class="spaceRow" height="1"&gt;&lt;img src="templates/subSilver/images/spacer.gif" width="1" height="1" /&gt;&lt;/td&gt;&lt;br /&gt; &lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9171016160501594940-1986237244434777124?l=bielsys.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bielsys.blogspot.com/feeds/1986237244434777124/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9171016160501594940&amp;postID=1986237244434777124' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1986237244434777124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9171016160501594940/posts/default/1986237244434777124'/><link rel='alternate' type='text/html' href='http://bielsys.blogspot.com/2007/10/usando-list-label-12.html' title='Usando List &amp; Label 12'/><author><name>BielSys</name><uri>http://www.blogger.com/profile/09188429742231549024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>
