Acceso rápido a datos de foxpro a partir de delphi


el Acceso de datos de FoxPro mediante la velocidad de Rushmore en Delphi.

derechos de Autor Pinnacle Publishing, Inc. Todos los derechos reservados.Acceso Rápido a Datos de FoxPro a partir de Delphi
Steve Zimmelman

Cuando Borland anunció que Delphi 3 iba a tener FoxPro DBF/CDX conductores, hubo un poco de emoción de FoxPro a los desarrolladores que estaban tratando de migrar sus aplicaciones Delphi. La emoción fue de corta duración, sin embargo, cuando se dieron cuenta de que los controladores no tienen el mismo impacto como su propio primo. El pequeño DLL de OLE que se presentan en este artículo podría ser el puente que finalmente trae los dos juntos.

recientemente he desarrollado una aplicación para nuestra empresa en Delphi 3, en la que se lee en las tablas de nuestro FoxPro DOS legado de sistema. Todo salió bien en la beta, así que empezamos a distribuir la aplicación a nuestros clientes. Hubo, sin embargo, uno de supervisión. Nunca hemos probado el sistema en contra de las mesas que estaban muy pobladas. Cuando instalamos la aplicación en uno de nuestros más grandes sitios de los clientes, la aplicación se cayó a sus rodillas y murió. El problema: El BDE fue el intento de algunas consultas complejas usando SQL contra una mesa que tenía cerca de 2 millones de registros. Nuestro cliente nos informó que las consultas que se estaban tomando las 72 horas para completar. Por supuesto, esto no era aceptable, por lo que empecé a investigar formas alternativas de ejecución de las consultas. El resultado fue una de Visual FoxPro (VFP) objeto OLE en la forma de un archivo DLL que ejecuta las consultas (o casi cualquier comando de FoxPro) desde dentro de Delphi, de forma transparente, y con la velocidad de Rushmore. El uso de esta tecnología, el tiempo de consulta cayó de horas a segundos.
Para aquellos que no están familiarizados con Visual FoxPro, tiene una característica llamada Sustitución de Macro, que es la base de la DLL de OLE. La Sustitución de macros trata el contenido de una variable de memoria como un literal de cadena de caracteres. Cuando un signo de y comercial ( & ) precede a un tipo de cadena variable de memoria, el contenido de la variable es tratada como una mano de comandos escritas, y se ejecuta.
el código de La VFP DLL de OLE es realmente muy simple, y puede contener tan poco como una sola función o un procedimiento. Decidí escribir unos procedimientos que son específicas de la aplicación, pero también se incluyen algunos genérico que puede ser utilizado por cualquier aplicación. Por el bien de la simplicidad, he incluido sólo la genérica de funciones y procedimientos en el siguiente código.

**************************************
* Programa: VFP_OLE.PRG
* 5 de Visual FoxPro DLL de OLE
**************************************
DEFINIR la CLASE VFP_OLE_Server COMO CONTENEDOR de OLEPUBLIC
& nbsp & nbsp & nbsp Procedimiento Init
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * El Procedimiento INIT es automáticamente
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * ejecuta cuando se carga la DLL.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Talk Off
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Conjunto Seguro
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp En el Error de Hacer Ole_Err Con Error(),Lineno(),Mensaje(),Programa()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Exclusivo Off
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Null
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *****************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Si CPDIALOG está ENCENDIDO y una DBF que se
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & creado sin que la página de códigos que se abre,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & la página de códigos del Cuadro de Diálogo enfrentar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & el usuario.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *****************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp CONJUNTO CPDIALOG OFF
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set volver a procesar A 1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * Mover Foxpro pantalla principal del modo off el bit-cubo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * por lo tanto, no va a ser visto si se ha hecho visible.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Mover la Ventana de la Pantalla Para -1000,-1000
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Modificar la Pantalla de la Ventana de Título 'VFP OLE'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ocultar la Ventana de la Pantalla
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procedimiento SetDir
& nbsp & nbsp & nbsp Parámetro redc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Default (m.redc)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Función ExeSql
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parámetro cSql
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Privado nRecs,i,cFile,cFileSrc,cFullPath,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cDestpath,cAlias,IsVFPFile,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cDbfFileName,nHandle
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp lIsVFPFile = .F.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cFullPath = Set('FullPath')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * Mostrar VFP Principal de la Ventana de modo de Archivo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * cuadro de diálogo será visible
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * si VFP no puede encontrar un archivo que
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * es necesaria para el comando SQL.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Mostrar la Pantalla de la Ventana
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Ejecutar la Instrucción SQL & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cSql = AllTrim(m.cSql)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & cSql
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ocultar la Ventana de la Pantalla
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp nRecs = _Tally
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Conjunto FullPath En
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cFileSrc = DBF()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp **************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Check tabla escriba.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Si Es de Tipo Visual FoxPro Convertir
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & a Fox2x.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & El BDE no admite tablas de VFP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp **************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp nHandle = FOpen(m.cFileSrc)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si nHandle <> -1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp lIsVFPFile = (FGets(m.nHandle,1)=Chr(48))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp =FClose(m.nHandle)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso (m.cFileSrc) Exclusivo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cDestPath = izquierda(dbf(),rata('/',dbf()))
& nbsp & nbsp & nbsp & nbsp & nbsp & Si nbsp m.lIsVFPFile
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Convertir el Resultado A Fox2x Formato & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cFile = 'T' a la derecha(sys(3),7)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Copia (m.cDestPath m.cFile) Tipo de Fox2x
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar (m.cFileSrc)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si el Archivo(a la Izquierda(m.cFileSrc,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Len(m.cFileSrc)-4) '.FTP')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar (a la Izquierda(m.cFileSrc,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Len(m.cFileSrc)-4) '.FTP')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cambiar el nombre de (m.cDestPath m.cFile '.DBF')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp (m.cFileSrc)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si el Archivo. (m.cDestPath m.cFile '.FPT')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cambiar el nombre de (m.cDestPath m.cFile '.FPT')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp A (a la Izquierda(m.cFileSrc,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Len(m.cFileSrc)-4) '.FTP')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso (m.cFileSrc) Exclusivo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbs * & Restaurar FullPath Configuración & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Conjunto FullPath & cFullPath
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ** & Resultado número de Registro & **
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Retorno (m.nRecs)
& nbsp & nbsp & nbsp EndFunc
& nbsp & nbsp & nbsp Procedimiento SetPath
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parámetro cPath
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Path To (m.cPath)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procedimiento FoxCommand
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parámetro división
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & división
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Función FoxFunction
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parámetro cFunc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Privado Rtn
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Rtn = & cFunc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Retorno (m.Rtn)
& nbsp & nbsp & nbsp EndFunc
ENDDEFINE
Procedimiento Ole_Err
& nbsp & nbsp & nbsp ** & Identificador DLL Errores internos & **
& nbsp & nbsp & nbsp Parámetro nErr,nLine,cMessage,cPRG
& nbsp & nbsp & nbsp SI (m.nErr=1707)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & CDX no existe, OK para Reintentar & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reintentar
& nbsp & nbsp & nbsp Else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MessageBox( m.cMessage Chr(13) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Error ' # ' str(m.nErr,5) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'En la Línea#' Str(m.nLine,5) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'En' m.cPrg chr(13) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Ver File:OLE_ERR.TXT para obtener más detalles.'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ,16, 'ERROR en VFP_OLE.DLL el Módulo')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Dump de la Memoria y el Estado de los Archivos en un Archivo De Texto.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Crear Cursor OleError (ErrText M(10))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Estado de la Lista NoConsole A Archivo OLE_STAT.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Lista de la Memoria * NoConsole A Archivo OLE_MEM.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Anexar en Blanco
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reemplazar ErrText Con
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Replicar('*',80) Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp DTOC(Date ()) ' ()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PadC(' ESTADO ',80,'*')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Anexar Memo ErrText De OLE_STAT.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reemplazar ErrText Con Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PadC(' MEMORIA ',80,'*')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10) Addi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Anexar Memo ErrText De OLE_MEM.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reemplazar ErrText Con Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PadC(' & End Error & ',80,'*')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10) Addi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si el Archivo('OLE_ERR.TXT')

& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Copia Memo ErrText A OLE_ERR.TXT Addi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Copia Memo ErrText A OLE_ERR.TXT
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar OLE_STAT.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar OLE_MEM.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Cerca de los Datos
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ocultar la Ventana de la Pantalla
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & El comando CANCELAR causas Delphi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & para ser capaz de capturar el error.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Cancelar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp Endif
EndProc
*:EF(VFP_OLE.PRG)

Después de que el archivo DLL se compila, debe ser registrado en REGSVR32.EXE, que se distribuye con windows 95 y NT y debe estar en el directorio /Windows/System para windows 95 y /Windows/System32 de windows NT. Sin embargo, este proceso puede ser automatizado por la aplicación Delphi en tiempo de ejecución. (ver función RegisterDLL)
En la aplicación Delphi he creado un método que intenta crear una instancia de la DLL en tiempo de ejecución, y otro para registrar la DLL si la creación de instancias método falla. Además, tengo 2 variables globales: vFoxOle y bIsFoxOle. vFoxOle es una Variante que señala el objeto OLE y bIsFoxOle es un valor Booleano que indica si el objeto OLE con éxito fue instanciado. De esta forma, se puede escribir la aplicación para manejar Datos de FoxPro con la VFP OLE o el BDE. Usted también debe tener una referencia a ComObj en los 'Usos' de la cláusula de la forma que se crea una instancia de la DLL.
En el Formulario del método create, yo llame a la Función IsFoxOle para crear instancias de la DLL de OLE. La función Delphi CreateOleObject() se utiliza para crear una conexión con el objeto OLE y devuelve un puntero al objeto que se almacena en la variable vFoxOle. CreateOleObject() se utiliza con un parámetro de cadena que apunta a la Clase que se crea una instancia. En este caso, el nombre de la DLL es VFP_OLE y la Clase es VFP_OLE_Server. Así que, para hacer una conexión que utiliza CreateOleObject('VFP_OLE.VFP_OLE_Server').

procedimiento TfrmFox.FormCreate(Sender: TObject)
Begin
& nbsp & nbsp & nbsp Si No IsFoxOle, a Continuación, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RegisterDLL
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Inicializar bIsFoxOle con el resultado
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // de la creación de instancias intento. Si el proveedor OLE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // objeto fue registrado, entonces el resultado será
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // será cierto.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp bIsFoxOle := IsFoxOle
& nbsp & nbsp & nbsp End Else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp bIsFoxOle := True
Fin
Función TFrmFox.IsFoxOle : Boolean
Begin
& nbsp & nbsp & nbsp Probar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Instanciar el objeto OLE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle :=
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp CreateOleObject('VFP_OLE.VFP_OLE_Server')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Resultado := True
& nbsp & nbsp & nbsp Excepto
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Resultado := False
& nbsp & nbsp & nbsp Final
Fin
Procedimiento TFrmFox.RegisterDLL
// Si REGSVR32.EXE existe RegisterDLL()
// se busca VFP_OLE.DLL
// en 2 lugares:
// 1) /Windows/System
// 2) el directorio actual
var a : Array[0..100] of Char
& nbsp & nbsp & nbsp & nbsp sSysDir : Cadena
& nbsp & nbsp & nbsp & nbsp sCurDir : String
Begin
& nbsp & nbsp & nbsp GetSystemDirectory(@a, 100)
& nbsp & nbsp & nbsp sSysDir : =
& nbsp & nbsp & nbsp sSysDir := AddBS(sSysDir)
& nbsp & nbsp & nbsp sCurDir := AddBS(GetCurrentDir)
& nbsp & nbsp & nbsp If FileExists(sSysDir 'REGSVR32.EXE'), a Continuación, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp If FileExists(sSysDir 'VFP_OLE.DLL') A continuación, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ''' sSysDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp End Else If FileExists(sCurDir 'VFP_OLE.DLL') A continuación, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ''' sCurDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Final
& nbsp & nbsp & nbsp End Else Begin
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Elevar la Excepción.Crear ('No se puede Registrar VFP_OLE.DLL !')
& nbsp & nbsp & nbsp Final
Fin

Prácticas
Supongamos que usted tiene una aplicación de Factura y usted necesita saber la cantidad de dinero que se adeuda, la edad, y que los debe. Su formulario de consulta podría tener este aspecto:
(Insertar Archivo: QForm1.BMP aquí)
Cuando el usuario hace clic en el botón ACEPTAR, la instrucción SQL dinámicamente es creado y enviado a la DLL como un parámetro para su procesamiento. Es importante tener en cuenta que la cadena SQL 'En la Tabla' como parte de la declaración. Sin esto, la aplicación Delphi no tiene forma de recoger los datos de resultado. Hay 3 maneras que usted puede manejar la creación de la Tabla: 1) Crear la tabla en la que los usuarios locales directorio temporal con un nombre de archivo estático. 2) Escribir una función que crea un nombre de archivo único o utilizar la función de API de Windows GetTempFileName(). 3) Combinar ambos 1 & 2 y crear un nombre único en el directorio Temp de Windows. Para los entornos de red, me parece que la opción 3 es la más segura. Es igualmente importante utilizar el método SetDir() antes y después de la ejecución de la Consulta. Esto es así FoxPro sabe donde encontrar las tablas es que se consultan en contra, y por lo que la aplicación Delphi puede encontrar el camino de regreso a casa. Si no SetDir() después de la consulta, entonces hay una posibilidad bastante buena que la aplicación Delphi no ser capaz de encontrar los componentes externos, como AVI, BMP, WAV o archivos que necesita. Esto es porque FoxPro físicamente cambia el puntero de directorio.
Este ejemplo asume que el DBF las mesas se encuentran en el mismo directorio que el Delphi ejecutable. La función GetTempDir() es un simple contenedor de función que utiliza la API de Windows para obtener el directorio temp de windows. La instrucción Select de SQL se crea dinámicamente basado en el número de Días de Vencimiento, y el resultado de la tabla se crea en el directorio Temp de Windows en un archivo llamado MyQuery.dbf. Después De MyQuery.dbf es creado, la Tabla1 objeto se le asigna su contenido y se muestran en la cuadrícula.

procedimiento TfrmFox.btnExeQueryClick(Sender: TObject)
Var
& nbsp & nbsp & nbsp sSQLText : String
& nbsp & nbsp & nbsp iRecs : Integer
& nbsp & nbsp & nbsp sAppDir : Cadena
begin
& nbsp & nbsp & nbsp Si bIsFoxOle, a Continuación, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Obtener la ruta de acceso del directorio de la aplicación
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp sAppDir :=
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ExtractFilePath(Application.ExeName)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si (e_PastDue.Texto = ')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp e_PastDue.Text := '0'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp sSQLText :=
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Seleccione el Cliente.Nombre,'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Factura.AcctNo, Factura.El equilibrio',
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' (Fecha()-Factura.Fecha) Como la Edad'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Desde el Cliente,Factura'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Donde'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' (el Cliente.AcctNo = Factura.AcctNo) Y'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' (Fecha()-Factura.Fecha) >= ' e_PastDue.Texto
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' Pedido Por el Cliente.Nombre,Edad,'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'En la Tabla' GetTempDir() 'MyQuery'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asegúrese de que el objeto de tabla en la que se lee
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // el resultado es cerrado antes de la consulta
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // se ejecuta.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si Tabla1.Activo, a Continuación, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.Cerrar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asegúrese de que la tabla se elimina después de cerrar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.DeleteTable
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asignar nombre temporal para Tabla1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.TableName := 'MyQuery.DBF'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asignar el Directorio temporal a Tabla1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.DatabaseName := GetTempDir()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Conjunto de VFP Defecto en el Directorio donde la
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Fox DBFs son almacenados.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.SetDir(sAppDir)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Ejecutar la Consulta
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp iRecs := vFoxOle.ExeSql(sSQLText)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Label7.Caption := IntToStr(iRecs)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si (iRecs = 0) Entonces
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MessageDlg('no se Encontró Ningún registro En la Consulta!'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ,mtInformation,[mbOK],0)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Else Begin
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // ExeSql() deja el resultado de la tabla de abrir
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // así que usted puede pre-proceso de la tabla
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // VFP antes de Delphi se Abre.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Estos Índices se utilizan para cambiar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // el orden haciendo clic en el
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Cuadrícula Título.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Índice De Nombre de Nombre de la Etiqueta')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Índice De la Edad de la Etiqueta de la Edad')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Índice De AcctNo Etiqueta AcctNo')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Índice De Equilibrio de la Etiqueta de Equilibrio')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Cerca de la Base de datos')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.Abierto
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Final
& nbsp & nbsp & nbsp End Else Begin
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MessageDlg('VFP_OLE.DLL No se crean Instancias!',
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mtError,[mbOK])
& nbsp & nbsp & nbsp End // Si bIsFoxOle
fin

Con este archivo DLL tiene la capacidad de hacer desde dentro de Delphi, casi cualquier cosa que usted puede hacer desde dentro de FoxPro. No sólo se limita a la simple Sustitución de Macros, pero puede ser utilizado para desarrollar Delphi extremos delanteros que utilizan la base de datos Visual FoxPro estructura. Ahora, no estoy sugiriendo que todos empezamos con Visual FoxPro para nuestro back-ends, pero hace un bonito puente para aquellos de nosotros que están migrando nuestros DOS aplicaciones de Windows y de FoxPro para Delphi y la necesidad de la velocidad de Rushmore.
Hay un par de advertencias a esta tecnología el uso de Visual FoxPro se debe tener en cuenta:

  • el manejo de Errores es limitado. Si una instrucción SQL hace referencia a una tabla de FoxPro no puede encontrar, se abre un cuadro de diálogo que pide al usuario por el camino de la misteriosa tabla. Sólo después de que el Escape se pulsa la tecla se genera un error capturable. Por lo que podría ser prudente para comprobar la existencia de las tablas con la función Delphi FileExists(), antes de ejecutar la consulta.
  • Los resultados de la consulta se devuelve a veces en Visual FoxPro formato de archivo, algo que Delphi no admite actualmente. El conjunto de resultados necesita ser convertido por la DLL que puede tomar más tiempo para procesar.
  • Hay 2 tiempo de ejecución de Visual FoxPro archivos Dll que debe ser distribuido con la aplicación Delphi que añadir cerca de 3.9 megas el tamaño global de la aplicación.
  • En el orden legal para distribuir el tiempo de ejecución de Visual FoxPro Dll o crear la DLL de OLE, debe poseer una copia de Visual FoxPro Profesional versión 5 o superior.
    Cambios Desde que Este Artículo Fue WrittenVisual FoxPro versión 6 y posteriores no funcionan con el archivo DLL. Debe compilar el objeto COM en un archivo EXE. El EXE pueden estar registrado mediante la ejecución de una vez en el equipo que van a acceder a ella. RegSvr32.exe no es siempre necesario.









Acceso rapido a datos de foxpro a partir de delphi


Acceso rapido a datos de foxpro a partir de delphi : Multi-millones de consejos para hacer su vida mas facil.


el Acceso de datos de FoxPro mediante la velocidad de Rushmore en Delphi.

Desarrolladores de Delphide enero de 1999

derechos de Autor Pinnacle Publishing, Inc. Todos los derechos reservados.Acceso Rapido a Datos de FoxPro a partir de Delphi
Steve Zimmelman

Cuando Borland anuncio que Delphi 3 iba a tener FoxPro DBF/CDX conductores, hubo un poco de emocion de FoxPro a los desarrolladores que estaban tratando de migrar sus aplicaciones Delphi. La emocion fue de corta duracion, sin embargo, cuando se dieron cuenta de que los controladores no tienen el mismo impacto como su propio primo. El pequeño DLL de OLE que se presentan en este articulo podria ser el puente que finalmente trae los dos juntos.

recientemente he desarrollado una aplicacion para nuestra empresa en Delphi 3, en la que se lee en las tablas de nuestro FoxPro DOS legado de sistema. Todo salio bien en la beta, asi que empezamos a distribuir la aplicacion a nuestros clientes. Hubo, sin embargo, uno de supervision. Nunca hemos probado el sistema en contra de las mesas que estaban muy pobladas. Cuando instalamos la aplicacion en uno de nuestros mas grandes sitios de los clientes, la aplicacion se cayo a sus rodillas y murio. El problema: El BDE fue el intento de algunas consultas complejas usando SQL contra una mesa que tenia cerca de 2 millones de registros. Nuestro cliente nos informo que las consultas que se estaban tomando las 72 horas para completar. Por supuesto, esto no era aceptable, por lo que empece a investigar formas alternativas de ejecucion de las consultas. El resultado fue una de Visual FoxPro (VFP) objeto OLE en la forma de un archivo DLL que ejecuta las consultas (o casi cualquier comando de FoxPro) desde dentro de Delphi, de forma transparente, y con la velocidad de Rushmore. El uso de esta tecnologia, el tiempo de consulta cayo de horas a segundos.
Para aquellos que no estan familiarizados con Visual FoxPro, tiene una caracteristica llamada Sustitucion de Macro, que es la base de la DLL de OLE. La Sustitucion de macros trata el contenido de una variable de memoria como un literal de cadena de caracteres. Cuando un signo de y comercial ( & ) precede a un tipo de cadena variable de memoria, el contenido de la variable es tratada como una mano de comandos escritas, y se ejecuta.
el codigo de La VFP DLL de OLE es realmente muy simple, y puede contener tan poco como una sola funcion o un procedimiento. Decidi escribir unos procedimientos que son especificas de la aplicacion, pero tambien se incluyen algunos generico que puede ser utilizado por cualquier aplicacion. Por el bien de la simplicidad, he incluido solo la generica de funciones y procedimientos en el siguiente codigo.

**************************************
* Programa: VFP_OLE.PRG
* 5 de Visual FoxPro DLL de OLE
**************************************
DEFINIR la CLASE VFP_OLE_Server COMO CONTENEDOR de OLEPUBLIC
& nbsp & nbsp & nbsp Procedimiento Init
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * El Procedimiento INIT es automaticamente
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * ejecuta cuando se carga la DLL.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Talk Off
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Conjunto Seguro
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp En el Error de Hacer Ole_Err Con Error(),Lineno(),Mensaje(),Programa()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Exclusivo Off
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Null
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *****************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Si CPDIALOG esta ENCENDIDO y una DBF que se
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & creado sin que la pagina de codigos que se abre,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & la pagina de codigos del Cuadro de Dialogo enfrentar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & el usuario.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *****************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp CONJUNTO CPDIALOG OFF
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set volver a procesar A 1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * Mover Foxpro pantalla principal del modo off el bit-cubo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * por lo tanto, no va a ser visto si se ha hecho visible.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Mover la Ventana de la Pantalla Para -1000,-1000
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Modificar la Pantalla de la Ventana de Titulo 'VFP OLE'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ocultar la Ventana de la Pantalla
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procedimiento SetDir
& nbsp & nbsp & nbsp Parametro redc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Default (m.redc)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Funcion ExeSql
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parametro cSql
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Privado nRecs,i,cFile,cFileSrc,cFullPath,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cDestpath,cAlias,IsVFPFile,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cDbfFileName,nHandle
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp lIsVFPFile = .F.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cFullPath = Set('FullPath')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * Mostrar VFP Principal de la Ventana de modo de Archivo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * cuadro de dialogo sera visible
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * si VFP no puede encontrar un archivo que
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * es necesaria para el comando SQL.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Mostrar la Pantalla de la Ventana
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Ejecutar la Instruccion SQL & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cSql = AllTrim(m.cSql)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & cSql
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ocultar la Ventana de la Pantalla
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp nRecs = _Tally
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Conjunto FullPath En
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cFileSrc = DBF()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp **************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Check tabla escriba.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Si Es de Tipo Visual FoxPro Convertir
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & a Fox2x.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & El BDE no admite tablas de VFP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp **************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp nHandle = FOpen(m.cFileSrc)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si nHandle <> -1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp lIsVFPFile = (FGets(m.nHandle,1)=Chr(48))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp =FClose(m.nHandle)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso (m.cFileSrc) Exclusivo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cDestPath = izquierda(dbf(),rata('/',dbf()))
& nbsp & nbsp & nbsp & nbsp & nbsp & Si nbsp m.lIsVFPFile
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Convertir el Resultado A Fox2x Formato & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cFile = 'T' a la derecha(sys(3),7)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Copia (m.cDestPath m.cFile) Tipo de Fox2x
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar (m.cFileSrc)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si el Archivo(a la Izquierda(m.cFileSrc,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Len(m.cFileSrc)-4) '.FTP')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar (a la Izquierda(m.cFileSrc,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Len(m.cFileSrc)-4) '.FTP')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cambiar el nombre de (m.cDestPath m.cFile '.DBF')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp (m.cFileSrc)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si el Archivo. (m.cDestPath m.cFile '.FPT')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cambiar el nombre de (m.cDestPath m.cFile '.FPT')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp A (a la Izquierda(m.cFileSrc,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Len(m.cFileSrc)-4) '.FTP')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Uso (m.cFileSrc) Exclusivo
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbs * & Restaurar FullPath Configuracion & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Conjunto FullPath & cFullPath
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ** & Resultado numero de Registro & **
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Retorno (m.nRecs)
& nbsp & nbsp & nbsp EndFunc
& nbsp & nbsp & nbsp Procedimiento SetPath
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parametro cPath
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Set Path To (m.cPath)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procedimiento FoxCommand
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parametro division
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & division
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Funcion FoxFunction
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Parametro cFunc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Privado Rtn
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Rtn = & cFunc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Retorno (m.Rtn)
& nbsp & nbsp & nbsp EndFunc
ENDDEFINE
Procedimiento Ole_Err
& nbsp & nbsp & nbsp ** & Identificador DLL Errores internos & **
& nbsp & nbsp & nbsp Parametro nErr,nLine,cMessage,cPRG
& nbsp & nbsp & nbsp SI (m.nErr=1707)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & CDX no existe, OK para Reintentar & *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reintentar
& nbsp & nbsp & nbsp Else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MessageBox( m.cMessage Chr(13) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Error ' # ' str(m.nErr,5) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'En la Linea#' Str(m.nLine,5) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'En' m.cPrg chr(13) Chr(13)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Ver File:OLE_ERR.TXT para obtener mas detalles.'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ,16, 'ERROR en VFP_OLE.DLL el Modulo')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & Dump de la Memoria y el Estado de los Archivos en un Archivo De Texto.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Crear Cursor OleError (ErrText M(10))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Estado de la Lista NoConsole A Archivo OLE_STAT.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Lista de la Memoria * NoConsole A Archivo OLE_MEM.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Anexar en Blanco
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reemplazar ErrText Con
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Replicar('*',80) Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp DTOC(Date ()) ' ()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PadC(' ESTADO ',80,'*')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Anexar Memo ErrText De OLE_STAT.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reemplazar ErrText Con Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PadC(' MEMORIA ',80,'*')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10) Addi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Anexar Memo ErrText De OLE_MEM.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Reemplazar ErrText Con Chr(13) Chr(10)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PadC(' & End Error & ',80,'*')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Chr(13) Chr(10) Addi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si el Archivo('OLE_ERR.TXT')

& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Copia Memo ErrText A OLE_ERR.TXT Addi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Copia Memo ErrText A OLE_ERR.TXT
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Endif
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar OLE_STAT.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Borrar OLE_MEM.TMP
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Cerca de los Datos
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ocultar la Ventana de la Pantalla
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & El comando CANCELAR causas Delphi
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp * & para ser capaz de capturar el error.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Cancelar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *
& nbsp & nbsp & nbsp Endif
EndProc
*:EF(VFP_OLE.PRG)

Despues de que el archivo DLL se compila, debe ser registrado en REGSVR32.EXE, que se distribuye con windows 95 y NT y debe estar en el directorio /Windows/System para windows 95 y /Windows/System32 de windows NT. Sin embargo, este proceso puede ser automatizado por la aplicacion Delphi en tiempo de ejecucion. (ver funcion RegisterDLL)
En la aplicacion Delphi he creado un metodo que intenta crear una instancia de la DLL en tiempo de ejecucion, y otro para registrar la DLL si la creacion de instancias metodo falla. Ademas, tengo 2 variables globales: vFoxOle y bIsFoxOle. vFoxOle es una Variante que señala el objeto OLE y bIsFoxOle es un valor Booleano que indica si el objeto OLE con exito fue instanciado. De esta forma, se puede escribir la aplicacion para manejar Datos de FoxPro con la VFP OLE o el BDE. Usted tambien debe tener una referencia a ComObj en los 'Usos' de la clausula de la forma que se crea una instancia de la DLL.
En el Formulario del metodo create, yo llame a la Funcion IsFoxOle para crear instancias de la DLL de OLE. La funcion Delphi CreateOleObject() se utiliza para crear una conexion con el objeto OLE y devuelve un puntero al objeto que se almacena en la variable vFoxOle. CreateOleObject() se utiliza con un parametro de cadena que apunta a la Clase que se crea una instancia. En este caso, el nombre de la DLL es VFP_OLE y la Clase es VFP_OLE_Server. Asi que, para hacer una conexion que utiliza CreateOleObject('VFP_OLE.VFP_OLE_Server').

procedimiento TfrmFox.FormCreate(Sender: TObject)
Begin
& nbsp & nbsp & nbsp Si No IsFoxOle, a Continuacion, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RegisterDLL
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Inicializar bIsFoxOle con el resultado
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // de la creacion de instancias intento. Si el proveedor OLE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // objeto fue registrado, entonces el resultado sera
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // sera cierto.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp bIsFoxOle := IsFoxOle
& nbsp & nbsp & nbsp End Else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp bIsFoxOle := True
Fin
Funcion TFrmFox.IsFoxOle : Boolean
Begin
& nbsp & nbsp & nbsp Probar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Instanciar el objeto OLE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle :=
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp CreateOleObject('VFP_OLE.VFP_OLE_Server')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Resultado := True
& nbsp & nbsp & nbsp Excepto
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Resultado := False
& nbsp & nbsp & nbsp Final
Fin
Procedimiento TFrmFox.RegisterDLL
// Si REGSVR32.EXE existe RegisterDLL()
// se busca VFP_OLE.DLL
// en 2 lugares:
// 1) /Windows/System
// 2) el directorio actual
var a : Array[0..100] of Char
& nbsp & nbsp & nbsp & nbsp sSysDir : Cadena
& nbsp & nbsp & nbsp & nbsp sCurDir : String
Begin
& nbsp & nbsp & nbsp GetSystemDirectory(@a, 100)
& nbsp & nbsp & nbsp sSysDir : =
& nbsp & nbsp & nbsp sSysDir := AddBS(sSysDir)
& nbsp & nbsp & nbsp sCurDir := AddBS(GetCurrentDir)
& nbsp & nbsp & nbsp If FileExists(sSysDir 'REGSVR32.EXE'), a Continuacion, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp If FileExists(sSysDir 'VFP_OLE.DLL') A continuacion, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ''' sSysDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp End Else If FileExists(sCurDir 'VFP_OLE.DLL') A continuacion, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ''' sCurDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Final
& nbsp & nbsp & nbsp End Else Begin
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Elevar la Excepcion.Crear ('No se puede Registrar VFP_OLE.DLL !')
& nbsp & nbsp & nbsp Final
Fin

Practicas
Supongamos que usted tiene una aplicacion de Factura y usted necesita saber la cantidad de dinero que se adeuda, la edad, y que los debe. Su formulario de consulta podria tener este aspecto:
(Insertar Archivo: QForm1.BMP aqui)
Cuando el usuario hace clic en el boton ACEPTAR, la instruccion SQL dinamicamente es creado y enviado a la DLL como un parametro para su procesamiento. Es importante tener en cuenta que la cadena SQL 'En la Tabla' como parte de la declaracion. Sin esto, la aplicacion Delphi no tiene forma de recoger los datos de resultado. Hay 3 maneras que usted puede manejar la creacion de la Tabla: 1) Crear la tabla en la que los usuarios locales directorio temporal con un nombre de archivo estatico. 2) Escribir una funcion que crea un nombre de archivo unico o utilizar la funcion de API de Windows GetTempFileName(). 3) Combinar ambos 1 & 2 y crear un nombre unico en el directorio Temp de Windows. Para los entornos de red, me parece que la opcion 3 es la mas segura. Es igualmente importante utilizar el metodo SetDir() antes y despues de la ejecucion de la Consulta. Esto es asi FoxPro sabe donde encontrar las tablas es que se consultan en contra, y por lo que la aplicacion Delphi puede encontrar el camino de regreso a casa. Si no SetDir() despues de la consulta, entonces hay una posibilidad bastante buena que la aplicacion Delphi no ser capaz de encontrar los componentes externos, como AVI, BMP, WAV o archivos que necesita. Esto es porque FoxPro fisicamente cambia el puntero de directorio.
Este ejemplo asume que el DBF las mesas se encuentran en el mismo directorio que el Delphi ejecutable. La funcion GetTempDir() es un simple contenedor de funcion que utiliza la API de Windows para obtener el directorio temp de windows. La instruccion Select de SQL se crea dinamicamente basado en el numero de Dias de Vencimiento, y el resultado de la tabla se crea en el directorio Temp de Windows en un archivo llamado MyQuery.dbf. Despues De MyQuery.dbf es creado, la Tabla1 objeto se le asigna su contenido y se muestran en la cuadricula.

procedimiento TfrmFox.btnExeQueryClick(Sender: TObject)
Var
& nbsp & nbsp & nbsp sSQLText : String
& nbsp & nbsp & nbsp iRecs : Integer
& nbsp & nbsp & nbsp sAppDir : Cadena
begin
& nbsp & nbsp & nbsp Si bIsFoxOle, a Continuacion, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Obtener la ruta de acceso del directorio de la aplicacion
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp sAppDir :=
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ExtractFilePath(Application.ExeName)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si (e_PastDue.Texto = ')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp e_PastDue.Text := '0'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp sSQLText :=
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Seleccione el Cliente.Nombre,'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Factura.AcctNo, Factura.El equilibrio',
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' (Fecha()-Factura.Fecha) Como la Edad'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Desde el Cliente,Factura'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'Donde'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' (el Cliente.AcctNo = Factura.AcctNo) Y'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' (Fecha()-Factura.Fecha) >= ' e_PastDue.Texto
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ' Pedido Por el Cliente.Nombre,Edad,'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp 'En la Tabla' GetTempDir() 'MyQuery'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asegurese de que el objeto de tabla en la que se lee
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // el resultado es cerrado antes de la consulta
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // se ejecuta.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si Tabla1.Activo, a Continuacion, Empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.Cerrar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asegurese de que la tabla se elimina despues de cerrar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.DeleteTable
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asignar nombre temporal para Tabla1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.TableName := 'MyQuery.DBF'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asignar el Directorio temporal a Tabla1
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.DatabaseName := GetTempDir()
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Conjunto de VFP Defecto en el Directorio donde la
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Fox DBFs son almacenados.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.SetDir(sAppDir)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Ejecutar la Consulta
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp iRecs := vFoxOle.ExeSql(sSQLText)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Label7.Caption := IntToStr(iRecs)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Si (iRecs = 0) Entonces
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MessageDlg('no se Encontro Ningun registro En la Consulta!'
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp ,mtInformation,[mbOK],0)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Else Begin
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // ExeSql() deja el resultado de la tabla de abrir
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // asi que usted puede pre-proceso de la tabla
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // VFP antes de Delphi se Abre.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Estos Indices se utilizan para cambiar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // el orden haciendo clic en el
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp // Cuadricula Titulo.
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Indice De Nombre de Nombre de la Etiqueta')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Indice De la Edad de la Etiqueta de la Edad')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Indice De AcctNo Etiqueta AcctNo')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Indice De Equilibrio de la Etiqueta de Equilibrio')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp vFoxOle.FoxCommand('Cerca de la Base de datos')
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tabla1.Abierto
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Final
& nbsp & nbsp & nbsp End Else Begin
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MessageDlg('VFP_OLE.DLL No se crean Instancias!',
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mtError,[mbOK])
& nbsp & nbsp & nbsp End // Si bIsFoxOle
fin

Con este archivo DLL tiene la capacidad de hacer desde dentro de Delphi, casi cualquier cosa que usted puede hacer desde dentro de FoxPro. No solo se limita a la simple Sustitucion de Macros, pero puede ser utilizado para desarrollar Delphi extremos delanteros que utilizan la base de datos Visual FoxPro estructura. Ahora, no estoy sugiriendo que todos empezamos con Visual FoxPro para nuestro back-ends, pero hace un bonito puente para aquellos de nosotros que estan migrando nuestros DOS aplicaciones de Windows y de FoxPro para Delphi y la necesidad de la velocidad de Rushmore.
Hay un par de advertencias a esta tecnologia el uso de Visual FoxPro se debe tener en cuenta:

  • el manejo de Errores es limitado. Si una instruccion SQL hace referencia a una tabla de FoxPro no puede encontrar, se abre un cuadro de dialogo que pide al usuario por el camino de la misteriosa tabla. Solo despues de que el Escape se pulsa la tecla se genera un error capturable. Por lo que podria ser prudente para comprobar la existencia de las tablas con la funcion Delphi FileExists(), antes de ejecutar la consulta.
  • Los resultados de la consulta se devuelve a veces en Visual FoxPro formato de archivo, algo que Delphi no admite actualmente. El conjunto de resultados necesita ser convertido por la DLL que puede tomar mas tiempo para procesar.
  • Hay 2 tiempo de ejecucion de Visual FoxPro archivos Dll que debe ser distribuido con la aplicacion Delphi que añadir cerca de 3.9 megas el tamaño global de la aplicacion.
  • En el orden legal para distribuir el tiempo de ejecucion de Visual FoxPro Dll o crear la DLL de OLE, debe poseer una copia de Visual FoxPro Profesional version 5 o superior.
    Cambios Desde que Este Articulo Fue WrittenVisual FoxPro version 6 y posteriores no funcionan con el archivo DLL. Debe compilar el objeto COM en un archivo EXE. El EXE pueden estar registrado mediante la ejecucion de una vez en el equipo que van a acceder a ella. RegSvr32.exe no es siempre necesario.


Acceso rápido a datos de foxpro a partir de delphi

Acceso rápido a datos de foxpro a partir de delphi : Multi-millones de consejos para hacer su vida más fácil.
Recommander aux amis
  • gplus
  • pinterest

Comentario

Dejar un comentario

Clasificación

Consejos Y Trucos www.consejosytrucos.net Ciempozuelos, Madrid Extramuros 82 ES-M 28350 Spain 674 192 969
Desarrolladores de Delphide enero de 1999