Libreria qdfoxJSON para serializar y deserializar objetos en VFP

4,917 views
Skip to first unread message

Victor Espina

unread,
Jan 31, 2012, 9:17:04 AM1/31/12
to publice...@googlegroups.com
Saludos amigos.

Una de las tecnologias que he estado estudiando en el marco de JQuery es JSON. JSON es un convenio de sintaxis que permite describir un objeto y su contenido mediante un string, para luego poder recrear el mismo objeto a partir de dicho string.

Aunque su uso se penso inicialmente para JavaScript, la especificacion es lo suficientemente simple y abierta como para permitir implementarlo en casi cualquier lenguaje. A pesar de que existen un par de implementaciones de JSON para VFP, ninguna de las dos me convencio bien fuese por su complejidad o por requerir de librerias externas.

Asi que decidi crear mi propio parser JSON adaptado a Foxpro y de paso le anadi un par de mejoras al estilo "fox" :) Una de las ventajas mas importantes que le veo a esta tecnologia es la de permitirnos crear un objeto completo en una sola instruccion, ej:

oCliente = JSONObject({"nombre: 'Victor Espina', pais: 'Venezuela', status: 'Activo', prospecto: false}")
?oCliente.Nombre --> 'Victor Espina'
?oCliente.Prospecto --> False

Tambien podemos guardar en un campo caracter todo el contenido de un registro de datos:

SELECT clientes
SCATTER NAME oRow MEMO
cData = JSONEncode(oRow)

...

oRow = JSONObject(cData)


Crear una coleccion rapidamente:

oDias = JSONObject("['Lunes','Martes','Miercoles','Jueves','Viernes','Sabado','Domingo']")
?oDias.Count --> 7
?oDias[1] --> "Lunes"
?oDias[7] --> "Doming"


Y muchas otras cosas mas. Pueden bajar el archivo desde aca:

Vean el archivo TEST.PRG y luego revisen la documentacion en el archivo qdfoxJSON.PRG.

Espero les sea de ayuda

Saludos

Victor Espina

Jose Antonio Blasco

unread,
Jan 31, 2012, 10:17:20 AM1/31/12
to publice...@googlegroups.com
Victor, como siempre, simple y efectivo.

Por cierto, el enlace correcto es:

http://vesmbp.no-ip.org/public/qdfoxJSON.rar

Un saludo.

--
Jose A. Blasco
Zaragoza - España

"No hay camino hacia la libertad, la libertad es el camino" - Indira Gandhi

Ing.Daniel Bojorge

unread,
Jan 31, 2012, 10:24:30 AM1/31/12
to publice...@googlegroups.com
Excelente aporte, muy muy bueno.

Gracias por compartir tus conocimientos con nosotros.


Dios L@s Bendiga

Saludos,

Daniel (Con 1 Estrella DCE de Microsoft)
www.debsconsultores.com
Nicaragua

"Si ustedes permanecen unidos a mí, y si permanecen fieles a mis enseñanzas, pidan lo que quieran y se les dará.
(Juan 15:7 DHH)
Bendito el varón que se fía en el SEÑOR, y cuya confianza es el SEÑOR.
(Jeremías 17:7 RV2000)

Carlos Miguel FARIAS

unread,
Jan 31, 2012, 10:51:43 AM1/31/12
to publice...@googlegroups.com
El formato json, para el paso de datos estructurados, es mucho mas simple y compacto que el xml (aunque el xml permite algunas otras cosas que con json no van).
Es más, una de las estructuras de datos que maneja el python internamente, es casi identica a json.
Saludos: Miguel, Santa Rosa (LP)

Victor Espina

unread,
Jan 31, 2012, 11:17:35 AM1/31/12
to publice...@googlegroups.com
Justamente miguel. Eso fue lo que me cautivo de JSON de inmediato, que es algo orientado especificamente a describir objetos, a diferencia de XML que es mucho mas generico.  Cuando vi los ejemplos en JavaScript, de una vez me dije: tengo que tener eso en Fox !! :)

Victor Espina

Ing.Daniel Bojorge

unread,
Jan 31, 2012, 11:24:38 AM1/31/12
to publice...@googlegroups.com
¿Se podrá enviar una variable  JSON de VFP a SQL Server?
Yo paso una tabla entera a SQL Server y ahí hago el proceso, en un procedimiento almacenado.  ¿Cómo sería en el caso de JSON?






Dios L@s Bendiga

Saludos,

Daniel (Con 1 Estrella DCE de Microsoft)
www.debsconsultores.com
Nicaragua

"Si ustedes permanecen unidos a mí, y si permanecen fieles a mis enseñanzas, pidan lo que quieran y se les dará.
(Juan 15:7 DHH)
Bendito el varón que se fía en el SEÑOR, y cuya confianza es el SEÑOR.
(Jeremías 17:7 RV2000)



Victor Espina

unread,
Jan 31, 2012, 12:20:16 PM1/31/12
to publice...@googlegroups.com
Hay varios parsers para SQL escritos en TSQL:


Pero ninguno crea una tabla normal como resultado, sino que crean una tabla del tipo "propiedad, valor".  Seria interesante crear una rutina que permita tomar un string JSON de este tipo:

[['01','PERAS',10.0], ['02','MANZANAS',12.0]]

y sirva para llenar un cursor de esta forma:

DECLARE @items TABLE (
 codigo CHAR(2), 
 nombre CHAR(50), 
 cantidad NUMERIC(10,2))

INSERT INTO @items 
 SELECT codigo, nombre, cantidad FROM dbo.parseJSON(@itemsData)

Si consiguen algo asi, avisenme!! 

Saludos

Victor Espina

Marco Plaza

unread,
Jan 31, 2012, 3:11:07 PM1/31/12
to Comunidad de Visual Foxpro en Español

Hola Victor, gracias por el aporte. Un envoltorio bastante util es
poder convertir cursores completos y viceversa, ej:

cursoraJson('cursor')
jsonaCursor('Cursor')

no sé si lo tienes implementado, traté de descargar el archivo pero se
pega..

Tengo un servidor con FoxIsapi y uso la función que mencioné que se
encuentra en la librería WestWindTools.

la implementación que hacen es como sigue:

Tomado de la ayuda de WWtools

Ej:

"
SELECT company,careof, entered ;
FROM tt_cust ;
into cursor TCustomers ;
order by Company

Resultado:

{"Rows":[{"company":"Avionics Inc. asdasd","careof":"John
Doe","entered":"\/Date(999993232)\/"},{"company":"Avis World
Headquarters","careof":"Steve Herbin","entered":"\/Date(999993232)\/"},
{"company":"BGP Productions","careof":"German Vicencio","entered":"\/
Date(999993232)\/"}]}

Basicamente crea un array de Filas de objetos para cada fila de la
tabla.
Cada objeto contiene propiedades para cada campo "


Otro dato: la ventaja principal de Json es que es soportado
nativamente por javascript, así que un servidor vfp con esta función
puede retornar cursores serializados para controles grid de cualquier
proveedor.

Saludos.

Marco

Victor Espina

unread,
Jan 31, 2012, 4:21:26 PM1/31/12
to publice...@googlegroups.com
Justamente implemente esas funciones hace un rato. Descarga de nuevo el rar y ahi estaran.


ZeRoberto

unread,
Jan 31, 2012, 9:18:09 PM1/31/12
to publice...@googlegroups.com
No puedo bajar el archivo o apagaste tu pc.

Saludos

El 31/01/12, Victor Espina <vesp...@gmail.com> escribió:

Marco Plaza

unread,
Feb 1, 2012, 10:36:16 AM2/1/12
to Comunidad de Visual Foxpro en Español
Víctor, gracias.. pero el enlace no funciona! avísanos para poder
descargarlo..

Saludos

Marco

On 31 ene, 22:18, ZeRoberto <zeroha...@gmail.com> wrote:
> No puedo bajar el archivo o apagaste tu pc.
>
> Saludos
>
> El 31/01/12, Victor Espina <vespi...@gmail.com> escribió:

ZeRoberto

unread,
Feb 1, 2012, 2:51:13 PM2/1/12
to publice...@googlegroups.com
Subelo a algun servidor de archivos
 
Saludos

Ing.Daniel Bojorge

unread,
Feb 1, 2012, 3:07:01 PM2/1/12
to publice...@googlegroups.com
Yo lo bajé, si me autorizan lo subo a algún hosting.


Dios L@s Bendiga

Saludos,

Daniel (Con 1 Estrella DCE de Microsoft)
www.debsconsultores.com
Nicaragua

"Si ustedes permanecen unidos a mí, y si permanecen fieles a mis enseñanzas, pidan lo que quieran y se les dará.
(Juan 15:7 DHH)
Bendito el varón que se fía en el SEÑOR, y cuya confianza es el SEÑOR.
(Jeremías 17:7 RV2000)



Ing.Daniel Bojorge

unread,
Feb 1, 2012, 3:08:39 PM2/1/12
to publice...@googlegroups.com
Este es el enlace que yo usé para bajaro, aún está activo





Dios L@s Bendiga

Saludos,

Daniel (Con 1 Estrella DCE de Microsoft)
www.debsconsultores.com
Nicaragua

"Si ustedes permanecen unidos a mí, y si permanecen fieles a mis enseñanzas, pidan lo que quieran y se les dará.
(Juan 15:7 DHH)
Bendito el varón que se fía en el SEÑOR, y cuya confianza es el SEÑOR.
(Jeremías 17:7 RV2000)



Victor Espina

unread,
Feb 2, 2012, 8:03:02 AM2/2/12
to publice...@googlegroups.com
Mis dsculpas por el link roto. Por razones familiares no he podido estar en línea. Si alguien logro bajar la clase por favor pongala a disposicion de los demás.

Jose Antonio Blasco

unread,
Feb 2, 2012, 10:59:00 AM2/2/12
to publice...@googlegroups.com
No se si te estás refiriendo a esto:

http://www.mediafire.com/?taa6t6sz9dswsju

Un saludo.

El día 2 de febrero de 2012 14:03, Victor Espina <vesp...@gmail.com> escribió:
> Mis dsculpas por el link roto. Por razones familiares no he podido estar en línea. Si alguien logro bajar la clase por favor pongala a disposicion de los demás.

--

Victor Espina

unread,
Feb 2, 2012, 3:08:08 PM2/2/12
to publice...@googlegroups.com
Exacto. Muchas gracias Jose. De todas formas ya encendi de nuevo mi portatil asi que el link original (previo cambio de .com a .org) ya funciona de nuevo.

Les aviso tambien que estoy preparando una segunda interfaz OOP para las funciones que existen ahora en esa libreria, de modo que en lugar de hacer:

cCadena = JSONEncode(objeto)

ahora se podria hacer tambien:

cCadena = JSON.Encode(objeto)

En realidad, debi haberlo hecho asi desde un principio pero no se que me dio por hacerlo como funciones aisladas. :)


Saludos

Victor Espina

Ing.Daniel Bojorge

unread,
Feb 2, 2012, 4:11:20 PM2/2/12
to publice...@googlegroups.com
Gracias


Dios L@s Bendiga

Saludos,

Daniel (Con 1 Estrella DCE de Microsoft)
www.debsconsultores.com
Nicaragua

"Si ustedes permanecen unidos a mí, y si permanecen fieles a mis enseñanzas, pidan lo que quieran y se les dará.
(Juan 15:7 DHH)
Bendito el varón que se fía en el SEÑOR, y cuya confianza es el SEÑOR.
(Jeremías 17:7 RV2000)



Daniel Sánchez

unread,
Feb 2, 2012, 11:13:48 PM2/2/12
to publice...@googlegroups.com
Claro siempre hay que pensar en OOP, así se puede encapsular todo lo relacionado con el objeto y aplicar sus métodos mucho más facil de trabajar y muy usado en el mundo Java y .Net.

Saludos

--
Daniel Sánchez Escobar
Investigación y Desarrollo
Reset Software & Sistemas
Móvil +051-949398047
Trujillo - Perú

Meforero

unread,
Feb 9, 2012, 1:13:04 PM2/9/12
to publice...@googlegroups.com
Buenas tardes a todos...

He leido mucho de json, no entiendo como hace uno para comunicarse con la pagina web que contiene el servicio, tengo una aplicacion en foxpro y me toca llamar un servicio json, pero no veo ejemplos.

Por favor alguien me podria decir donde hay ejemplo con envio de parametros y recogida de parametros ?

Gracias

Jose Diaz

unread,
Feb 9, 2012, 2:47:08 PM2/9/12
to Comunidad de Visual Foxpro en Español
Buenas tardes Victor
Muy buen aporte este que nos hiciste llegar.
Gracias

No tendras un ejemplo de como enviar o recibir datos con JSON y VFP y
usando un servidor en la web con PHP y MYSQL, osea tenieno vfp como
cliente y como servidor php y mysql en la web y que se hablen con
JSON.
Saludos

On 31 ene, 10:17, Victor Espina <vespi...@gmail.com> wrote:
> JSONObject("['Lunes','Martes','Miercoles','Jueves','Viernes','Sabado','Domi­ngo']")

Victor Espina

unread,
Feb 9, 2012, 4:02:06 PM2/9/12
to publice...@googlegroups.com
Excelente idea.

Acabo de modificar la libreria para permitir que la clase JSONObject() pueda ser inicializada con un URL, ej:

object = JSONObject("http://server/resource/id")
?object.Id

Esto nos permitiria invocar un servicio Web, recibir su respuesta en formato JSON y convertir esa respuesta en un objeto que podamos manipular en Fox. Mira el archivo TEST5.PRG en el RAR que les anexo.

Para ENVIAR datos en formato JSON a un recurso web necesitas investigar como hacer un POST desde VFP. Una vez tengas esto, puedes usar el metodo Encode() del objeto JSON para obtener los datos en formato JSON que vas a enviar.

Una cosa importante aqui.  Aunque la especificacion de JSON no indica que los nombres de propiedades deban ir encerrados entre comillas, muchos parsers JSON lo usan asi. qdfoxJSON por defecto NO encierra los nombres de propiedades entre comillas, pero esto se puede cambiar asi:

JSON.quotePropertyNames = .T.

Igualmente, qdfoxJSON usa comillas simples tanto para las propiedades (en caso que quotePropertyNames este en .T.) como para delimitar valores tipo string. Sin embargo, algunos servicios requieren comillas dobles. Esto se puede cambiar de esta forma:

JSON.stringDelimitator = ["]


Aqui les dejo el link para la nueva version:

Victor Espina

Juanpa

unread,
Mar 27, 2012, 7:44:15 AM3/27/12
to Comunidad de Visual Foxpro en Español
Buenos días,

He estado probando la librería qdfoxJSON de Victor y me parece muy
buena, pero me da algún error en algunas operaciones. Estoy intentando
convertir un cusor de VFP en una cadena JSON a través del método
"encodeCursor" para guardarlo en un fichero y posteriormente volver a
convertir esa cadena en un cursor a través del método "parseCursor".
Creo que el problema está cuando alguno de los campos del cursor
contiene puntos, comillas, etc.

La cadena que me genera "encodeCursor" y que luego me da error al
importarla a través de "parseCursor" es la siguiente:

{jsonschema:'cursor',name:'cuperso',rows:[{activo:true,anticipo:
0,caducarcon:@,cadumerpel:@,categoria:'
',codigo:'00081',codletra:'J',codpostal:'19005',comentario:'JUAN PABLO
MARTIN PEINADO
TFNO. FIJO: 949123456/666666666
jua...@hotmail.com -- E-MAIL',ctabanco:'
',cthoraesp:0,direccion:'AVD. BELEÑA, 25C - 4ºA
',duracionct:'
',externo:false,fechaalta:@20111004,fechabaja:@,fechacontr:@,fechanaci:@19751125,irpf:
0,localidad:'GUADALAJARA ',nif:'012345678P
',nombanco:' ',nombre:'JUAN PABLO
MARTÍN
',porcen1:0,porcen2:0,porcen3:0,prhoraesp:0,prhoraext:0,prhoranor:
0,provincia:'GUADALAJARA ',ptepago:0,ptsdiacerr:0,ptsdietac:
0,ptsdietam:0,ptshextra:0,ptshnormal:0,ptssalbas:0,sueldoextr:
0,telefono:'666666666 ',tfnoempre:'
',tipocarcon:' '}],schemax:['CODIGO','C',
5,0,false,false,'','','','','','','','','','',0,0,'CODLETRA','C',
1,0,true,false,'','','','','','','','','','',0,0,'NOMBRE','C',
50,0,true,false,'','','','','','','','','','',0,0,'CATEGORIA','C',
2,0,true,false,'','','','','','','','','','',0,0,'NIF','C',
15,0,true,false,'','','','','','','','','','',0,0,'TELEFONO','C',
15,0,true,false,'','','','','','','','','','',0,0,'DIRECCION','C',
30,0,true,false,'','','','','','','','','','',0,0,'CODPOSTAL','C',
5,0,true,false,'','','','','','','','','','',0,0,'LOCALIDAD','C',
20,0,true,false,'','','','','','','','','','',0,0,'PROVINCIA','C',
20,0,true,false,'','','','','','','','','','',0,0,'COMENTARIO','M',
4,0,true,false,'','','','','','','','','','',0,0,'PTSSALBAS','N',
10,2,true,false,'','','','','','','','','','',0,0,'PTSHNORMAL','N',
8,2,true,false,'','','','','','','','','','',0,0,'PTSHEXTRA','N',
8,2,true,false,'','','','','','','','','','',0,0,'PTSDIETAC','N',
8,2,true,false,'','','','','','','','','','',0,0,'PTSDIETAM','N',
8,2,true,false,'','','','','','','','','','',0,0,'IRPF','N',
5,2,true,false,'','','','','','','','','','',0,0,'PTSDIACERR','N',
8,2,true,false,'','','','','','','','','','',0,0,'PTEPAGO','N',
11,2,true,false,'','','','','','','','','','',0,0,'ANTICIPO','N',
11,2,true,false,'','','','','','','','','','',0,0,'PORCEN1','N',
4,1,true,false,'','','','','','','','','','',0,0,'PORCEN2','N',
4,1,true,false,'','','','','','','','','','',0,0,'PORCEN3','N',
4,1,true,false,'','','','','','','','','','',0,0,'TIPOCARCON','C',
10,0,false,false,'','','','','','','','','','',0,0,'CADUCARCON','D',
8,0,false,false,'','','','','','','','','','',0,0,'CADUMERPEL','D',
8,0,false,false,'','','','','','','','','','',0,0,'ACTIVO','L',
1,0,false,false,'','','','','','','','','','',0,0,'EXTERNO','L',
1,0,false,false,'','','','','','','','','','',0,0,'CTHORAESP','N',
7,2,false,false,'','','','','','','','','','',0,0,'PRHORANOR','N',
7,2,false,false,'','','','','','','','','','',0,0,'PRHORAEXT','N',
7,2,false,false,'','','','','','','','','','',0,0,'PRHORAESP','N',
7,2,false,false,'','','','','','','','','','',0,0,'FECHAALTA','D',
8,0,false,false,'','','','','','','','','','',0,0,'FECHABAJA','D',
8,0,false,false,'','','','','','','','','','',0,0,'CTABANCO','C',
20,0,false,false,'','','','','','','','','','',0,0,'NOMBANCO','C',
30,0,false,false,'','','','','','','','','','',0,0,'FECHANACI','D',
8,0,false,false,'','','','','','','','','','',0,0,'FECHACONTR','D',
8,0,false,false,'','','','','','','','','','',0,0,'DURACIONCT','C',
20,0,false,false,'','','','','','','','','','',0,0,'TFNOEMPRE','C',
20,0,false,false,'','','','','','','','','','',0,0,'SUELDOEXTR','N',
7,2,false,false,'','','','','','','','','','',0,0]}

Me gustaría saber si hay alguna forma de solucionarlo o si Victor
puede realizar alguna mofificación que solucione este problema.

Muchas gracias.

Juan Pablo Martín Peinado
Guadalajara - España

Victor Espina

unread,
Mar 28, 2012, 9:35:05 AM3/28/12
to publice...@googlegroups.com
JuanPa, con la informacion que proporcionaste revisare la rutina a ver cual es el problema y si puedo solucionarlo facilmente.  Como bien dices, el problema probablemente este en el contenido de los campos textos, por ejemplo, si contienen comillas simples o dobles.

Saludos

Victor Espina

Victor Espina

unread,
Mar 28, 2012, 10:42:00 AM3/28/12
to publice...@googlegroups.com
JuanPa, el problema con el string JSON que publicaste es que habian varios CRLF incrustados en el string que causaban el problema al hacer el parsing. Estos CRLFs no fueron introducidos por qdfoxJSON al hacer Parse del cursor original (lo probe).

En todo caso, hice un cambio en la libreria para permitirle manejar caracteres como CRLF, comillas simples y dobles dentro de los valores string, para evitar problemas relacionados con esto.

Puedes descargar la nueva version desde aqui:

Saludos

Victor Espina

Juanpa

unread,
Mar 28, 2012, 10:53:37 AM3/28/12
to Comunidad de Visual Foxpro en Español
Efectivamente, los CRLFs ya estaban en un campo Memo antes de
convertirlo a un string JSON. Tengo algunas tablas con campos Memo en
los que el usuario puede introducir cualquier tipo de caracter.

Voy a probar la nueva versión.

Muchas gracias Victor.

-------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
-------------------------------------

Claudio Luna

unread,
Mar 28, 2012, 1:33:20 PM3/28/12
to publice...@googlegroups.com
Estimado Victor
Probando la librería el procedmiento clone me dió un error.
El mismo estaba definido así.
 PROCEDURE Clone
  RETURN JSONObject(THIS.ToJSON)
 ENDPROC
to.JSON es un procedimiento lo cambié así  y funcionó..
 PROCEDURE Clone
  RETURN JSONObject(THIS.ToJSON())
 ENDPROC
le agregue () a toJSON...

Saludos
Gracias a Victor por estar siempre colaborando al grupo y a todo el foro..

Juanpa

unread,
Mar 29, 2012, 4:43:34 AM3/29/12
to publice...@googlegroups.com
A mi también me ha dado un error en el procedimiento "is"


-------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
-------------------------------------

Victor Espina

unread,
Mar 29, 2012, 9:22:36 AM3/29/12
to publice...@googlegroups.com
JuanPa, que error te dio con ese metodo?  lo acabo de probar y funciona correctamente, hasta donde veo.  Ese metodo de la clase JSONObject permite determinar si el objeto pertenece a un schema dado o no:

oCliente = JSONObject("schema:cliente")
IF NOT oCliente.Is("cliente")
 MESSAGEBOX("Este objeto no es un cliente")
ENDIF

Si te falla, podrias indicarme como hacer para reproducir el problema?

Saludos

Victor Espina

Victor Espina

unread,
Mar 29, 2012, 9:49:25 AM3/29/12
to publice...@googlegroups.com
Encontre un error en los cambios que hice ayer para lo del problema con los CRLFs y comillas. Acabo de subir una nueva version que lo corrije. Adicionalmente, inclui una nueva propiedad llamada "CanonicalNotation" que, al ponerla en .T., hace que la clase genere un string JSON acorde a la sintaxis "oficial".

Pueden descargar la nueva version desde codeWiki:

Saludos

Victor Espina

Juanpa

unread,
Mar 29, 2012, 11:40:24 AM3/29/12
to publice...@googlegroups.com
Ok Victor,

Mañana probaré esta nueva versión y te cuento como me ha ido.

Muchas gracias.

-----------------------------------

Juan Pablo Martín Peinado
Guadalajara - España
-----------------------------------

Juanpa

unread,
Mar 30, 2012, 5:09:26 AM3/30/12
to publice...@googlegroups.com
Hola Victor,

He estado haciendo pruebas con esta última versión y me ha funcionado perfectamente.

Ahora toca ponerse a usarla en producción ya que creo que me va a ser muy util.

Muchas gracias.
-------------------------------------

Juan Pablo Martín Peinado
Guadalajara - España
-------------------------------------


El jueves 29 de marzo de 2012 15:49:25 UTC+2, Victor Espina escribió:

Victor Espina

unread,
Mar 30, 2012, 8:47:02 AM3/30/12
to publice...@googlegroups.com
Me alegro JuanPa.  Mucha suerte con tu proyecto. Cualquier cosa con la libreria no dudes en escribir.

Victor Espina

Juanpa

unread,
Apr 10, 2012, 4:41:24 AM4/10/12
to publice...@googlegroups.com
Hola Victor,

He encontrado otro problemilla en el metodo encodeCursor y luego me da error al utilizar parseCursor. El problema es que no convierte bien algunos avances de linea. He detectado que a veces el avance de línea no está compuesto por: CHR(13) + CHR(10), sino solamente por un CHR(13).

De momento lo he solucionado añadiendo una línea en la PROCEDURE _encodeString, de manera que quede de la siguiente forma:

 HIDDEN PROCEDURE _encodeString(pcString)
  pcString = STRT(pcString, CHR(13) + CHR(10), "%CRLF%")
  pcString = STRT(pcString, CHR(13), "%CRLF%")   && ----- Nueva línea para solucionar el problema.
  pcString = STRT(pcString, CHR(9), [%TAB%])
  pcString = STRT(pcString, ['], [%SINGLEQUOTE%])
  pcString = STRT(pcString, ["], [%DOUBLEQUOTE%])
  RETURN pcString
 ENDPROC

Sería interesante que lo tuvieses en cuenta para futuras versiones o mirar si hay alguna forma mejor de solucionarlo.

Muchas gracias.
---------------------------------------

Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------

Victor Espina

unread,
Apr 10, 2012, 9:22:19 AM4/10/12
to publice...@googlegroups.com
Esta genial JuanPa. Lo unico que te diria es que CHR(13) debe cambiarse por %CR% y no por %CRLF% ya que, como bien dices, no es lo mismo CRLF que CR.

La funcion _encodeString deberia quedar asi:

 HIDDEN PROCEDURE _encodeString(pcString)
  pcString = STRT(pcString, CHR(13), "%CR%")
  pcString = STRT(pcString, CHR(10), "%LF%") 

  pcString = STRT(pcString, CHR(9), [%TAB%])
  pcString = STRT(pcString, ['], [%SINGLEQUOTE%])
  pcString = STRT(pcString, ["], [%DOUBLEQUOTE%])
  RETURN pcString
 ENDPROC

De esta forma tomamos ya en cuenta todos los casos posibles: CRLF, CR o LF. Igual cambio hay que hacer en _decodeString:

 HIDDEN PROCEDURE _decodeString(pcString)
  pcString = STRT(pcString, [%CR%], CHR(13))
  pcString = STRT(pcString, [%LF%], CHR(10))
  pcString = STRT(pcString, [%TAB%], CHR(9))
  pcString = STRT(pcString, [%SINGLEQUOTE%], ['])
  pcString = STRT(pcString, [%DOUBLEQUOTE%], ["])
  RETURN pcString
 ENDPROC

Este cambio ya vendra en la proxima version de la libreria. Mientras, sugiero a todos los que esten usando esta libreria que hagan este cambio manualmente.

Saludos

Victor Espina

Juanpa

unread,
Apr 10, 2012, 9:46:52 AM4/10/12
to publice...@googlegroups.com
Ok, Victor,

Lo cambiaré según sugireres.


---------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------

Juanpa

unread,
Apr 12, 2012, 6:27:52 AM4/12/12
to publice...@googlegroups.com
Hola Victor,

He encontrado un problema en encodeCursor. Cuando un campo del cursor es númerico con decimales, en la procedure _encodeValue lo deja sin decimales redondeando su valor.

He hecho unos cambios que parece que lo solucionan.

En la procedure _encodeValue, cuando es un dato númerico lo he dejado así:

     CASE cType $ "NIYF"   && Numeric value
          IF puValue = INT(puValue)
           cJSONValue = ALLTRIM(STR(puValue))
          ELSE
*           cJSONValue = ALLTRIM(STR(puValue,10))
            lnLongitud = LEN(ALLT(TRANSFORM(puValue)))
            lnDecimales = lnLongitud - AT(",", TRANSFORM(puValue))
            cJSONValue = STRTRAN(ALLT(STR(puValue, lnLongitud, lnDecimales)), ",", ".")
          ENDIF

... y en la procedure Parse cuando es númerico convierto el punto decimal en coma:

          OTHERWISE                   && Numeric value
*               uValue = VAL(cValue)
               uValue = VAL(STRTRAN(cValue, ".", ","))

A ver si puedes revisarlo por si encuentras una solución mejor.

Victor Espina

unread,
Apr 12, 2012, 9:31:35 AM4/12/12
to publice...@googlegroups.com
Gracias por el reporte JuanPa.  El cambio en _encodeValue es correcto; el que tengo que verificar es el del cambiar "." por ","... no entiendo el proposito de ese cambio, ya que VAL() usa "." y no "," como separador decimal.

Saludos

Victor Espina

Juanpa

unread,
Apr 12, 2012, 1:28:39 PM4/12/12
to publice...@googlegroups.com
Hola Victor,

Yo he tenido que hacer ese cambio de "." por "," para que me lo tomase bien. Puede que tenga que ver con la configuración que tengo de SET POINT y SET SEPARATOR. En mi caso lo tengo así:
SET POINT TO ','
SET SEPARATOR TO '.'

Si es así, pienso que habría que hacer algún cambio para que funcione independientemente de como estén configurados esos SET.

Saludos,

---------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------

Victor Espina

unread,
Apr 12, 2012, 2:53:03 PM4/12/12
to publice...@googlegroups.com
Exacto. Tienes razon.

Saludos

Victor Espina

Victor Espina

unread,
Apr 12, 2012, 3:04:04 PM4/12/12
to publice...@googlegroups.com
JuanPa, revise el codigo tanto de _encodeValue como de Parse.  Por un lado, el problema con el _encodeValue era que la linea que decia:

cJSONValue = ALLTRIM(STR(puValue,10))

debio haber dicho:

cJSONValue = ALLTRIM(STR(puValue,30,10))

Eso deberia bastar para considerar cualquier valor numerico hasta con 10 decimales.

Por otro lado, me di cuenta que la configuracion de SET POINT no deberia afectar el funcionamiento de la rutina pues sea cual sea el valor asignado al punto decimal, tanto el STR como el VAL lo tomaran en cuenta. Donde si se podria crear un problema es si recibes un JSON codificado con "punto" como punto decimal y lo tratas de expandir en tu programa con "coma" como punto decimal.  

Saludos

Victor Espina

Juanpa

unread,
Apr 12, 2012, 5:21:59 PM4/12/12
to publice...@googlegroups.com
Hola Victor,

No sé si te has fijado que en el código que he puesto en _encodeValue estoy incluyendo un STRTRAN que me sustituye la "," por ".".
Lo he puesto por que al ser un valor númerico no va entre comillas y al volver a pasarlo a cursor con parseCursor y encontrar una coma lo toma como si fuese el siguiente par de elementos y a partir de ahí se lia y me da error.

De todas formas ahora estoy en mi casa, mañana volveré a probarlo más detenidamente en la oficina incluyendo la modificación que me has comentado.


Saludos,
---------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------


Victor Espina

unread,
Apr 12, 2012, 5:30:21 PM4/12/12
to publice...@googlegroups.com
Ahhhh, tienes razon con eso. Bueno punto con lo de la confusion con la ",". De todas todas hay que converitr el separador decimal en "punto" antes de convertir.

Victor

Rafa Cano

unread,
Apr 12, 2012, 6:04:44 PM4/12/12
to publice...@googlegroups.com
Victor si se va a recibir un numero con muchos decimales y has de pasarlo a string también has de setear SET DECIMAL, ya que sino puedes perder decimales. Yo normalmente cuando paso a carácter información numérica tengo:

SET SEPARATOR TO
SET POINT TO "."
SET DECIMALS TO 10

Una manera en VFP9, de pasar un numero a carácter quitando los decimales no significativos sería:

? LTRIM(RTRIM(RTRIM(TRANSFORM(m.valorNumerico, "9999999999999999.9999999999"), "0"), "."))


Saludos Rafael Cano
Jaén - España
Ronda - Málaga - España

Rafa Cano

unread,
Apr 12, 2012, 6:13:04 PM4/12/12
to publice...@googlegroups.com
La verdad es que sin la máscara funciona igual. pero los RTRIM déjalos.
? RTRIM(RTRIM(TRANSFORM(m.valorNumerico), "0"), ".") 

Muchas veces por querer ser explicito uno riza el rizo.

Victor Espina

unread,
Apr 12, 2012, 9:23:34 PM4/12/12
to publice...@googlegroups.com
Gracias Rafa. Definitivamente tengo que ponerle mas atencion a este asunto.

Saludos

Victor

Juanpa

unread,
Apr 13, 2012, 7:21:03 AM4/13/12
to publice...@googlegroups.com
Buenas,

Resumiento, con las aportaciones que ha hecho Rafa, creo que para pasar los datos númericos al string y teniendo en cuenta que hay que convertir la "coma" decimal en "punto", debería quedar, salvo que ha alguien se le ocurra algo mejor, de la siguiente manera:


     CASE cType $ "NIYF"   && Numeric value
          IF puValue = INT(puValue)
              cJSONValue = ALLTRIM(STR(puValue))
          ELSE
*           cJSONValue = ALLTRIM(STR(puValue,10))
            cJSONValue = STRTRAN(RTRIM(RTRIM(TRANSFORM(puValue), "0"), "."), ",", ".")
          ENDIF

... y al hacer el paso contrario volver a convertir el "punto" en "coma":


          OTHERWISE                   && Numeric value
*               uValue = VAL(cValue)
               uValue = VAL(STRTRAN(cValue, ".", ","))

Saludos,
---------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------


Rafa Cano

unread,
Apr 13, 2012, 7:29:06 AM4/13/12
to publice...@googlegroups.com
Eso estaría equivocado, sería algo así, siendo más general:
cJSONValue = CHRTRAN(RTRIM(RTRIM(TRANSFORM(puValue), "0"), SET("POINT")), SET("POINT"), ".")

He usado CHRTRAN, pero vamos que STRTRAN también funciona.

Juanpa

unread,
Apr 13, 2012, 10:07:54 AM4/13/12
to publice...@googlegroups.com
Ok Rafa,

En ese caso creo que al hacer el paso contrario también habría que utilizar SET("POINT") :


          OTHERWISE                   && Numeric value
*               uValue = VAL(cValue)
*               uValue = VAL(STRTRAN(cValue, ".", ","))
               uValue = VAL(STRTRAN(cValue, ".", SET("POINT")))


Saludos,
---------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------

Victor Espina

unread,
Apr 13, 2012, 10:26:52 AM4/13/12
to publice...@googlegroups.com
El problema JuanPa es que no puedes asumir que la "," es el separador decimal siempre al volver a convertir el valor JSON a numerico.  Lo correcto es unificar el separador al generar la representacion JSON y luego sustituir el separador "universal" por el valor actual de SET POINT antes de hacer el Parse.

Saludos

Victor Espina

Juanpa

unread,
Apr 13, 2012, 10:36:45 AM4/13/12
to publice...@googlegroups.com
Hola Victor,

Creo que no has visto mi último post, en el cual ya incluyo un SET("POINT"), según el consejo de Rafa, para darme el separador decimal.

Un saludo,

---------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------


Victor Espina

unread,
Apr 13, 2012, 11:42:21 AM4/13/12
to publice...@googlegroups.com
SI, no lo habia visto.  Si puedes, enviame el codigo de _encodeValue y Parse para pegarlos en el fuente oficial y sacar ya una nueva version con esas correcciones, vale?

Saludos

Juanpa

unread,
Apr 13, 2012, 12:27:13 PM4/13/12
to publice...@googlegroups.com
Ok Victor,

Dejo comentadas las líneas según las tenías tú.

En el Parse, quedaría así la línea para valores númericos:


          OTHERWISE                   && Numeric value
*               uValue = VAL(cValue)
               uValue = VAL(STRTRAN(cValue, ".", SET("POINT")))

... en _encodeValue así:


     CASE cType $ "NIYF"   && Numeric value
          IF puValue = INT(puValue)
              cJSONValue = ALLTRIM(STR(puValue))
          ELSE
*           cJSONValue = ALLTRIM(STR(puValue,10))
            cJSONValue = CHRTRAN(RTRIM(RTRIM(TRANSFORM(puValue), "0"), SET("POINT")),SET("POINT"), ".")
          ENDIF

Recuerda que también se cambió el código de _encodeString y _decodeString:

 HIDDEN PROCEDURE _encodeString(pcString)
*  pcString = STRT(pcString, CHR(13) + CHR(10), "%CRLF%")

  pcString = STRT(pcString, CHR(13), "%CR%")
  pcString = STRT(pcString, CHR(10), "%LF%")
  pcString = STRT(pcString, CHR(9), [%TAB%])
  pcString = STRT(pcString, ['], [%SINGLEQUOTE%])
  pcString = STRT(pcString, ["], [%DOUBLEQUOTE%])
  RETURN pcString
 ENDPROC
 
 HIDDEN PROCEDURE _decodeString(pcString)
*  pcString = STRT(pcString, "%CRLF%", CHR(13) + CHR(10))

  pcString = STRT(pcString, [%CR%], CHR(13))
  pcString = STRT(pcString, [%LF%], CHR(10))
  pcString = STRT(pcString, [%TAB%], CHR(9))
  pcString = STRT(pcString, [%SINGLEQUOTE%], ['])
  pcString = STRT(pcString, [%DOUBLEQUOTE%], ["])
  RETURN pcString
 ENDPROC

Un saludo,
---------------------------------------
Juan Pablo Martín Peinado
Guadalajara - España
---------------------------------------

Victor Espina

unread,
Apr 14, 2012, 11:16:45 AM4/14/12
to publice...@googlegroups.com
Acabo de actualizar la version en la pagina oficial con los cambios indicados por ti y rafa.  Muchas gracias a ambos.

La version actual es la 1.5

Saludos

Victor Espina

cesarpe

unread,
Mar 13, 2013, 5:39:47 PM3/13/13
to publice...@googlegroups.com, vesp...@gmail.com
Hola Victor,
Al tratar de trabajar con una tabla que tiene valores .NULL. me daba error, pero lo he arreglado con esta línea
esta en el procedimiento PROCEDURE Parse(pcJSON)

cambiar esta línea,
  CASE cValue == "null"

por esta otra:
  CASE UPPER(cValue) == "NULL" OR UPPER(cValue) == ".NULL."

con esto ya no sale ningún error.
Muy bueno el programa.

Saludos 
César.

Fabio Mascarenhas

unread,
Apr 28, 2015, 3:56:42 PM4/28/15
to publice...@googlegroups.com
Boa tarde Vitor,
Muito interessante essa sua classe e estou interessado em utilizá-la.
Eu tenho este conjunto de dados e preciso transformar em uma tabela, como posso utilizar sua classe para isso ?

Este é um exemplo de dados

[{"CNPJ_CPF":"54517628001160","Mes":1,"Ano":2014,"IdProduto":41,"DescrProduto":"Cancelamento - NFCe","Qtde":7},{"CNPJ_CPF":"54517628001160","Mes":1,"Ano":2014,"IdProduto":31,"DescrProduto":"Inutilização – NFCe","Qtde":4},{"CNPJ_CPF":"54517628001160","Mes":1,"Ano":2014,"IdProduto":71,"DescrProduto":"Rejeição - NFCe","Qtde":1035},{"CNPJ_CPF":"54517628001160","Mes":1,"Ano":2014,"IdProduto":2,"DescrProduto":"NFCe","Qtde":1968}]

Qual a melhor função para que transforme estes dados num cursor VFP9 ?

Agradeço a atenção,

Fabio Mascarenhas 

Victor Espina

unread,
Apr 30, 2015, 11:00:50 PM4/30/15
to publice...@googlegroups.com
Fabio, la version actual de qdfoxJSON no soporta lo que quieres hacer, pero un amigo y yo hemos estado trabajando en un nuevo parser JSON 100% VFP para el proyecto ActiveVFP, y que tambien sera usado para la nueva version de qdfoxJSON.

Este nuevo parser incluye un metodo llamado "toCursor()"  que permite tomar un string JSON como el que mencionas y crea un cursor con los datos, sin necesidad de indicar explicitamente la estructura del cursor:

json.toCursor(cString, "QDATA")

SELECT qdata
?CNPJ_CPF   -->  "54517628001160"

Por favor, descarga este nuevo parser desde aqui:

Al inicio de tu programa haz:
DO json

y eso cargara la libreria y creara el objecto "json".


Saludos

Victor Espina

Fernando D. Bozzo

unread,
May 1, 2015, 6:39:01 AM5/1/15
to publice...@googlegroups.com
Hola Victor:

El link no deja bajar el prg y en su lugar se baja una página html con extensión prg.


Saludos.-

Victor Espina

unread,
May 1, 2015, 8:21:44 AM5/1/15
to publice...@googlegroups.com
Problema con el MIME Type.   Deberia funcionar correctamente ahora.     Les recomiendo que abran el archivo y lean los comentarios del inicio. Ahi esta toda la documentacion.

Saludos

Victor

Fernando D. Bozzo

unread,
May 1, 2015, 11:04:15 AM5/1/15
to publice...@googlegroups.com
Perfecto! Ya funciona y ya lo estoy probando.

Una pregunta:
¿Este módulo lo considerás core dentro de tus sistemas FoxPro? o sea, ¿tienen funcionalidad dependiente de este componente?


Saludos!

Victor Espina

unread,
May 1, 2015, 1:20:43 PM5/1/15
to publice...@googlegroups.com
Mira, honestamente hasta ahora nunca he usado fuertemente JSON en mis aplicaciones VFP, y por tanto no tengo otros componentes que dependan de este.   En mis aplicaciones Web si uso JSON constantemente, tanto en el browser como en el lado de servidor y, justamente para esto, es que he estado trabajando en este parser.

Sin embargo, la idea con este parser es tambien empezar a usarlo de forma consistente en mis aplicaciones VFP por las ventajas que ofrece para simplificar codigo. 


Victor

Fernando D. Bozzo

unread,
May 1, 2015, 1:35:22 PM5/1/15
to publice...@googlegroups.com
Estaba haciendo una prueba json con una librería de clases abierta como tabla, y al llegar a cierto registro da un error. ¿Preferís que te reporte al foro o en privado?



Victor Espina

unread,
May 1, 2015, 7:13:48 PM5/1/15
to publice...@googlegroups.com
Si quieres en privado, y enviame la tabla y el PRG que estas usando para probar.

Saludos

Victor

Hugo C.

unread,
May 1, 2015, 7:51:07 PM5/1/15
to publice...@googlegroups.com
Gracias por el dato Victor, para probar.

Saludos.

Victor Espina

unread,
May 2, 2015, 7:36:05 AM5/2/15
to publice...@googlegroups.com
Encontrado el error y corregido.  No se me habia ocurrido intentar convertir a JSON un archivo SCX.    Puedes bajar la nueva version desde el mismo link original.

Saludos

Victor

Fernando D. Bozzo

unread,
May 2, 2015, 9:37:15 AM5/2/15
to publice...@googlegroups.com
Hola Victor:

Ahora da un error por tipo de dato incorrecto cuando indicás el tercer parámetro de la sesión de datos (igual al ejemplo que te pasé):





Victor Espina

unread,
May 2, 2015, 9:57:23 AM5/2/15
to publice...@googlegroups.com
Corregido,  Puedes descargar de nuevo desde el mismo link.

Victor

Fernando D. Bozzo

unread,
May 2, 2015, 10:19:57 AM5/2/15
to publice...@googlegroups.com
Genial, ya va bien.

Saludos.-


mapner

unread,
May 2, 2015, 10:44:43 AM5/2/15
to publice...@googlegroups.com
Hola Victor,

Uso JSON en aplicaciones web. Librerías JS Ajax como www.jeasyui.com hacen uso intensivo de esta tecnología para comunicar datos con el backend. Estando disponible para VFP con esta herramienta lo podremos probar como objetos COM invocables por PHP u otro lenguaje para generación de datos. Muy bueno!

Se agradece el aporte.

Saludos!

Victor Espina

unread,
May 2, 2015, 12:35:56 PM5/2/15
to publice...@googlegroups.com
Exacto! Yo lo uso para pasar datos entre el browser y el servidor mediante servicios REST en ActiveVFP.   Funciona genial! 

Victor

mapner

unread,
May 2, 2015, 12:48:13 PM5/2/15
to publice...@googlegroups.com
Que bueno. Una consulta, sabes si es posible correr ActiveVFP en Apache web server?

Saludos!

Victor Espina

unread,
May 2, 2015, 1:56:05 PM5/2/15
to publice...@googlegroups.com
Mira, teoricamente yo pensaria que si, por que al final del dia es como un ASP normal (PHP, JSP, ASP.NET).  Claro, solo Apache sobre Window.  Encontre este link donde en teoria explican como configurar el apache para soportar ActiveVFP:



Saludos

Victor

mapner

unread,
May 2, 2015, 5:59:26 PM5/2/15
to publice...@googlegroups.com
Hola,

encontré un buen tutorial para hacer andar ASP en Apache, lo probé en WAMP y funcioná bien.


Ahora viene el tema de como hacer andar ActiveVFP en Apache, seguiremos investigando.

Saludos

Victor Espina

unread,
May 2, 2015, 6:37:19 PM5/2/15
to publice...@googlegroups.com
Acabo de publicar una actualizacion para JSON.PRG que permite usar expresiones para asignar el valor de un elemento del JSON, asi como tambien elementos del mismo JSON definidos anteriormente, ejemplo:

PRIVATE nEdad, cJSON
nEdad
= 44
TEXT TO cJSON NOSHOW
{
  nombre
: "Victor Espina",
  edad
: nEdad,
  a
ñoNac: (YEAR(GOMONTH(DATE(), -(12 * THIS.edad))))
}
ENDTEXT
oVES
= json.Parse(cJSON)
?oVES.nombre - "Victor Espina"
?oVES.edad - 44
?oVES.añoNac - 1971




La descarga sigue estando en el link original:

Saludos

Victor Espina

HernanCano

unread,
May 2, 2015, 11:47:07 PM5/2/15
to publice...@googlegroups.com
Chévere, Víctor.

Me interesa saber cómo reconfigurar Apache para que funcione con algunas aplicaciones que originalmente sólo funcionarían en IIS.

Pero tu link da info en polaco. ¿Alguien me ayuda? Me defiendo con español e inglés....

Fernando D. Bozzo

unread,
May 3, 2015, 7:12:29 AM5/3/15
to publice...@googlegroups.com
Hola Hernán:

Podés usar el servicio de Google Translate para poner la url del sitio y que te lo traduzca. Yo lo estoy haciendo para chuzmear un pcoo :)


mapner

unread,
May 3, 2015, 9:26:52 AM5/3/15
to publice...@googlegroups.com
Hola,
en un post anterior en este mismo hilo puse un Link con un buen tutorial para hacer funcionar aplicaciones ASP en Apache. lo he probado y funciona OK. Otra alternativa que al parecer funciona es usar el proyecto MONO (un émulo de .NET pero multiplataforma).

Saludos

Carlos Alfaro

unread,
Jan 22, 2018, 7:51:14 PM1/22/18
to Comunidad de Visual Foxpro en Español
Hola Victor, como vas en el proceso de preparar esa nueva librería con el encode? estoy trabajando en un proyecto en Costa Rica, para la facturación electrónica y todo se hace a traves de un apirestfull y pasa objetos de Jason, hay una comunidad de usuarios de visual fox pro en nuestro pais pero todos andamos parecidos con problemas de comunicación en el API.


Saludos 
Carlos Alfaro

El jueves, 2 de febrero de 2012, 14:08:08 (UTC-6), Victor Espina escribió:
Exacto. Muchas gracias Jose. De todas formas ya encendi de nuevo mi portatil asi que el link original (previo cambio de .com a .org) ya funciona de nuevo.

Les aviso tambien que estoy preparando una segunda interfaz OOP para las funciones que existen ahora en esa libreria, de modo que en lugar de hacer:

cCadena = JSONEncode(objeto)

ahora se podria hacer tambien:

cCadena = JSON.Encode(objeto)

En realidad, debi haberlo hecho asi desde un principio pero no se que me dio por hacerlo como funciones aisladas. :)


Saludos

Victor Espina

Leonardo jauregui

unread,
Mar 30, 2018, 3:00:47 PM3/30/18
to Comunidad de Visual Foxpro en Español
Hola Victor, excelente la clase me encanto y comenze a usarla en un proyecto de varios años.
Quería comentarte que encontré un error no es de syntaxys pero es algo parecido que hace fallar un método.
La libreria la baje de codeplex hace un momento... creo que es la ultima version (1.8) https://archive.codeplex.com/?p=qdfoxjson

Aqui el metodo con el error:
 HIDDEN PROCEDURE _isCollection(puValue)
  RETURN (VARTYPE(puValue) = "O" AND PEMSTATUS(puValue,"BaseClass",5) AND LOWER(puValue.baseClass == "collection"))
 ENDPROC

Aqui solucionado:
 HIDDEN PROCEDURE _isCollection(puValue)
  RETURN (VARTYPE(puValue) = "O" AND PEMSTATUS(puValue,"BaseClass",5) AND LOWER(puValue.baseClass) == "collection")
 ENDPROC


En si es una pelotudes como decimos los argentinos ;) simplemente cerraste el "(" de LOWER luego dela comparacion en vez de antes. 

Gracias por compartir esta libreria con todos! Esta genial!
Un saludo!

Moises Ruiz

unread,
Aug 30, 2020, 6:38:40 PM8/30/20
to Comunidad de Visual Foxpro en Español
Hola buenas con todos.

Para comentarles que estoy tratando de jalas los datos de una web service, pero sin embargo si en una linea de caracteres tiene una tilde o un apostrofe, lo que me jala solo la primera letra entes del la tilde o el apostrofe.
1.PNG

y el resultado de la consulta me sale asi.

2.PNG
  
y esto es lo que tengo en la web service

3z.PNG
 espero me puedan ayudar. se les agredecere muy gustosamente.

Edwin Duran

unread,
Aug 30, 2020, 7:52:12 PM8/30/20
to Comunidad de Visual Foxpro en Español

Víctor Hugo Espínola Domínguez

unread,
Aug 30, 2020, 10:47:31 PM8/30/20
to publice...@googlegroups.com
\u00b4 está en formato UniCode Escape Sequence 00b4 (180 en decimal) es el código del carácter, para convertir los caracteres codificados puedes usar esta función:

Function UCES2Chr(tcTexto As String) As String

Local lcBSu As String, ;
lcChr As String, ;
lcHex As String, ;
lcTexto As String, ;
lnPos As Number

lcTexto = m.tcTexto
Do While "\u" $ m.lcTexto
    lnPos = At("\u", m.lcTexto)
    lcBSu = Substr(m.lcTexto, m.lnPos, 6)
    lcHex = "0x" + Right(m.lcBSu, 4)
    lcChr = Chr(Evaluate(m.lcHex))
    lcTexto = Strtran(m.lcTexto, m.lcBSu, m.lcChr)
Enddo

Return m.lcTexto 

Saludos,
Víctor.
Lambaré - Paraguay.



--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/c92c6705-dfb4-46e3-b061-a14d92af45e3n%40googlegroups.com.

Marco Plaza

unread,
Aug 31, 2020, 2:52:02 AM8/31/20
to Comunidad de Visual Foxpro en Español

Es así Víctor.. pero no se compliquen, nFJson implementa el soporte para unicode.

Google no devuelve nfJson cuando buscas "foxpro json parser"
hay que escribir "foxpro json parser github" para que devuelva páginas de github!.
(hay mucho contenido de VFP que no se muestra a menos que coloquemos github en la búsqueda )

Para convertir tu Json fácilmente en un objeto  descarga nfJsonRead:

y simplemente llamas la función:

oRespuesta = nfJsonRead( m.miJsonString )

Para crear json de vuelta ( y no necesitas enviar propiedades sensibles al tamaño de letra )
puedes convertir a json un objeto basado en empty usando miJson = nfJsonCreate( miObjeto ).

( descargas nfJsonCreate de la página del proyecto ).

Adicionalmente, si el objeto que quieren crear tiene muchos niveles, arrays etc., es muy tedioso
( y poco manejable ) usar multiples addproperty.. en su lugar pueden usar underscore.prg

Ahí está la guia, pero el test.prg se explica solo:

Saludos.

Irwin Rodriguez

unread,
Aug 31, 2020, 2:53:07 AM8/31/20
to publice...@googlegroups.com
Hola Moises, con JSONFox obtienes los caracteres especiales de forma automática:

Do LocFile("JSONFox", "app", "open")
Text to jsonstr noshow
{"result":"success","data":{"ruc":"20602682928","razon":"D\u00b4 IMPORT AMAZONAS S.A.C.","estado":"ACTIVO","condicion":"HABIDO","ubigeo":"250101","tipo_via":"JR.","nombre_via":"JULIO C. ARANA","codi_zona":"-","tipo_zona":"-","numero":"101","interior":"-","lote":"-","depa":"-","manzana":"-","kilometro":"-"}}
endtext
obj = _Screen.json.parse(jsonstr)
?obj.data.razon && D´ IMPORT AMAZONAS S.A.C.

Saludos!

Roxana

unread,
Feb 20, 2021, 5:45:21 AM2/20/21
to Comunidad de Visual Foxpro en Español
Estimados,

Veo que esta version tiene problema con los numericos grandes y con los numericos con decimales. Tienen alguna version que resuelva esto?

Les comprato mi codigo:
SET PROCEDURE TO qdfoxJSON
JSONStart()

?"JSON Test #1"
?"Version " + JSON.Version
?
?"THIS TEST SHOWS HOW TO USE ENCODE AND DECODE OBJECTS USING JSON HELPER"
?
?"Creating test object..." 

LOCAL o
#IF VERSION(5) >= 800
 o = CREATEOBJECT("Empty")    && Empty object
#ELSE
 o = CREATEOBJECT("JSONEmpty")
#ENDIF
AddProperty(o, "version",1)
AddProperty(o, "CUIT",27243715089)
AddProperty(o, "importe",1025)

Con estos datos el JSON que arma es asi: 
{cuit:2.724E+10,importe:1025,version:1}

Y si en importe pongo 1025.25 directamente da error.
Alguien ya estuvo luchando con esto?

Les agradezcon de ante mano cualquier ayuda.

Saludos,

Roxana

Edwin Duran

unread,
Feb 20, 2021, 3:44:55 PM2/20/21
to Comunidad de Visual Foxpro en Español
Prueba con esto, se ha mejorado mucho y e json lo puedes convertir a cursor https://groups.google.com/g/publicesvfoxpro/c/tebg6lCTvcU/m/sIN9p9brBQAJ

Marco Plaza

unread,
Feb 20, 2021, 8:19:32 PM2/20/21
to Comunidad de Visual Foxpro en Español

Puedes usar nfJson y probar las funciones "e()"  y "_()" de nfTools para crear y añadir propiedades a objetos.
Descarga estos 3 programas:

 y con una sola línea podrás crear el objeto y obtener el json:  

<pre>
#DEFINE PRETTY .T.

* si tu objeto tiene menos de 14 propiedades, puedes usar  e() :

?  nfJsonCreate(  e("version",1,"CUIT", 27243715089,"importe",1025)  ,  PRETTY  )

* si prefieres una forma mas es mas estructurada, puedes usar _() :

o = create('empty')

with _(m.o)
.version = 1
.cuit = 27243715089
.importe = 1025
endwith

? nfJsonCreate( m.o , PRETTY  )

</pre>

Saludos.
Reply all
Reply to author
Forward
0 new messages