24 de marzo de 2004

Comparar dos registros completos

La siguiente función permíte comparar de forma simple, dos registros completos de una o diferentes tablas.

Arroja resultado .T. si tanto la estructura como el contenido de cada campo es igual.

? m_CompReg("cVentas","Ventas")

FUNCTION M_COMPREG()
LParameters tcCursor1, tcCursor2
  SELECT (tcCursor1)
  SCATTER NAME OL_01 &&  Posicionado en uno de los registros a comparar
   SELECT (tcCursor2)
  SCATTER NAME OL_02 &&  Posicionado en el otro de los registros a comparar
  RETURN  COMPOBJ(OL_01,OL_02)
ENDFUNC

Julio Rossi

23 de marzo de 2004

Ultimo día "X" de un mes

Función que nos retorna el último día "X" de un mes, como por ejemplo el último día Viernes de Marzo de 2014.
Ejemplo:
*-- Ultimo Viernes de Marzo de 2014
UltimoDia(6,3,2014)

*-- Ultimo Sábado de Diciembre de 2014
? UltimoDia(7,12,2014)
La función y sus parámetros:
FUNCTION UltimoDia(tnDiaSem, tnMes,tnAnio)
*-- tnDiaSem 1=Dom, 2=Lun, 3=Mar, ..., 7=Sab 
  LOCAL ldFecha
  ldFecha = GOMONTH(DATE(tnAnio,tnMes,1),1) - 1
  DO WHILE DOW(ldFecha,1) # tnDiaSem
    ldFecha = ldFecha - 1
  ENDDO
  RETURN ldFecha
ENDFUNC

22 de marzo de 2004

Respaldar Base de Datos MSDE/MS Sql Server con VFP

Muchas veces cuando desarrollamos aplicaciones Cliente/Servidor con MSDE o MS Sql Server deseamos incluir la opción de respaldo. La siguiente función les ayuda a hacerlo.

1.- Nos conectamos a Master
LOCAL lCdb_respaldar,lCdb_dispositivo,lNconex
** Nos conectamos a Master
lNconex=SQLCONNECT('Master')

2.- Tenemos dos formas de hacer el respaldo, Iniciacilzando el Dispositivo de respaldo o agregandole el respaldo a dicho dispositivo
lCdb_respaldar='midb'
lCdb_dispositivo='midispositivo.bak'

2.1- Inicializando el dispositivo
If sqlexec(lNconex,"backup database "+lCdb_respaldar+" to " ;
   +lCdb_dispositivo+" with init") > 0
   =Messagebox('Respaldo Realizado con exito',64,'Respaldo')
Endif

2.2.- Agregando el respaldo al dispositivo
If sqlexec(lNconex,"backup database "+lCdb_respaldar+" to "+lCdb_dispositivo) > 0
   =Messagebox('Respaldo Realizado con exito',64,'Respaldo')
Endif

3.- Como crear un dispositivo de respaldo en caso de no poseerlo.
If sqlexec(lNconex,"sp_addumpdevice 'disk', '"+lCdb_respaldar+"', ;
   'C:Archivos de programaMicrosoft SQL ServerMSSQLBACKUP"+lCdb_respaldar+".BAK'") > 0
   =Messagebox('Dispositivo creado con exito',64,'Respaldo')
Endif
=SQLDISCONNECT(lNconex )

Nota: Para este ejemplo se asumio que se posee una conexión en la base de datos de VFP llamada Master. La ruta de donde se debe crear el dispositivo varia dependiendo la ruta donde se instaló el servidor MSDE o MS Sql Server.

Espero les sirva.

José G. Samper

10 de marzo de 2004

Intercambiando Datos entre VFP 8.0 y .Net mediante XML Web Services

Autor: José G. Samper

Cuando estamos intercambiando datos entre VFP 8.0 y .Net mediante XML Web Services, nos hemos encontrado que la interpretación del Xml por parte a una de las dos herramientas no resulta tan transparente como desearíamos. Con este artículo pretendemos explicar como se realiza de forma sencilla esta trasferencia para que la interpretación sea mucho más sencilla por parte de la herramienta que recibe los datos.

DESDE VFP 8.0 A .NET

ENVIANDO

Si deseamos enviarlo en forma de texto

Cuando deseamos enviar datos desde VFP 8.0 mediante un XML que represente un Dataset este será enviado en forma de texto por consiguiente la interpretación por parte de .Net debe ser de esa forma. Ejemplo:

LOCAL oXMLAdapter AS XMLADAPTER,lcXml AS STRING
LOCAL loXMLAdapter AS XMLADAPTER
LOCAL loDOM, loData, loSchema, loNode
CREATE CURSOR PortalFox (ID i, nombre c(250))
INSERT INTO PortalFox (ID,nombre) VALUES (1,'PortalFox')
lcXml=''
&&&Creamos el Objeto XMLAdapter
oXMLAdapter=CREATEOBJECT('xmladapter')
WITH oXMLAdapter
  .RELEASEXML(.T.) &&& limpiamos el XML por si este objeto fue usado para interpretar otro xml
  .UTF8ENCODED = .F. &&& Colocamos UTF8Encoded en Falso para no tener problemas con los acentos al momento de interpretar el XML
  .ISDIFFGRAM = .F.
  llIncludeBefore = .F.
  llChangesOnly = .F.
  llIsFile = .F.
  lcSchemaLocation = ""
  lcAlias='PortalFox'
&&& Invocamos este metodo por cada tabla que necesitemos incluir en el Dataset
  .ADDTABLESCHEMA(lcAlias,.F.,STRCONV(lcAlias,12,1033),STRCONV("FoxData",12,1033),STRCONV("",12,1034))
&&& convertimos los datos contenidos en las tablas agregadas al esquema a Xml
  .TOXML("lcXml",lcSchemaLocation,llIsFile,llIncludeBefore,llChangesOnly)
ENDWITH
RETURN lcXml

Si deseamos enviarlo en forma de objeto XMLDOM

Cuando deseamos enviar datos desde VFP 8.0 mediante un objeto que represente un “Dataset” este será enviado por SOAP en forma de XMLDOM consiguiente la interpretación por parte de .Net debe ser de esa forma. Ejemplo:

LOCAL oXMLAdapter AS XMLADAPTER,lcXml AS STRING
LOCAL loXMLAdapter AS XMLADAPTER
LOCAL loDOM, loData, loSchema, loNode
CREATE CURSOR PortalFox (ID i, nombre c(250))
INSERT INTO PortalFox (ID,nombre) VALUES (1,'PortalFox')
lcXml=''
&&&Creamos el Objeto XMLAdapter
oXMLAdapter=CREATEOBJECT('xmladapter')
WITH oXMLAdapter
  .RELEASEXML(.T.) &&& limpiamos el XML por si este objeto fue usado para interpretar otro xml
  .UTF8ENCODED = .F. &&& Colocamos UTF8Encoded en Falso para no tener problemas con los acentos al momento de interpretar el XML
  .ISDIFFGRAM = .F.
  llIncludeBefore = .F.
  llChangesOnly = .F.
  llIsFile = .F.
  lcSchemaLocation = ""
  lcAlias='PortalFox'
&&& Invocamos este metodo por cada tabla que necesitemos incluir en el Dataset
  .ADDTABLESCHEMA(lcAlias,.F.,STRCONV(lcAlias,12,1033),STRCONV("FoxData",12,1033),STRCONV("",12,1034))
&&& convertimos los datos contenidos en las tablas agregadas al esquema a Xml
  .TOXML("lcXml",lcSchemaLocation,llIsFile,llIncludeBefore,llChangesOnly)
ENDWITH
loXMLAdapter = CREATEOBJECT('xmladapter')
loXMLAdapter.LOADXML(lcXML)
&&Buscamos la referencia del objeto XMLDOM
loDOM = loXMLAdapter.IXMLDOMELEMENT
loNode = loDOM.childNodes.ITEM(0)
IF loNode.nodeName == "xsd:schema"
  loSchema = loNode
  loData = loDOM.childNodes.ITEM(1)
ELSE
  loSchema = loDOM.childNodes.ITEM(1)
  loData = loNode
ENDIF
lcXML = loSchema.XML + loData.XML
RETURN lcXML

RECIBIENDO

Si estamos recibiendo el XML forma de texto

El error mas común al recibir el Xml en .Net, es que usamos directamente el método ReadXml del objeto Dataset y este normalmente nos devuelve el error "URI no válido: el esquema del URI no es válido.". Ejemplo:

Ws_o_Com  oComWS= new  Ws_o_Com();
string lcXml;
System.Data.DataSet dsEjemplo = new  System.Data.DataSet ();
lcXml = oComWS.metodollamado(this.TextBox1.Text);
dsEjemplo.ReadXml(lcXml);
grdDatasetSample.DataSource= dsEjemplo;
grdDatasetSample.Refresh();

Como deberíamos hacerlo, bueno la forma mas sencilla que he encontrado de hacer esto es creando los objetos System.IO.StringReader y System.Xml.XmlTextReader, los cuales me permiten la correcta interpretación del XML recibido. Ejemplo:

Ws_o_Com  oComWS= new  Ws_o_Com();
string lcXml;
System.Data.DataSet dsEjemplo = new  System.Data.DataSet ();
lcXml = oComWS.metodollamado(this.TextBox1.Text);
System.IO.StringReader Sx =  new System.IO.StringReader(lcXml);
System.Xml.XmlTextReader oXmlReader =  new System.Xml.XmlTextReader(Sx);
dsEjemplo.ReadXml(oXmlReader);
grdDatasetSample.DataSource= dsEjemplo;
grdDatasetSample.Refresh();

Si estamos recibiendo un objeto XMLDOM

Esta es la forma más sencilla de recibir datos desde VFP 8.0 a .Net debido a que .Net interpreta los datos de una forma natural. Hasta el momento solo he podido usar esta forma de recibir datos desde VFP 8.0 cuando le envió datos a un Web Service hecho en .Net, debido a que no he podido encontrar un objeto en VFP 8.0 que .Net lo convierta de forma implícita a Dataset

public bool  ActualizaDatos(DataSet  ds, ref  string cErrorMessage)
   {
        Clientes oClientes = new  Clientes();
        dsEjemplo = oClientes.Actualizar (ds, cErrorMessage);
    }

DESDE .NET A VFP 8.0

ENVIANDO

Si deseamos enviarlo en forma de texto

Cuando deseamos enviar datos desde .Net mediante un Dataset en forma de texto debemos convertir el Dataset en String y consiguiente la interpretación por parte de VFP 8.0 debe ser de esa forma. Ejemplo:

Implementamos un WebMethod que devuelva los datos solicitados y nosotros debemos hacer hacer las conversiones correspondientes.

public String GetClientes()
{
System.Data.DataSet dsEjemplo = new  System.Data.DataSet ();
  Clientes oClientes = new  Clientes ();
  dsEjemplo = oClientes.GetClientes();
System.IO.StringWriter swXML = new System.IO.StringWriter();
dsEjemplo.WriteXml(swXML,System.Data.XmlWriteMode.WriteSchema);
return swXML.ToString();
}

Se recomienda que al momento de generar el XML para ser enviado a VFP 8.0 este sea generado con el esquema para una correcta interpretación de los datos por parte de VFP 8.0

Si deseamos enviarlo en forma de objeto DataSet

Cuando deseamos enviar datos desde .Net mediante un Dataset este será enviado por SOAP en forma de XMLDOM, consiguiente la interpretación por parte de VFP 8.0 debe ser de esa forma. Ejemplo:

Implementamos un WebMethod que devuelva los datos solicitados y SOAP se encarga de hacer las conversiones correspondientes.

public DataSet  GetClientes()
{
  Clientes oClientes = new  Clientes ();
  return oClientes.GetClientes();
}

NOTA: Se recomienda que los dataset que sean enviados desde .Net a VFP 8.0 sean tipeados debido a que si VFP 8.0 recibe un tipo de datos String que no contenga el largo del mismo lo convierte automáticamente en Memo

RECIBIENDO

Cuando invocamos un Web Services de .Net desde VFP 8.0 tenemos dos formas de recibir los datos, esto depende de cómo se haya implementado el WebMethod.

1.- En forma de Objeto, .Net puede devolver un objeto “Dataset” y SOAP lo transporta como un objeto XMLDOM. En estos casos es necesario hacer un Attach del objeto recibido y no un LoadXml. Ejemplo:

LOCAL loNetWebService AS "XML Web Service"
LOCAL loException, lcErrorMsg, loWSHandler
LOCAL loObj, lxXML, loSchema
LOCAL oXMLAdapter AS XMLADAPTER
TRY
  loWSHandler = NEWOBJECT("WSHandler",IIF(VERSION(2)=0,"",HOME()+"FFC")+"_ws3client.vcx")
  loNetWebService = loWSHandler.SetupClient("http://PortalFox/NetWebService.asmx?wsdl", " NetWebService ", " NetWebService ")
  oObj = loNetWebService.wsObject.metodoallamar()
  IF VARTYPE(oObj)="O"
    loSchema = loObj.ITEM(0)
    lxXML = loObj.ITEM(1)
    oXMLAdapter=CREATEOBJECT('xmladapter')
    oXMLAdapter.RELEASEXML(.T.)
    IF VARTYPE(lxXML)="O" AND VARTYPE(loSchema)="O"
      oXMLAdapter.ATTACH(txXML, toSchema)
    ENDIF
  ENDIF
CATCH TO loException
  **Manejo de Errores
FINALLY
ENDTRY

2.- En forma de texto, .Net puede devolver un Xml y SOAP lo transporta como un String. En estos casos es necesario hacer un LoadXml del String recibido y no un Attach, se debe tener en cuenta que si el String recibido no contiene el esquema y no se posee el esquema des mismo no será interpretado por VFP 8.0. Ejemplo:

LOCAL loNetWebService AS "XML Web Service"
LOCAL loException, lcErrorMsg, loWSHandler
LOCAL lxXML
LOCAL oXMLAdapter AS XMLADAPTER
TRY
  loWSHandler = NEWOBJECT("WSHandler",IIF(VERSION(2)=0,"",HOME()+"FFC")+"_ws3client.vcx")
  loNetWebService = loWSHandler.SetupClient("http://PortalFox/NetWebService.asmx?wsdl", " NetWebService ", " NetWebService ")
  lxXML = loNetWebService.wsObject.metodoallamar()
  IF TYPE('lxXML')='C' AND !EMPTY(lxXML)
    oXMLAdapter=CREATEOBJECT('xmladapter')
    oXMLAdapter.RELEASEXML(.T.)
    oXMLAdapter.LOADXML(lxXML)
  ENDIF
CATCH TO loException
  **Manejo de Errores
FINALLY
ENDTRY

Por último lo que les puedo decir es que aunque es muy fácil y practico el intercambio de datos mediante Web Services entre VFP 8.0 y .Net, deben tener en cuenta que esto se realiza mediante paquetes SOAP, así que deben tener mucho cuidado con la cantidad de datos que envían.

Espero les Sirva

José G. Samper

9 de marzo de 2004

Acrónimos

A todos nos ha ocurrido alguna vez, que nos hemos quedado confundidos ante un acrónimo no descrito. ...

Se podría hacer una interminable lista de acrónimos; pero se trata de reflejar sólo los relacionados con nuestro trabajo.

A

  • ACK = (Acknowledgment) Acusar recibo, tomar conocimiento
  • ADO = (ActiveX Data Object)
  • ANSI = (American National Standards Institute) Instituto Nacional Norteamericano de Normas
  • API = (Application Program Interface) Interface de Programa de Aplicación
  • ASCII = (American Standad Code for Information Interchange)
  • ASP = (Active Server Page)

B

  • BCL = (Base Class Library) Librería de Clases Binarias
  • BCP = (Bulk Copy Program) Programa de Copia Masiva
  • BIOS = (Basic Input/Output System) Sistema Básico de Entrada/Salida
  • BIT = (Binary Digit) Digito Binario
  • BLOB = (Binary Large Object) Objeto Grande Binario
  • BPI = (Bits Per Inch) Bits Por Pulgada
  • BPS = (Bits Per Seconds) Bits Por Segundos

C

  • CAD = (Computer Aided Design) Diseño Asistido por Computadora
  • CASE = (Computer Aided Software Engineering) Ingeniería de Software Asistido por Computadora
  • CLR = (Common Languaje Runtime)
  • CLS = (Common Languaje Specifications)
  • COM = (Components Object Model)
  • CR/LF = (Carriage Return/Line Feed) Retorno de Carro/Avance de Línea
  • CSV = (Comma Separated Values) Valores Separados por Comas

D

  • DAO = (Data Access Object)
  • DDE = (Dynamic Data Exchange) Intercambio Dinámico de Datos
  • DLL = (Dynamic Link Library) Librería de Enlace Dinámico
  • DNA = (Distributed Internet Application)
  • DNS = (Domain Name System) Sistema de Nombres de Dominio
  • DOM = (Document Object Model)
  • DSN = (Data Source Name) Nombre de Fuentes de Datos
  • DTD = (Document Type Definition) Definición de Tipo de Documento

E

  • EDI = (Electronic Data Interchange + Electronic Document Interchange) Intercambio Electrónico de Datos + Intercambio Electrónico de Documentos

F

  • FAQ = (Frequently Asked Question) Preguntas Frecuentes
  • FAT = (File Allocation Table) Tabla de Asignación de Archivos
  • FIFO = (First-In, First-Out) Primero en Entrar, Primero en Salir
  • FK = (Foreing Key)
  • FTP = (File Transfer Protocol) Protocolo de Transferencia de Archivos
  • FYI = (For Your Information) Para Su Información

G

  • GB = (Gigabyte) 1024 Megabytes
  • GDI = (Graphics Device Interface) Interface de Dispositivo Grafico
  • GIGO = (Garbage-In, Garbage-Out) Entra Basura, Sale Basura
  • GMT = (Greenwich Meridian Time) Tiempo del Meridiano de Greenwich

H

  • HTH = (Hope This Help) Espero que eso te ayude
  • HTML = (HyperText Markup Languaje) Lenguaje de Marcas HiperTextual
  • HTTP = (HyperText Transfer Protocol) Protocolo de Transmisión de HyperTexto

I

  • I/O = (Input/Output) Entrada/Salida
  • IDE = (Interactive Development Environment) Entorno de Desarrollo Interactivo
  • IIS = (Internet Information Service)
  • IMAP = (Internet Message Access Protocol) Protocolo de Acceso a los Mensajes de Internet. Protocolo para recuperar del servidor mensajes de correo electrónico
  • IMO = (In My Opinion) En Mi Opinión
  • IP = (Internet Protocol) Protocolo de Internet
  • ISDN = (Integral Services Digital Network) Red de Servicios Digitales Integrados
  • ISP = (Internet Service Provider) Proveedor de Servicios de Internet

J

  •  

K

  • KB = (Kilobyte) 1024 Bytes

L

  • LAN = (Local Area Network) Red de Área Local

M

  • MB = (Megabyte) 1024 Kilobytes
  • MRU = (Extensive Mark-up Languaje)
  • MS = (Microsoft Corporation)
  • MSDN = (Microsoft Developer Network)
  • MSN = (Microsoft Network)
  • MTS = (Microsoft Transaction Server)
  • MVP = (Most Valuable Professional) Profesional Mas Valioso

N

  • NIC = (Network Interface Card) Plaqueta Interfase de Red
  • NNTP = (Network News Transfer Protocol) Protocolo de Transferencia de Noticias en Red
  • NTFS = (New Technology File System) Sistema de Archivo de NT

O

  • OCR = (Optical Character Recognition) Reconocimiento Óptico de Caracteres
  • ODBC = (Open DataBase Connectivity) Conectividad en Base de Datos Abierta
  • OEM = (Original Equipment Manufacturer) Fabricante de Equipo Original
  • OLE = (Object Linking and Embedding) Vinculación e Incrustación de Objetos
  • OOP = (Object-Oriented Programming) Programación Orientada a Objeto
  • OS = (Operating System) Sistema Operativo

P

  • PC = (Personal Computer) Computadora Personal
  • PDF = (Portable Document Format) Formato de Documento Portátil
  • PF = (PortalFox)
  • PK = (Primary Key) Clave Primaria
  • PLC = (Programmable Logic Controller) Controlador de Lógica Programable
  • POP = (Post Office Protocol) Protocolo de Oficina de Correos
  • PPP = (Point to Point Protocol) Protocolo Punto a Punto
  • PPTP = (Point to Point Tunneling Protocol) Protocolo Punto a Punto "tunelizado"

Q

  •  

R

  • RAD = (Rapid Application Development) Desarrollo Rápido de Aplicaciones
  • RAID = (Redundant Array of Independents Disks) Matrices Redundantes de Discos Independientes
  • RAM = (Random Access Memory) Memoria de Acceso Aleatorio
  • RDB = (Relational Data Base) Base de Datos Relacional
  • RDBMS = (Relational Data Base Management System) Sistema de Administración de Base de Datos Relacional
  • RDS = (Remote Data Service) Servicio de Datos Remotos
  • RF = (Radio Frequency) Radio Frecuencia
  • RGB = (Red-Green-Blue) Rojo-Verde-Azul
  • RPC = (Remote Procedure Call) Llamada a Procedimiento Remoto
  • RTF = (Rich Text Format) Formato de Texto Enriquecido
  • RTFM = (Read The Fucked Manual) Lee El Jodido Manual

S

  • SDF = (Space Delimited File) Archivo Delimitado por Espacios
  • SDK = (Software Developer's Kit) Juego de Desarrollo de Software
  • SMTP = (Simple Mail Transport Protocol) Protocolo de Transferencia de Correo Simple
  • SOAP = (Simple Object Access Protocol)
  • SOHO = (Small Office, Home Office) Oficina Pequeña, Oficina Hogareña
  • SPT = (SQL Pass Through) Paso a Traves de SQL
  • SQL = (Structured Query Languaje) Lenguajes de Consultas Estructurado
  • SYSOP = (System Operator) Operador del Sistema

T

  • TB = Terabyte (1024 Gigabytes)
  • TCP/IP = (Transmission Control Protocol/Internet Protocol) Protocolo de Control de Transmisión/Protocolo de Internet
  • TIA = (Thanks In Advance) Gracias De Antemano

U

  • UDF = (User Defined Function) Función Definida por el Usuario
  • UPS = (Uninterrumpible Power Supply) Fuente de Alimentación ininterrumpida

V

  • VPN = (Virtual Private Network) Red Privada Virtual

W

  • WAN = (Wide Area Network) Red de Área Amplia
  • WSDL = (Web Services Descript Languaje)
  • WWW = (World Wide Web) Telaraña de todo el mundo

X

  • XML = (eXtensible Markup Languaje) Lenguaje eXtensible de Marcas

Y

  • Y2K = (Year 2 K) Año 2000

Z

  •  

Esta lista, es sólo una primera versión, la iremos enriqueciendo entre todos,

Saludos,

Ana María Bisbé York

5 de marzo de 2004

Breve Reseña sobre los conceptos de Cliente-Servidor

Autor: Antonio Muñoz de Burgos y Caravaca

En definitiva, no hay que confundir el termino "cliente-servidor" en su relación a una aplicación o a un motor de DB, es más, tampoco hay que confundir (no digo que sea tu caso) la palabra "servidor" con lo siguiente, que mi DB vFoxPro o la que fuera este un servidor, poco tiene que ver con lo que es una arquitectura cliente-servidor, tampoco hay que confundir que por el mero caso que utilice un proveedor para conectar a una DB, tengo una aplicación C/S o que la DB es C/S.



Y ahora intentaré de la forma más simple conceptuar cliente-servidor.

(1) Porque hablamos de una aplicación C/S, el requisito base, es porque hay algún modulo (componente) de programación que se encarga de servir algo de forma eficiente y que tiene la capacidad de ejecutarlo en cualquier sitio "menos en el cliente" en resumidas cuentas se ejecuta y se procesa en un servidor o n-Servidores y no en el cliente y no pasa por medio del sistema de comunicación (LAN,WAN,etc) información que no se corresponda con el resultado de lo solicitado.

(2) Porque hablamos de una DB C/S, el concepto es el mismo pero que se encuentra de forma "explicita" en el propio motor de DB.

Básicamente y hablando en un sentido estricto, el PC cliente solicita a otro PC servidor (ordenador anfitrión) que se ejecute una tarea especifica.

El programa cliente cumple dos funciones distintas: por lado debe de ser capaz de gestionar la comunicación con el servidor, solicita un servicio y recibe los datos enviados por el anfitrión. Por otro lado maneja el interfaz (la capa de presentación) con el usuario.

El PC anfitrión (Servidor) básicamente sólo tiene que encargarse de atender la solicitud, procesarla y enviarla de la forma más eficiente, e incluso puede delegar partes en otros servidor que ha su vez tendrán básicamente la misma función.

Se puede ver que el concepto es tan válido para el punto (1) y (2).

La diferencia del punto (2) en cuanto a MSDE, SQL-Server, Oracle con motores de DB como puede ser vFoxPro, Access, es que las primeras tienen de forma "explicita" la capacidad de servir en base al concepto dado.

(1) Puedo tener una aplicación vFoxPro C/S:
Respuesta: SI

(2) La DB de vFoxPro es C/S:
Respuesta: NO

(3) Puedo realizar una aplicación vFoxPro C/S contra una DB vFoxPro:
Respuesta: SI

(4) En este caso puedo tener una DB vFoxPro con capacidad C/S, por medio de un proveedor:
Respuesta: NO

(5) Puedo hacer que mi DB vFoxPro sea C/S:
Respuesta: SI
Es necesario crear un componente que se encargue de dicha función, por sí solo nunca.
El componente debe de ser capaz de recibir solicitudes.
Si realmente necesitas esto, probablemente la mejor opción es dar un salto y utilizar DB que de forma explicita sean C/S.

(6) El componente lo puedo crear exclusivamente en vFoxPro.
Respuesta: SI

(7)Si no me quiero crear un componente, puedo utilizar otras herramientas.
Respuesta: SI
Pero tendrías que utilizar servicios Web, por lo menos las que conozco, se basan en eso.

(8) Puedo tener una aplicación vFoxPro C/S contra DB vFoxPro y que pueda ser accedida por medio de Internet, por redireccionamiento de IP
Respuesta: SI
Creando un componente de escucha y cumpliendo el punto (5)

(9) Según el punto (8) puedo hacer una aplicación C/S y que funcione con redireccionamiento IP, esto solo es posible por medio de una aplicación Web, por ejemplo utilizando IIS, Apache, AFP, WC, etc.
Respuesta: NO, no es necesario utilizar servicios Web, para crear una aplicación C/S en vFoxPro y funcione por medio de una conexión como puede ser Internet.

(10) Entonces puedo saltarme el punto (9)
Respuesta: SI

(11) Entonces como lo hago.
Creando un componente ver el punto (8)

Un ejemplo claro de aplicación C/S en los terminos a lo que nos hemos estado refiriendo es eMans Server, que en su funcionamiento "no" utiliza IIS, Apache, o cualquier otro producto similar o de tipo Web.

La aplicación eMans Server, es una aplicación totalmente distinta y poco tiene que ver con el concepto de mi Web eMans, los caminos de desarrollo son totalmente distintos, la primera eMans Server (es una aplicación C/S con cliente pesado) y mi Web eMans (es una aplicación Web), aunque ambas son aplicaciones C/S.

La Web eMans necesita apollarse en IIS, mientras que eMans Server "no"

Bueno, no aburro más al personal, creo que de este mensaje saldrán unos pocos de K., pero todo sea por la patria ;-))

Saludos,

Antonio Muñoz de Burgos

3 de marzo de 2004

Solucionar Error: SQL: La cláusula GROUP BY falta o no es válida

¿Que pasará? ¿Ya no sirve Visual FoxPro? Antes servía!! Bueno, hay que tomarlo con calma, aquí te decimos cómo solucionarlo y una explicación del por qué ...

La solución y documentación de ésto se encuentra en el siguiente:

--- INFO: SQL SELECT Behavior Changes in Visual FoxPro 8.0 ---
http://support.microsoft.com/?id=813361


También ha sido documentado en el Wiki de VFP:
http://fox.wikis.com/wc.dll?Wiki~Enginebehavior

Despues de leerlos quizás te preguntarás:


"¿Por qué demonios tengo que hacerlo al estilo VFP 8 si antes no era necesario?"

Bueno, hay varios motivos.
  • VFP8 es mas compatible con el estandar ANSI SQL 92, por lo tanto tendras menos problemas a la hora de hacer un upgrade a un servidor de base de datos que cumpla con ese estandar.
  • Las clausulas SQL que lleven agrupacion deberian incluir en sus agrupaciones todos los campos que se proyectan en el SELECT (exceptuando las funciones agregadas). Por que esto?, por que de otro modo se obtienen agrupaciones ambiguas, pues deberias especificar cuales seran los siguientes campos a decidir en caso de que la agrupacion tenga empates. Esas son cuestiones de álgebra relacional (y los estándares ANSI SQL 92).
  • Recuerdas los tiempos de SET STRICTDATE?, es el mismo caso, antes podiamos manejar los sistemas con ambiguedades, pero a la larga tendriamos más problemas.
Puedes usar el comando SET ENGINEBEHAVIOR 70, para salir rápidamente del paso, pero mejor sería corregir tus sentencias SQL para que cumpla con este nuevo requerimiento de VFP8.

Para auxiliarte en esta pesada labor, puedes utilizar la Herramienta llamada "Referencias de Código" o "Code References", esta la encontrarás en el menú Herramientas, puedes ponerte a buscar en todo lo tenga "GROUP BY", con esto encontrarás todos los lugares donde se encuentre tu cadena de búsqueda, así sea una sentencia SQL embebida, o una cadena que se macrosustituirá, o alguna propiedad RowSource de los ListBox y ControlBox, así como también en algún RecordSource de Grids.

Espero te sea de utilidad.

Espartaco Palma Martínez

2 de marzo de 2004

Dimensiones de una imagen

Truco para conocer las dimensiones de una imagen desde VFP.
LOCAL loImagen AS IMAGE
LOCAL lcArchivo, lcNombre, lcRet
lcArchivo = GETPICT()
IF NOT EMPTY(lcArchivo)
  *-- Creo un objeto Image
  loImagen = CREATEOBJECT("Image")
  loImagen.STRETCH = 0
  loImagen.PICTURE = lcArchivo
  lcRet = "Nombre: " + JUSTFNAME(lcArchivo) + CHR(13) + ;
    "Dimensiones: " + ALLTRIM(STR(loImagen.WIDTH)) + ;
    " x " + ALLTRIM(STR(loImagen.HEIGHT))
  loImagen = .NULL.
  RELEASE loImagen
ELSE
  lcRet = "No se selecciono una imagen"
ENDIF
MESSAGEBOX(lcRet)