Llamar metodo de un checkbox dentro del Grid

1,183 views
Skip to first unread message

Misael Rocha P

unread,
Feb 25, 2013, 3:39:48 PM2/25/13
to publice...@googlegroups.com
Buenas tardes, respetuosamente me dirijo a Ustedes para solicitarles su valiosa ayua ante mi situacion, originalmente era solo espectador ahora me uno a la comunidad de Visual FoxProm, agradeciendo de antemando por su apoyo paso a comentarles lo que sucede
 
Al cargar mi formulario llama una propiedad  "llamaGrdPagos" la cual le da formato al Grid, le añade sus campos y sus 2 checkbox SI y NO, así también la informacion de una consulta desde mi cursor y en si lo que necesito que visualmente tenga y contenga el Grid y hasta ahi todo funciona como lo necesito no hay ningun error en el codigo solo que ahora no se como hacerle pues necesito poder controlar los eventos en tiempo de ejecucion de los check si selecciono SI se pone en blanco NO y viceversa, y me he truncado pues los checkbox los añado desde el metodo donde le doy forma al Grid

.column5.removeobject("Text1") 
.column5.addobject("chkPagoSi","Checkbox")

.column6.removeobject("Text1") 
.column6.addobject("chkPagoNo","Checkbox")
 
entonces en tiempo de diseño podria, pero no existen pues en tiempo de ejecucion elimino los texbox y añado los check, he ahi mi problema existencial :D
 
como podria hacerle Saludos :D

Pablo Daniel Lissa

unread,
Feb 25, 2013, 4:09:28 PM2/25/13
to publice...@googlegroups.com
Hola:

Me resulta un poco complejo pensar en una solución para el problema que planteas. No estoy diciendo que no se pueda hacer, pero me resultaría más sencillo pensar, por ejemplo, en un ComboBox con los valores Sí/No, o un solo CheckBox, al fin que necesitas manejar solamente dos estados posibles.

Saludos.

Víctor Hugo Espínola Domínguez

unread,
Feb 25, 2013, 4:18:50 PM2/25/13
to publicesvfoxpro
Hola Misael

No sé si entendí lo que pretendes:

PROCEDURE grdPagos.chkPagoSi.InteractiveChange

This.Parent.chkPagoNo.Value = ! This.Value

ENDPROC
PROCEDURE grdPagos.chkPagoNo.InteractiveChange

This.Parent.chkPagoSi.Value = ! This.Value

ENDPROC

Saludos,
Víctor.


Misael Rocha P

unread,
Feb 25, 2013, 4:30:13 PM2/25/13
to publice...@googlegroups.com
Hola, Muchas Gracias Pablo por responder, analizando lo que me comentas pues si seria una solucion rapida aunque pues si me gustaria sifuera posible tal planteamiento, adjunto imagen de las grids son dos grd_DbfCobranza(izquierda) y grd_DbfPagos(derecha) este ultimo con los checkbox cargados desde el metodo llamaGrdPagos pues resulta que al seleccionar un cliente del grd_DbfCobranza valga la redundancia llama el metodo llamaGrdPagos y son 14 registros por default que se cargan que son las fechas de los proximos pagos que van a realizar los clientes, entonces si yo selecciono SI y al guardar los datos cumple la condicion que realizo el pago correspondiente a dicha fecha, de lo contrario si es NO, ese registro pretendo copiarlo a una tabla que se llame dbf_CuentasxCobrar.
 
Gracias Victor Hugo por responder de ser asi donde lo coloco pues el checkbox está añadido en tiempo de ejecucion?? perdon quise decir como lo llamo al dar click en el checkbox()?
pagos.png

Pablo Daniel Lissa

unread,
Feb 25, 2013, 4:59:03 PM2/25/13
to publice...@googlegroups.com
Bueno, entonces.

Ahí va un ejemplo con BINDEVENT( ):

CREATE CURSOR c_datos (nro i, fechaPago d, abono n(8,2), saldo n(8,2), si l, no l)
INSERT INTO c_datos VALUES (1, DATE(), 200, 9800, .F., .F.)
INSERT INTO c_datos VALUES (2, DATE(), 100, 9700, .F., .F.)
GO TOP


LOCAL oForm as Form
oForm = CREATEOBJECT("Form")
WITH oForm as Form
    .WindowType = 1
    .Width = 500
    .AddObject("grdPagos", "MiGrilla")
    .grdPagos.RecordSource = "c_datos"
    .grdPagos.RecordSourceType = 1
    .grdPagos.Visible = .T.
    .Show()
ENDWITH


DEFINE CLASS MiGrilla as Grid
    ColumnCount = 6
    Width = 500
   
    PROCEDURE Init
        WITH this.Column5 as Column
            .RemoveObject("Text1")
            .AddObject("chkPagoSi", "CheckBox")
            .chkPagoSi.Caption = ""
            BINDEVENT(.chkPagoSi, "InteractiveChange", this, "seleccionarSi")
            .Sparse = .F.
            .Header1.Caption = "Sí"
        ENDWITH

        WITH this.Column6 as Column
            .RemoveObject("Text1")
            .AddObject("chkPagoNo", "CheckBox")
            .chkPagoNo.Caption = ""
            BINDEVENT(.chkPagoNo, "InteractiveChange", this, "seleccionarNo")
            .Sparse = .F.
            .Header1.Caption = "No"
        ENDWITH
    ENDPROC
   
   
    PROCEDURE seleccionarSi
        replace no WITH .F. IN (this.RecordSource)
    ENDPROC

    PROCEDURE seleccionarNo
        replace si WITH .F. IN (this.RecordSource)
    ENDPROC
ENDDEFINE

Obviamente, si tu grilla no es una clase y no contiene esos métodos delegados (SeleccionarSi y SeleccionarNO) conviene no usar BINDEVENT dentro de los métodos de la grilla. Por ejemplo, si son métodos del formulario, tendrías que escribir algo como:
            BINDEVENT(thisform.grdPagos.Column6.chkPagoNo, "InteractiveChange", thisform, "seleccionarNo")
luego de haber configurado la grilla.

Espero que te sirva. Saludos.

FidelJ

unread,
Feb 25, 2013, 5:01:11 PM2/25/13
to publice...@googlegroups.com
* Suponiendo que el ControlGrid se llame "Grilla"
* Suponiendo que las columnas afectadas son la 6 y la 7

* Creamos un Método en el formulario llamado "SoluProb"
* Metodo Soluprob
LOCAL LoObje
nEv=AEVENTS(gaEvent,0)
IF nEv=0
RETURN
ENDIF
LoObje=gaEvent[1]
lValor=loObje.Value
oColumn=LoObje.Parent
oControl=ocolumn.ControlSource
nos=ALINES(gaControl,oControl,1,".")
cTabla=gaControl[1]
cCampo=gaControl[2]
SELECT (cTabla)
do case
case Upper(cCampo)==THISFORM.CAMPOSI
replace (Thisform.CampoNo) with !lValor
CASE uPPER(cCampo)==thisform.campoNo
replace (Thisform.CampoSi) with !lValor
endcase


*********************************
* Despues de crear la cuadrícula
*********************************
WITH thisform.Grilla
.Columns[6].REadonly=.f.
.Columns[7].Readonly=.f.
ENDWITH
* Agregamos dos propiedades con el nombre de los campos
* que supongo "PAGOSI" Y "PAGONO", ambos "L"

WITH thisform
.Addproperty("CampoSi","PAGOSI")
.ADDPROPERTY("CampoNo","NOPAGO")
ENDWITH
objGrid=Thisform.Grilla
FOR i=6 TO 7
BINDEVENT(objGrid.Columns[i].Check1,"click",This,"SoluProb")
NEXT

*****************************
* Destroy del Form
*****************************
UNBINDEVENTS(Thisform.Grilla)


Cambia los nombres de ControlGrid y Columnas como te haga falta.

FidelJ

unread,
Feb 25, 2013, 5:06:41 PM2/25/13
to publice...@googlegroups.com
Bueno, se armó un lío entre PAGONO Y NOPAGO.

*********************************
* Despues de crear la cuadrícula
*********************************
WITH thisform.Grilla
 .Columns[6].REadonly=.f.
       .Columns[7].Readonly=.f.
ENDWITH
* Agregamos dos propiedades con el nombre de los campos
* que supongo "PAGOSI" Y "PAGONO", ambos "L"

WITH thisform
  .Addproperty("CampoSi","PAGOSI")
       .ADDPROPERTY("CampoNo","PAGONO")
ENDWITH
objGrid=Thisform.Grilla
FOR i=6 TO 7
     BINDEVENT(objGrid.Columns[i].Check1,"click",This,"SoluProb")
NEXT

Ahora puede. En mi modelo de prueba tenía otros nombres. Sorry.


El lunes, 25 de febrero de 2013 17:39:48 UTC-3, Misael Rocha P escribió:

Ricardo Pina

unread,
Feb 25, 2013, 5:47:13 PM2/25/13
to Grupo VFP
Hola Misael
 
Tomando el ejemplo de Pablo te pongo otra variante para que veas lo vérsatil que es nuestro Zorro.
 
CREATE CURSOR c_datos (nro i, fechaPago d, abono n(8,2), saldo n(8,2), si l, no l)
INSERT INTO c_datos VALUES (1, DATE(), 200, 9800, .F., .F.)
INSERT INTO c_datos VALUES (2, DATE(), 100, 9700, .F., .F.)
GO TOP

LOCAL oForm as Form
oForm = CREATEOBJECT("Form")
WITH oForm as Form
    .WindowType = 1
    .Width = 500
    .AddObject("grdPagos", "MiGrilla")
    .grdPagos.RecordSource = "c_datos"
    .grdPagos.RecordSourceType = 1
    .grdPagos.Visible = .T.
    .Show()
ENDWITH

DEFINE CLASS MiGrilla as Grid
    ColumnCount = 6
    Width = 500
   
    PROCEDURE Init
        WITH this.Column5 as Column
            .RemoveObject("Text1")
            .AddObject("chkPagoSi", "MiCheckSi")
            .chkPagoSi.Caption = ""

            .Sparse = .F.
            .Header1.Caption = "Sí"
        ENDWITH
        WITH this.Column6 as Column
            .RemoveObject("Text1")
            .AddObject("chkPagoNo", "MiCheckNo")
            .chkPagoNo.Caption = ""

            .Sparse = .F.
            .Header1.Caption = "No"
        ENDWITH
    ENDPROC
ENDDEFINE
   
DEFINE CLASS MiCheckSi as CheckBox
    PROCEDURE Interactivechange
            replace no WITH .F. IN (thisform.grdPagos.RecordSource)
    ENDPROC
ENDDEFINE
DEFINE CLASS MiCheckNo as CheckBox
    PROCEDURE Interactivechange
        replace si WITH .F. IN (thisform.grdPagos.RecordSource)
    ENDPROC
ENDDEFINE
 
Saludos 
--
            

                   Ricardo Pina

Desarrollo y Servicios Informáticos

                  Profesionales
               www.dsip.com.ar

 

 

Misael Rocha P

unread,
Feb 25, 2013, 5:48:43 PM2/25/13
to publice...@googlegroups.com
Ooorales!! pues bueno con lo que me acaban de aportar Pablo Daniel, FidelJ tengo para analizarlo un rato, entonces voy a ver como funciona y adaptarlo de ser asi pues les comento en lo subsecuente de lo contrario estare dandoles lada... Una excelente comunidad...
 
 
Gracias...

Misael Rocha P

unread,
Feb 25, 2013, 6:08:49 PM2/25/13
to publice...@googlegroups.com
Si definiitvamente si Ricardo, lo poco que se de Visua Fox Pro me ha gustado mucho en todo su aspecto. gracias a todos por su ayuda, estoy viendo todo lo que me han hecho favor de mandar!
 
 

Misael Rocha P

unread,
Feb 25, 2013, 6:40:59 PM2/25/13
to publice...@googlegroups.com
SELECT id_pago, fechapago, abono, saldo, pagosi, pagono;
FROM dbf_pagos where cliente = tmpCobranza.cliente INTO CURSOR tmpPagos NOFILTER READWRITE
 
thisform.pageframe1.page1.grdDbf_pagos.RecordSource = "tmpPagos"
thisform.pageframe1.page1.grdDbf_pagos.Refresh()
 
WITH thisform.pageframe1.page1.grdDbf_pagos
 .ColumnCount = 6
 .AllowAutoColumnFit = 2
 .AllowHeaderSizing = .F.
 .BackColor = RGB(255,255,255)
 .DeleteMark = .F.
 .ForeColor = RGB(0,0,0)
 .FontName = "Calibri"
 .FontSize = 10
 .GridLineColor = RGB(192,192,192)
 .GridLineWidth = 1
 .GridLines = 3
 .HeaderHeight = 20
 .Height = 289
 .HighlightRow = .F.
 .Left = 597
 .Panel = 1
 .RecordMark = .F.
 .RecordSource = 'tmpPagos'
 .linkmaster = 'tmpCobranza'
 .Relationalexpr = 'Cliente'
 .RecordSourceType = 1
 .ScrollBars = 2
 .Top = 13
 .Width = 357
 .visible = .T.
 .column1.header1.caption = "No."
 .column2.header1.caption = "Fecha de Pago"
 .column3.header1.caption = "Abono"
 .column4.header1.caption = "Saldo"
    
 IF PEMSTATUS(.column5, "Text1", 5)
  .column5.removeobject("Text1")     
  .column5.addobject("chkPagosi","Checkbox")
  .column5.chkPagosi.visible=.T.
  .column5.chkPagosi.enabled=.T.
  .column5.chkPagosi.caption = ""
  .column5.chkPagosi.backstyle = 0
  .column5.chkPagosi.readonly = .F.
  .column5.chkPagosi.centered = .T.
  
  .column5.sparse = .F.
  .column5.header1.caption = "Si"
     
  IF PEMSTATUS(.column6, "Text1", 5)

   .column6.removeobject("Text1") 
   .column6.addobject("chkPagoNo","Checkbox")
   .column6.chkPagoNo.visible=.T.
   .column6.chkPagoNo.enabled=.T.
   .column6.chkPagoNo.caption = ""
   .column6.chkPagoNo.backstyle = 0
   .column6.chkPagoNo.Readonly = .F.
   .column6.chkPagoNo.centered = .T.
      
   .column6.sparse = .F.
   .column6.header1.caption = "No"
    
  
  ENDIF
 ENDIF
 
 
 FOR grdNegrit=1 TO 6
  ncol="column"+ALLTRIM(STR(grdNegrit))+"."
  .&ncol.header1.Alignment=2
 ENDFOR
 
 .Column3.InputMask = "$999,999.99"
 .Column4.InputMask = "$999,999.99" 
 .column1.Width = 24
 .column2.width = 141
 .column3.Width = 59
 .column4.Width = 69
 .column5.Width = 19
 .column6.Width = 19
 
ENDWITH
THISFORM.REFRESH
 
 
éste es el codigo que utilizo para hacer la consulta insertarla en el grid y controlar su aspecto en todo el sentido de la palabra, en modo diseño tengo los grids con el recorsource="" y su tamaño definido al mismo de ejecucion, estuve viendo y si efectivamente es lo que necesito pero como adapto en este metodo para que se le pueda dar click al checkbox y si es con ek bindevent() lo trate de hacer pero marca error que no existe la propiedad aunque si existe una igual con el nombre pero es metodo,
 

bindevent(thisform.pageframe1.page1.grdDbf_pagos.column5.chkPagoNo, "InteractiveChange",thisform, "chkPagoNo")

 

Misael Rocha P

unread,
Feb 25, 2013, 6:59:49 PM2/25/13
to publice...@googlegroups.com
Hola FidelJ
ahora que lo ejecute en mi formulario, funciona cambiando los aspectos importantees como me lo hiciste ver, y si en efecto funciona solo que el check de la columna 5 que corresponde a SI, lo muestra como textbox, y checkbox de la columna 6 si me lo muestra bien
 
 
asi es como lo pongo y al ejecutar falla en lo que te comente
 
LOCAL LoObje
nEv=AEVENTS(gaEvent,0)
IF nEv=0
  RETURN
ENDIF
LoObje=gaEvent[1]
lValor=loObje.Value
oColumn=LoObje.Parent
oGrid=loObje.Parent.Parent.Name
oControl=ocolumn.ControlSource
nos=ALINES(gaControl,oControl,1,".")
cTabla=gaControl[1]
cCampo=gaControl[2]
SELECT tmpPagos
DO case
  case Upper(cCampo)== thisform.pageframe1.page1.grdDbf_pagos.chkPagoSi
   replace thisform.pageframe1.page1.grdDbf_pagos.chkPagoNo with !lValor
  CASE uPPER(cCampo)==thisform.pageframe1.page1.grdDbf_pagos.chkPagoNo
   replace thisform.pageframe1.page1.grdDbf_pagos.chkPagoSi with !lValor
ENDCASE

WITH thisform
    .Addproperty("CampoSi","PAGOSI")
    .ADDPROPERTY("CampoNo","PAGONO")
ENDWITH
objGrid=Thisform.pageframe1.page1.grdDbf_pagos
FOR i=5 TO 6

Misael Rocha P

unread,
Feb 26, 2013, 12:51:12 AM2/26/13
to publice...@googlegroups.com
Buenas Noches a todos, reaccione algo tarde y pido disculpas por que todas las respuestas practicamente apuntaban a lo mismo, por fin he resuelto algo tan sencillo pero bueno asi pasa no? bueno eso digo yo!!.
¬¬'
-
 
 
Lo resolvi de la siguiente manera, agrege 2 metodos llamados meChkPagoSi y meChkPagoNo a cada evento respectivamente le puse su codigo
 
meChkPagoNo
 

thisform.pageframe1.page1.grdDbf_Pagos.column5.chkPagoSi = 1

thisform.pageframe1.page1.grdDbf_Pagos.column6.chkPagoSi = 0

 

meChkPagoNo

thisform.pageframe1.page1.grdDbf_Pagos.column5.chkPagoSi = 0

thisform.pageframe1.page1.grdDbf_Pagos.column6.chkPagoSi = 1

y en el metodo llenaGrdPagos

BINDEVENT(thisform.pageframe1.page1.grdDbf_pagos.column5.chkPagoSi, 'Click', thisform,"meChkPagoSi")
BINDEVENT(thisform.pageframe1.page1.grdDbf_pagos.column6.chkPagoNo, 'Click', thisform,"meChkPagoNo")

 
Hasta que porfin entendi de manera practica la funcion binevent(), ya lo habia leido no hace mucho pero no le encontré la utilidad en su momento y por ende no le preste mucha atención, ahora que se presento la situacion agradezco de verdad su atento Apoyo a todos Ustedes; Pablo Daniel, Victor Hugo, FidelJ y Ricardo Pina me abrieron los ojos. les paso todo el codigo que empleo en el metodo llenaGrdPagos por si algo en alguna oacion llegara a servir, nunca falta :D Saludos nuevamente estare dandoles lata espero no muy seguido pero es un excelente grupo sin ser barbero pero si estoy agradecido que en poco tiempo tuve respuestas!!!
 
Hasta Pronto
  .column5.addobject("chkPagoSi","Checkbox")
  .column5.chkPagosi.visible=.T.
  .column5.chkPagosi.enabled=.T.
  .column5.chkPagosi.caption = ""
  .column5.chkPagosi.backstyle = 0
  .column5.chkPagosi.readonly = .F.
  .column5.chkPagosi.centered = .T.
  
  .column5.sparse = .F.
  .column5.header1.caption = "Si" 

 ENDIF

 
     
  IF PEMSTATUS(.column6, "Text1", 5)
   .column6.removeobject("Text1") 
   .column6.addobject("chkPagoNo","Checkbox")
   .column6.chkPagoNo.visible=.T.
   .column6.chkPagoNo.enabled=.T.
   .column6.chkPagoNo.caption = ""
   .column6.chkPagoNo.backstyle = 0
   .column6.chkPagoNo.Readonly = .F.
   .column6.chkPagoNo.centered = .T.
      
   .column6.sparse = .F.
   .column6.header1.caption = "No" 
    
  ENDIF
 
 FOR grdNegrit=1 TO 6
  ncol="column"+ALLTRIM(STR(grdNegrit))+"."
  .&ncol.header1.Alignment=2
 
 ENDFOR
 
 .Column3.InputMask = "$999,999.99"
 .Column4.InputMask = "$999,999.99" 
 .column1.Width = 24
 .column2.width = 141
 .column3.Width = 59
 .column4.Width = 69
 .column5.Width = 19
 .column6.Width = 19
 
ENDWITH
 
  BINDEVENT(thisform.pageframe1.page1.grdDbf_pagos.column5.chkPagoSi, 'Click', thisform,"meChkPagoSi")
  BINDEVENT(thisform.pageframe1.page1.grdDbf_pagos.column6.chkPagoNo, 'Click', thisform,"meChkPagoNo")
 
THISFORM.REFRESH
 
aunque creo lo habia puesto arriba, bueno no creo que haya problema verdad? Saludos y gracias por todo nuevamente a todos uds.

FidelJ

unread,
Feb 26, 2013, 7:48:29 AM2/26/13
to publice...@googlegroups.com
Misael:
Veo que algunas cosas aparecen desordenadas. No sé si es por el Copy & Paste, pero por las dudas, quiero efectuar algunas aclaraciones.

* Este código iba en el INit del formulario, o en el método que 
* genera la cuadrícula de Pagos "grdDbf_pagos"
* La idea es 
* 1) saber cómo se llaman los campos de la tabla
*    que se verán afectados
* 2) Crear una secuencia de BindEvent() para las columnas afectadas
*    con un solo método delegado "SoluProb"
*
* Este segmento podría estar incluso, en el Load del formulario
WITH thisform
    .Addproperty("CampoSi","PAGOSI")
    .ADDPROPERTY("CampoNo","PAGONO")
ENDWITH

* En la creación del Control Grid, prefiero mantener los nombres de
* los objetos por Default. En este caso, los CheckBox agregados a cada columna
* se llaman siempre "Check1". Eso facilita la secuenciación de los 
* BindEvent. Si no, tienes que escribirlos a todos.
* De todos modos, lo importante es saber en qué columna se produce el
* evento Click y su ControlSource asociado.
*
* Este segmento tiene que seguir a la creación del objeto Grid.
objGrid=Thisform.pageframe1.page1.grdDbf_pagos
FOR i=5 TO 6
BINDEVENT(objGrid.Columns[i].Check1,"click",This,"SoluProb")
next



*----------------------------------------------
* Método de Usuario * "SoluProb" *
* Basado en una respuesta de Pablo Daniel Lisa
* para una consulta anterior 
*----------------------------------------------
LOCAL LoObje
nEv=AEVENTS(gaEvent,0)
IF nEv=0
  RETURN
ENDIF
LoObje=gaEvent[1]
lValor=loObje.Value
oColumn=LoObje.Parent
oGrid=loObje.Parent.Parent.Name   && Nombre de la cuadrícula (literal)
*                                 && en este caso no se utiliza
oControl=ocolumn.ControlSource
nos=ALINES(gaControl,oControl,1,".")
cTabla=gaControl[1]
cCampo=gaControl[2]

* LoObje, es una referencia al objeto que responde a BindEvent,
* determinado a través de AEVENTS()
* en este caso podría ser:
* thisform.pageframe1.page1.grdDbf_pagos.Columns[5].Check1
* o
* thisform.pageframe1.page1.grdDbf_pagos.Columns[6].Check1
* oColumn, es una referencia al objeto contenedor de lcObje
* en este caso podría ser:
* thisform.pageframe1.page1.grdDbf_pagos.Columns[5]
* o
* thisform.pageframe1.page1.grdDbf_pagos.Columns[6]
*
* oControl=oColumn.ControlSource
* es un literal = 'NombreTabla.Campo'
*
* nos=ALINES(gaControl,oControl,1,".") genera una matriz de dos elementos
* Elemento 1= Nombre de la tabla
* Elemento 2= Nombre del Campo
*
* Por Eso:
* cTabla=gaControl[1]
* Luego, puedes hacer Select (cTabla). 
* Con esto te independizas de cómo se llama la tabla
* y lo puedes aplicar a cualquier otra cuadrícula.
* cCampo=gaControl[2] 
* Nombre del campo de la tabla asociado a la columna
* afectada por el BindEvent.
*
* Lo que corresponde cambiar, es el valor en la tabla (o cursor) y que luego 
* se vean reflejados en el control grid.
*
* Este mecanismo permite que exista un solo método "cDelegate" que resuelva 
* el problema, en lugar de generar un "cDelegate" para cada columna.


<Código Puesto>
SELECT tmpPagos
DO case
 case Upper(cCampo)== thisform.pageframe1.page1.grdDbf_pagos.chkPagoSi
  replace thisform.pageframe1.page1.grdDbf_pagos.chkPagoNo with !lValor
 CASE uPPER(cCampo)==thisform.pageframe1.page1.grdDbf_pagos.chkPagoNo
  replace thisform.pageframe1.page1.grdDbf_pagos.chkPagoSi with !lValor
ENDCASE
</Código Puesto>


<Código Sugerido>
* Se propone "Upper(cCampo)", porque se definió el valor de la 
* propiedad respectiva con mayúsculas. Podría ser a la inversa.
SELECT (cTabla)
do case
case Upper(cCampo)==THISFORM.CAMPOSI
replace (Thisform.CampoNo) with !lValor
CASE uPPER(cCampo)==thisform.campoNo
replace (Thisform.CampoSi) with !lValor
endcase
* Esto resulta seguramente más rápído que citar toda la cadena de parent.
</Código Sugerido>

************************************************************************
* Sugerencias
**************
* 1) Evita, en lo posible, el uso de Thisform.REfresh.
* 2) Utiliza el objecto Columns() en lugar de macrosustitución
* 3) No necesitas quitar el objeto Text1 de la columna
* Puedes agregar el objeto que necesites y utilizar
* la propiedad CurrentControl="NuevoObjeto"
* Para el caso de agregar CheckBox, conviene definir primero
* el ControlSource de la columna. Ello porque CheckBox soporta
* valores numéricos (0,1 y 2) y lógicos. 
* Sample
lcAlias = "Nombre del Cursor"
Select (lcAlias)
nFields=Afields(gastruct)
cName=lcAlias+"."+lcNombreCampo

with thisform.Grid1
        .Columncount=nfields
.RecordSource=lcAlias
.RecordMark=.t.
.DeleteMark=.f.
for wi=1 to alen(gastruct,1)
with .Columns[wi].Header1
.Caption=Proper(gastruct[wi,1])
.Fontsize=8
endwith
do case
case gastruct[wi,2]="C"
* .Columns(wi). (lo que sea)
case gastruct[wi,2]="N"
* .Columns(wi). (lo que sea)
case gastruct[wi,2]="M"
* .Columns(wi). (lo que sea)
case gastruct[wi,2]="D"
* .Columns(wi). (lo que sea)
case gastruct[wi,2]="T"
* .Columns(wi). (lo que sea)
case gastruct[wi,2]="I"
* .Columns(wi). (lo que sea)

case gastruct[wi,2]="L"
.Columns(wi).ControlSource='&cName'
.Columns(wi).Sparse=.f.
if Vartype(.Columns(wi).Check1)#"O"
.Columns(wi).AddObject("Check1",'CheckBox')
endif
.Columns(wi).CurrentControl="Check1"
.Columns(wi).Check1.Caption=""
.Columns(wi).Check1.Visible=.t.
* etc
endcase
next
endwith



Saludos.
Fidel.


El lunes, 25 de febrero de 2013 17:39:48 UTC-3, Misael Rocha P escribió:

Misael Rocha P

unread,
Feb 26, 2013, 12:14:04 PM2/26/13
to publice...@googlegroups.com
Hola Fidel, Buenos Dias;
 
Ok entiendo!!, claro que pondre todo a la practica y aunque ya habia finalizado y que ahora mismo quite la marca te comento que lo voy a hacer de esta manera aparte te quiero preguntar sobre lo que me dices
 
no hace mucho una persona me hizo la misma observacion sobre el thisform.refresh pero sinceramente no lo entiendo, que tanto conflicto puede haber o el por que, bueno al menos creo que lo uso lo necesario pero si me brinca ahora mismo y tambien me gustaria entender que es la macrosustitucion la palabra en si suena interesante pero a la practica no lo entiendo y tienes razon no es necesario quitar el objeto textbox del grid solo que me deje llevar jejeje, viendolo bien no hay por que quitarlo!!
 
Saludos y Gracias:)

FidelJ

unread,
Feb 26, 2013, 6:20:31 PM2/26/13
to publice...@googlegroups.com
 1) Referenciar al objeto en lugar de Macrosustitución
 
FOR grdNegrit=1 TO 6
 ncol="column"+ALLTRIM(STR(grdNegrit))+"."
 
.&ncol.header1.Alignment=2 &&macrosustitución
 ENDFOR

En lugar de eso,es mejor;
For i=1 to Thisform.pageframe1.page1.grdDbf_pagos
       .Columns[i].header1.Alignment=2  && referencia directa al objeto.
next


En algunos casos la macrosustitución es irremplazable. Cuando un comando se ejecuta con referencia directa (no literal), puede que no haya otra solución. Algunos admiten expresión de nombre.
por ejemplo
lcTabla="c:\miruta\MiTabla"
USE (lcTabla) IN 0 SHARED      (expresión de nombre)  Preferida
USE &lcTabla IN 0 SHARED      (macrosustitución)       Esto es más lento, aunque funciona.

CD C:\MIRUTA\DATOS     MKDIR C:\MIRUTA\DATOS
DIRECTORY(cDirectoryName [, nFlags]) && cDirectoryName es un literal
? Directory("c:\MiRuta\Datos")

lcRoot="C:\MIRUTA\DATOS"
if !Directory(lcRoot)
      MKDIR &LcRoot  && macrosustitución
ENDIF
CD &lcRoot   && macrosustitución

Otro caso:
Escribes una fórmula:
miFormula=" h + b * x "
Luego:
h=20
b=5
x=12
nREsulta=&miFormula       && macrosustitución (reemplazable por Evaluate() )
ó
nResulta=Evaluate(miFormula)   && recomendado.

Otro caso:
lValue= .T. | .F.
lcInforma=iif(lValue,"Ha realizado un cambio","Se fue sin saludar")
Messagebox("Informa que &lcInforma y Chau!")   && ó Messagebox("Informa que "+lcInforma+" y Chau!")



Thisform.Refresh.
No es que "Prohibido usar Thisform.Refresh". En la mayoría de los casos no produce gran cosa, en otros puede dar un dolor de cabeza. En algunos casos resultará necesario. En formularios muy complejos con objetos dentro de contenedores y pageframe, Thisform.Refresh será un tanto remolón.

Si generas un control Grid y estás asignando .Columns[i].ControlSource='cursor.campo', el Refresh subsiguiente no es necesario. 
Si en el INIT de un formulario, escribes
with thisform
      .Text1.ControlSource='Thisform.Prop1'
      .TExt2.ControlSource='Thisform.Prop2'
endwith
Thisform.refresh && no es necesario.

Si en un método ó control hacemos
Thisform.Prop1="Valiente"
Thisform,Text1.Refresh && actualiza el valor del control Text1

En cambio, si en un cursor asociado a un control grid haces cambios desde un cuadro del formulario ó desde otro formulario, será necesario Thisform.Grid1.Refresh (tampoco Thisform.Refresh)  cuando agregas un registro. Si modificas un registro existente, en general no será necesario el Refresh.
Si tienes un conjunto de controles TextBox ó EditBox y los trabajas a todos como Value (sin asignar ningún ControlSource), el Refresh para esos controles no hará nada visible. Y si en algún lugar del formulario escribes thisform.Text1.Value="Mi programa", el cambio se refleja de inmediato.

En general, prefiero crear un método donde indico qué objetos se actualizan con .Refresh
Para juntar con macrosustitución, podemos escribir, por ejemplo:
* Método "MiRefresh"
lcListaRefresh="Text1,text2,Text5,Spinner1,Grid1,Edit2"
nRef=Alines(gaRef,lcListaRefresh,1,",")
with thisform
for i=1 to alen(garef)
      lcObjeto=garef[i]
      .&lcObjeto..Refresh
next
ENDWITH

Saludos.

Misael Rocha P

unread,
Feb 26, 2013, 7:34:53 PM2/26/13
to publice...@googlegroups.com
Hola, Fidel Gracias por la informacion, mas claro no me pudo quedar muy extensa y entendible, ahora veo de verdad!!!
Muchas Gracias por tu tiempo lo aprecio. en lo subsecuente voy a saber como usar el Refresh y la macrosustitucion.
 
Saludos y hasta pronto.
Reply all
Reply to author
Forward
0 new messages