Recorrer items de clase Empty

353 views
Skip to first unread message

Antonio.xt

unread,
Jan 22, 2015, 6:44:26 PM1/22/15
to publice...@googlegroups.com

Que tal grupo, una pregunta:
¿Hay alguna forma de recorrer los elementos de un objeto empty?

El asunto es este:
Tengo una funcion que crea un objeto Empty en base a un arreglo de 2 dimensiones con los elementos a incluir en el objeto, por ejemplo:

DIMENSION arDatos[2,2]
arDatos(1,1) = 'clave'
arDatos(1,2) = 0
arDatos(2,1) = 'descripcion'
arDatos(2,2) = ""

oDatos = fnCreaObjetoEmpty(@arDatos)

oDatos.clave = 25
oDatos.descripcion = "Descripcion No. 1"

? oDatos.clave
? oDatos.descripcion

*Esta es la funcion que crea el objeto
FUNCTION fnCreaObjetoEmpty(pArDat)
   Local oObjeto, a
   oObjeto = CREATEOBJECT("empty")
   For a=1 to ALEN(pArDat,1)
      ADDPROPERTY(oObjeto, pArDat(a,1), pArDat(a,2))
   Endfor
   Return oObjeto
ENDFUNC

Hasta aqui, ya tengo creado el objeto, pero el arreglo con el que se crea puede ser con cualquier otros datos, es decir, en vez de clave y descripcion puede ser no_doc,fecha,importe, etc.

Entonces despues de asignarle valores a los elementos del objeto necesito "Limpiarlo", se me ocurrio recorrer el objeto como cualquier otro objeto, pero no me permite recorrerlo con FOR EACH.
Habra algun metodo para eso, o con el mismo FOR EACH, por ejemplo:
FOR EACH propiedad IN oObjeto
   ? propiedad
ENDFOR

Si no se puede, igual se vuelve a llamar la funcion para crearlo y se crea vacio, pero estoy buscando una solucion un poco mas...mmm...   mejor, si mas mejor. No, mejor dicho mas profesional.

Gracias y saludos...


Carlos Miguel FARIAS

unread,
Jan 22, 2015, 6:52:35 PM1/22/15
to Grupo Fox
Me parece que lo que tienes que usar es un objeto COLLECTION, funciona parecido y te permite recorrerlo.
Saludos: Miguel, La Pampa (RA)

Antonio.xt

unread,
Jan 22, 2015, 6:58:32 PM1/22/15
to publice...@googlegroups.com

Ok Miguel, voy a probar con ese objeto.

Gracias...

Antonio Meza

unread,
Jan 22, 2015, 7:25:49 PM1/22/15
to publice...@googlegroups.com
A lo mejor te sirva o te de mas ideas una funcion del Maestro Victor Espina


saludos
Antonio Meza

Fidel Charny

unread,
Jan 22, 2015, 7:40:38 PM1/22/15
to publice...@googlegroups.com
Puedes revelar las propiedades con Amembers(laArray,loEmpty)
Luego sería
for i=1 to alen(laArray)
      ? loempty.&laArray[i]
next
O una combinación válida para Evaluate().

Antonio.xt

unread,
Jan 23, 2015, 10:37:27 AM1/23/15
to publice...@googlegroups.com

Gracias compañeros, ya hice las pruebas y ya elabore un procedimiento para lo que necesitaba.
Crear un objeto en base a una clase Empty (para este fin me parecio mejor la clase empty, en vez de Custom o Collection), y crearla en base a un arreglo, poder limpiarla independientemente de la cantidad y nombre de sus propiedades, y vincularla a la propiedad ControlSource.

Miguel, ya probe la clase Collection y aunque se me facilitaba recorrer los items para limpiar las propiedades, se me dificultaba para crearla en base a un arreglo, ademas se me paso mencionar que los items ivan a ir vinculados al ControlSource de los objetos de un Form.

Tocayo, ya habia visto ese procedimiento del maestro Victor, de hecho la idea la tome de ese procedimiento y de una clase de la pagina del maestro Fer de Bozzo.

Fidel, exacto, no me acordaba de esa funcion, y es precisamente la que necesitaba.

Les agradezco...

El procedimiento para limpiar la clase es el siguiente:

DO prLimpiaObjEmpty WITH (oDatos)

******************

PROCEDURE prLimpiaObjEmpty(oEmpty)
   Local laProps, nCount, A, lcProp
   Dimension laProps[1]
   nCount = Amembers(laProps, oEmpty)
   For A=1 to nCount
      lcProp = "oEmpty." + laProps[A]
      Do Case
      Case Vartype(Evaluate(lcProp)) = "C"
         &lcProp = ""
      Case Vartype(Evaluate(lcProp)) = "N"
         &lcProp = 0
      Case Vartype(Evaluate(lcProp)) = "D"
         &lcProp = {//}
      Case Vartype(Evaluate(lcProp)) = "T"
         &lcProp = {/:}
      Case Vartype(Evaluate(lcProp)) = "L"
         &lcProp = .F.
      Otherwise
         &lcProp = ""
      Endcase
   Endfor
ENDPROC


Fernando D. Bozzo

unread,
Jan 23, 2015, 11:05:38 AM1/23/15
to publice...@googlegroups.com
Hola Antonio:

Es un poco lenta la implementación que elegiste, en vez de esto que evalúa la misma propiedad varias veces:


      Do Case
      Case Vartype(Evaluate(lcProp)) = "C"
         &lcProp = ""
      Case Vartype(Evaluate(lcProp)) = "N"
         &lcProp = 0
      Case Vartype(Evaluate(lcProp)) = "D"
         &lcProp = {//}
      Case Vartype(Evaluate(lcProp)) = "T"
         &lcProp = {/:}
      Case Vartype(Evaluate(lcProp)) = "L"
         &lcProp = .F.
      Otherwise
         &lcProp = ""
      Endcase


Te conviene guardar Evaluate(lcProp) en una variable (lcDato) y el vartype(lcDato) en otra (lcTipoDato), así solamente preguntás por lcTipoDato en el DO CASE.


Saludos.-

Victor Espina

unread,
Jan 23, 2015, 11:09:58 AM1/23/15
to publice...@googlegroups.com
Antonio, tu codigo no es optimo porque estas forzando a evaluar VARTYPE() y EVALUATE() por cada branch del DO CASE.  Una forma mas eficiente seria:

PROCEDURE prLimpiaObjEmpty(oEmpty)
   Local laProps, nCount, A, lcProp, uValue, cValueType, uEmptyValue
   Dimension laProps[1]
   nCount = Amembers(laProps, oEmpty)
   For A=1 to nCount
      lcProp = laProps[A]
      uValue = GETPEM(oEmpty, lcProp)
      cValueType = VARTYPE(uValue)
      uEmptyValue = ""
      Do Case
      Case cValueType = "C"
         uEmptyValue = ""
      Case cValueType $ "NFIY"
         uEmptyValue = 0
      Case cValueType = "D"
         uEmptyValue = {}
      Case cValueType = "T"
         uEmptyValue = {//::} 
      case cValueType = "L"
         uEmptyValue = .F.
      Endcase
      store uEmptyValue TO ("oEmpty." + lcProp)
   Endfor
ENDPROC

Fernando D. Bozzo

unread,
Jan 23, 2015, 11:12:41 AM1/23/15
to publice...@googlegroups.com
A esto yo lo llamo "pensamiento en paralelo" :D

Jean Pierre Adonis De La Cruz Garcia

unread,
Jan 23, 2015, 11:27:57 AM1/23/15
to publice...@googlegroups.com
A mi parecer no seria mejor ahorrar unas cuantas lineas en la programacion, si estoy mal, corrijanme.
Pero a mi manera seria asi.

PROCEDURE prLimpiaObjEmpty(oEmpty)
   Local laProps, nCount, A, lcProp, uValue, cValueType, uEmptyValue
   Dimension laProps[1]
   nCount = Amembers(laProps, oEmpty)
   For A=1 to nCount
      lcProp = laProps[A]
      uValue = GETPEM(oEmpty, lcProp)
      cValueType = VARTYPE(uValue)
      uEmptyValue = ""
      uEmptyValue=icase(cValueType = "C", "", cValueType $ "NFIY", 0, cValueType = "D",{}, cValueType = "T",{//::}cValueType = "L",.F.)
      store uEmptyValue TO ("oEmpty." + lcProp)
   Endfor
ENDPROC


Y de esa manera ahoramos de digitar 12 lineas, claro, no se si sera burrada mia lo que escribir, jejeje

Victor Espina

unread,
Jan 23, 2015, 11:59:27 AM1/23/15
to publice...@googlegroups.com
En mi opinion, no debe ahorrar lineas a costa de la legibilidad del codigo.  Ese es un error que comenten mucho los programadores de C/C++, que siempre quieren escribir todo en una sola linea :)

Victor Espina

Víctor Hugo Espínola Domínguez

unread,
Jan 23, 2015, 12:26:15 PM1/23/15
to publice...@googlegroups.com
Hola Jean Pierre

Es más legible así:

      uEmptyValue=icase(cValueType = "C", ""         ;
                      , cValueType $ "NFIY", 0       ;
                      , cValueType = "D",{}          ;
                      , cValueType = "T",{//::}      ;
                      , cValueType = "L",.F.)

Saludos,
Víctor.
Lambaré - Paraguay.

Jean Pierre Adonis De La Cruz Garcia

unread,
Jan 23, 2015, 12:30:18 PM1/23/15
to publice...@googlegroups.com
Perfecto, osea si damos con la idea entonces, bueno, la verdad que toda mi vida que he programado, siempre me ha gustado, reducir lineas de programación, la mayor parte de mis sistemas están en pocas lineas, y es mas robusto, ya que le adiciono al lado && información y ya se mas o menos que hace el sistema, como siemrpe es costumbre.

EL Zorro evoluciona, siempre. 
 

Fernando D. Bozzo

unread,
Jan 23, 2015, 12:56:37 PM1/23/15
to publice...@googlegroups.com
Ojo con la idea de "robusto", que es errónea en este caso. Conozco personas que repiten condiciones varias veces en distintos sitios para que la evaluación sea "más robusta" :D

Lo que hace robusto a un sistema es lo bien programado, diseñado y autodocumentado que esté, y la buena gestión de errores que tenga.




Antonio.xt

unread,
Jan 23, 2015, 1:01:14 PM1/23/15
to publice...@googlegroups.com

Excelente, aun mas optimizado y simplificado.

Les agradezco las sugerencias, y precisamente de los creadores de las clases en que me base.


Y Jean Pierre, burrada, burrada, no es, ya que si se simplifica aun mas el codigo, con menos lineas.

Jean Pierre Adonis De La Cruz Garcia

unread,
Jan 23, 2015, 1:01:50 PM1/23/15
to publice...@googlegroups.com
Excelente y muy precisa tu respuesta lo tomare bien en cuenta.

Atte. Jean Pierre Adonis De la Cruz Garcia.
Reply all
Reply to author
Forward
0 new messages