FoxPro/Visual FoxPro - Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

 
Vista:
sin imagen de perfil
Val: 313
Bronce
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Jose Francisco (166 intervenciones) el 12/12/2018 03:42:03
Hola estimados tengo un grid que al elegir el articulo de otro grid , me graba los replace pero NO graba la ganancia (gan) en la última vez que elijo el artículo de la lista .
La ganancia la busca primero en otra tabla.-

adjunto código en beforrerowcolchangue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
wdesc=art1rec.desc
wunid=art1rec.unid
wprec_u=art1rec.prec_u
wprec_u=art1rec.prec_u
wpdesc=art1rec.pdesc
wimporte=art1rec.importe
wimporte=(wprec_u*wunid)
wpdesc=(wimporte*wdesc)/100
wimporte=wimporte-wpdesc
 
replace importe WITH wimporte  (aqui siempre graba el importe todas las veces)
 
IF art1rec.unid=0 OR art1rec.unid>0
 
SELECT 2
**23/11/2018
wart=art1rec.articulo
wunid=art1rec.unid
wgan=art1rec.gan
 
SELECT 4
SEEK CODART
 
wart=xartm.codart
IF wart=xartm.codart
wgan=((xartm.ganancia)*wunid)
 
replace art1rec.gan WITH wgan
*****
en la ultima vuelta NO graba la gan.......
sólo Graba la gan en la última vuelta de elegir el artículo  si hago un click en importe de la fila del grid
 
*****
thisform.txtganancia.Value=wgan
 
ENDIF
ENDIF

Aguardo respuesta
Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Mauricio (45 intervenciones) el 12/12/2018 13:21:28
Revisa el SEEK donde actualizas ganancia, posiblemente no lo encuentra y por eso no lo actualiza
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 313
Bronce
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Jose Francisco (166 intervenciones) el 13/12/2018 04:31:56
El seek encuentra bien la ganancia ya que cada vez que elijo un articulo trae la ganancia al campo del formulario : thisform.txtganancia.Value con el siguiente código, thisform.txtganancia.Value=wgan..

El último aerticulo que elijo también trae bien la ganancia pero no la graba en la tabla.-
Ahora , si hago un click en importe , si graba bien el replace.-
No puedo programar aguna rutina para que llegue a hacer ese click por programación en la última fila del grid campo importe?
(Probé con thisform.grid1.column6.header1.Click luego del replace pero no funciona).-
Aguardo respuesta
Gracias.-
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.011
Oro
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Fidel José (657 intervenciones) el 13/12/2018 20:32:06
Lo primero que haría es mudar ese código al evento AfterRowColChange del Grid.
Lo segundo es refactorizar
1) Estos SELECT 1, SELECT 4, SELECT 150 son antiguos (FoxBase). Reemplaza el número de área por el Alias de la tabla y tus programas gananrán en claridad.

1.1 Apertura de una tabla
lcTabla = "clientes"
lcPath = "\\Servidor\Recurso\Carpeta_Compartida"

USE (ADDBS(m.lcPath)+m.lcTabla IN 0 SHARED && en este caso el Alias = Nombre
SELECT Clientes

Alternativa:
USE (ADDBS(m.lcPath)+m.lcTabla IN 0 SHARED AGAIN ALIAS MisClientes
SELECT MisClientes

La tabla se abrirá en la menor area de trabajo desocupada. Pero ya te despreocupas del área de trabajo.

2) Si usas el comando SEEK siempre debes utilizar la comprobación IF FOUND() [ o IF !EOF() ]. De otra forma tendrás sorpresas.
En lugar del comando SEEK (anticuado), debes utilizar una de las siguientes funciones:
SEEK( eExpresion_buscada, lcAlias_Tabla , lcEtiqueta_Indice)
ó
INDEXSEEK(eExpresion_Buscada, .t. ,lcAlias_Tabla,lcEtiqueta_Indice)
Yo prefiero esta última porque no mueve el puntero de registro si no encuentra el valor buscado.
Ambas funciones devuelven Verdadero o Falso, por lo que no hay nada que testear luego
Ambas funciones tienen la ventaja de que no necesitás seleccionar el área de trabajo para ejecutar la búsqueda.
Seek() es más rápida cuando la búsqueda fracasa que INDEXSEEK(), porque no pierde tiempo en reposicionar el puntero de registro.

IF INDEXSEEK(Codart,.T., lcAlias, lcEtiqueta)

ENDIF

3) La nomenclatura de las variables no te ayuda. Usa la convención de prefijo de dos letras:
Primera letra: L=Local, G= Public, P=private
Segunda Letra: Tipo de dato.
Ejemplo
LOCAL lcDescribe, lnValor, ldFecha

4) El paso de valor de un campo a Variable y de Variable a valor de campo de otra tabla o cursor se puede evitar las más de las veces, pasando la referencia:

SELECT TABLA_A
Replace Campo1 WITH Tabla_B.Campox

4.1) Si el nombre de la tabla está contenido en una variable:
lcCursor = SYS(2015)
SELECT * FROM TABLA_B WHERE CODART="ZZZ" INTO CURSOR (lcCursor)
SELECT TABLA_A
REPLACE CAMPO1 WITH EVALUATE(m.lcCursor+".Campox")

Si el nombre del campo también es variable
lcField = "Nombre"
SELECT TABLA_A
REPLACE CAMPO1 WITH EVALUATE(m.lcCursor+"."+m.lcField)

Te recomiendo este excelente artículo de Fernando D. Bozzo
https://fdbozzo.blogspot.com/2014/09/vfp-guia-de-buenas-practicas-de.html
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 313
Bronce
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Jose Francisco (166 intervenciones) el 13/12/2018 21:32:36
Hola Fidel Jose, ante todo gracias por tu respuesta y tanto conocimiento brindado,,,,cambié el código de lugar pero es peor, no graba en ningún replace la ganancia, te paso el código con algunos cambios según me indicaste.
Los select los tengo definidos en el init del formulario principal y los llamo con selec 2 , select 4 , ahora los llamé según vuestra indicación
pero continúo con el mismo problema :
EN LA ÚLTIMA ELECCIIÓN DEL ARTÍCULO NO HACE EL REPLACE DE LA GANANCIA EN LA TABLA art1rec.-
AHORA, SI HAGO UN CLICK EN EL IMPORTE SI LO HACE.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
wdesc=art1rec.desc
wunid=art1rec.unid
wprec_u=art1rec.prec_u
wprec_u=art1rec.prec_u
wpdesc=art1rec.pdesc
wimporte=art1rec.importe
wimporte=(wprec_u*wunid)
wpdesc=(wimporte*wdesc)/100
wimporte=wimporte-wpdesc
 
replace importe WITH wimporte
 
**aqui no va porque repite cuando levanto la lista
*SUM ALL art1rec.gan TO wgan
*thisform.txtganancia.Value=wgan
 
 
IF art1rec.unid=0 OR art1rec.unid>0
 
*select 2
SELECT art1rec
 
wart=art1rec.articulo
wunid=art1rec.unid
wgan=art1rec.gan
 
*SELECT 4
SELECT xartm
SEEK CODART
IF FOUND()
wart=xartm.codart
IF wart=xartm.codart
wgan=((xartm.ganancia)*wunid)
 
thisform.txtganancia.Value=wgan
 
*SELECT 2
SELECT art1rec
replace art1rec.gan WITH wgan
 
ENDIF
ENDIF
ENDIF

COMO PUEDO AGREGAR UN CLICK AUTOMÁTICAMENTE EN IMPORTE DEL GRID PARA QUE ME HAGA EL CÁLCULO EN LA ÚLTIMA VUELTA O ELECCIÓN DEL ARTÍCULO?
Aguardo alguna otra respuesta o sugerencia.-
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.011
Oro
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Fidel José (657 intervenciones) el 14/12/2018 23:50:12
1) tu código con algunas observaciones (menores por cierto)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
wdesc=art1rec.desc
wunid=art1rec.unid
wprec_u=art1rec.prec_u
wprec_u=art1rec.prec_u
wpdesc=art1rec.pdesc
 
***  Cuál debe ser el valor de wImporte? ***
wimporte=art1rec.importe
wimporte=(wprec_u*wunid)
******************************************
 
wpdesc=(wimporte*wdesc)/100
wimporte=wimporte-wpdesc
 
*** En que tabla o cursor se reemplaza esto? ***
replace importe WITH wimporte
 
*aqui no va porque repite cuando levanto la lista
*SUM ALL art1rec.gan TO wgan
*thisform.txtganancia.Value=wgan
 
 
IF art1rec.unid=0 OR art1rec.unid>0
	SELECT art1rec
	wart=art1rec.articulo
	wunid=art1rec.unid
	wgan=art1rec.gan
 
	SELECT xartm
 
	SEEK CODART
 
	IF FOUND()
 
		wart=xartm.codart
 
		IF wart=xartm.codart
 
			wgan= xartm.ganancia * wunid
			thisform.txtganancia.Value=wgan
 
			SELECT art1rec
			replace art1rec.gan WITH wgan
		ENDIF
 
	ENDIF
 
ENDIF

2) Ahora que se entiende un poco, cuál es la razón por la cual este código estaría en un evento como AfterRowColChange o BeforeRowColChange? Esos eventos se disparan permanentemente y lo que se programa ahí es qué sucede cuándo el usuario mueve el puntero de registro con el mouse o con las Arrow Key.
Para poder responder a esa pregunta, hay que hacerse otras preguntas (por lo menos, en mi caso porque no sé que intentas hacer).
a) Qué es lo que necesitas hacer?
b) Desde dónde se lanza el proceso?
c) Ingresas valores directamente en el Control Grid o tienes un formulario de ingreso?

Me anticipo con algo: si introduces valores directamente en el grid, la programación de los eventos debería estar en cada objeto Current Control contenido en los objetos Column del grid.
Sin embargo, es absolutamente no recomendable programar sobre los objetos Text1, Check1, etc que puedan ser current Control de las columnas. Ello porque, en tiempo de ejecución, cualquier cambio puede hacerte desaparecer toda la programación de esos objetos.
Si estás trabajando con VFP9, tienes dos recursos a los que deberías apelar:
1) Crear objetos de clase (textbox, checkbox, combobox, etc) e incorporarlos al control Grid mediante programación
2) Utilizar BindEvent con el código delegado en métodos del formulario.
Si no tienes buen dominio de las clases, lo más conveniente es apelar a BindEvent()
Pero mejor comenta un poco tu idea, para no aumentar la confusión
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 313
Bronce
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Jose Francisco (166 intervenciones) el 15/12/2018 01:12:21
Hola Fidel José, tenés razón, disculpá pero faltó explicarte el proceso, en éste interín lo solucioné con lo siguiente:

Hice un do while para que recorra el arhivo y cuando modifico hace un recálculo.-(me sirve para todo)
En realidad ya lo tenía para el primer uso de ese formulario (luego agregue cálculo de ganancia)
(en el sum all más abajo me guarda luego que se recalcula el importe)
EN EL BOTÓN GRABAR DEL FORMULARIO PRINCIPAL RECIBOS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
SELECT arti1rec
GO top
DO WHILE NOT EOF()
SELECT xrec
*(es la tabla del formulario principal recibos)
SET FILTER TO nrocomb == ThisForm.txtnrocomb.Value IN "art1rec"
*aqui combino el el grid1 (tabla art1rec) con la tabla xrec del formulario principal ,
IF nrocomb=thisform.txtnrocomb.value
 
***ATENCIÓN NO ESCRIBIR CON EL ALIAS PORQUE NO GRABA
SELECT art1rec
 
warticulo=art1rec.articulo
wdesc=art1rec.desc
wunid=art1rec.unid
wprec_u=art1rec.prec_u
wprec_u=art1rec.prec_u
wpdesc=art1rec.pdesc
wimporte=art1rec.importe
wimporte=(wprec_u*wunid)
wpdesc=(wimporte*wdesc)/100
wimporte=wimporte-wpdesc
 
replace articulo WITH warticulo
replace unid WITH wunid
replace prec_u WITH wprec_u
replace desc WITH wdesc
replace pdesc WITH wpdesc
replace importe WITH wimporte
 
****en la tabla art1rec
 
ENDIF
SKIP
LOOP
EXIT
ENDDO
 
thisform.txtganancia.Value=0
 
WAIT WINDOW "Calculando Ganancia..." TIMEOUT .8
 
SUM ALL art1rec.gan TO wgan FOR art1rec.nrocomb=thisform.txtnrocomb.value
thisform.txtganancia.Value=wgan

*debe haber una mejor forma pero ésta me sirvió.-
Cualquier siugerencia se acepta

Saludos y muchas gracias!
***************************************************************************
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 313
Bronce
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Jose Francisco (166 intervenciones) el 15/12/2018 01:28:41
Te califiqué positivo por aquí.-
Muchas gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 1.011
Oro
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Fidel José (657 intervenciones) el 15/12/2018 12:47:14
Hola José Francisco
Te hago algunas observaciones

0) No hagas CrossPost. Fijate que aprovechaste otro hilo con otra consulta para meter la misma consulta que ya habías iniciado por este hilo. Entonces hay que andar revisando todo para saber qué avance tiene el tema.

1) Uso del comando REPLACE
En lugar de una sucesión de comandos replace
1
2
3
4
5
6
replace articulo WITH warticulo
replace unid WITH wunid
replace prec_u WITH wprec_u
replace desc WITH wdesc
replace pdesc WITH wpdesc
replace importe WITH wimporte
conviene utilizar este tipo de sintaxis
1
2
3
4
5
6
7
REPLACE articulo WITH warticulo,;
	unid WITH wUnid,;
	prec_u WITH wprec_u,;
	desc WITH wdesc,;
	pdesc WITH wpdesc,;
	importe WITH wImporte
FLUSH
Pensá que cada comando REPLACE necesita verificar el estado de bloqueo del registro por lo cual resulta mucho más lento que colocar un solo REPLACE con las instrucciones necesarias.

2) Uso del bucle DO WHILE
Expones una sucesión de comandos un tanto extraña:
DO WHILE !EOF()
SELECT xrec && no se ve el motivo de este select. Tal vez falte una parte del código
SET FILTER TO nrocomb == ThisForm.txtnrocomb.Value IN "art1rec" && dentro del bucle?
* otros comandos
SKIP && mueve el puntero al siguiente registro disponible
LOOP && envia el control al inicio del bucle (para qué?)
EXIT && sale del bucle (cosa que no va a ocurrir aquí porque lo impide el LOOP anterior
ENDDO && cierre del bucle (Ok)

2.1. SET FILTER. En general el uso de SET FILTER debe evitarse, salvo para cursores o tablas locales (no compartidas) y cuando no se pueda encontrar algo mejor. De todos modos, aqui caben dos observaciones:
2.1.1) Podría ser SET FILTER TO nrocomb == ThisForm.txtnrocomb.Value IN art1rec && sin las comillas
2.1.2) El comando no debería estar dentro del bucle porque para el bucle TxtNroComb.Value es una constante, por lo que lo único que logra es que el proceso sea más lento y la lectura del código más confusa.
2.1.3) IF nrocomb=thisform.txtnrocomb.value. Como viene el código, el campo nroComb parece referirse a la tabla XREC. Como del código expuesto no se desprende que XREC tenga movimiento de puntero alguno dentro del bucle, el comando es ocioso, o debería estar fuera del bucle.

2.2. LOOP es un comando que se utiliza cuando se quiere evitar que el programa continúe ejecutando las líneas siguientes. Pero siempre debe responder a una condición (IF ocurreTalCosa THEN LOOP ENDIF) y no como un código que se ejecuta incondicionalmente, porque eso hará que el código siguiente no se ejecute, con el riesgo de crear un bucle infinto.

2.3. EXIT es un comando que se utiliza cuando, debido a cierta ocurrencia, se necesita abandonar el bucle. Al igual que LOOP, siempre debe responder a una condición (IF / ENDIF)

2.4. Miro este código y no estoy convencido de tenga que ser así:
SELECT art1rec
warticulo=art1rec.articulo
wdesc=art1rec.desc
wunid=art1rec.unid
wprec_u=art1rec.prec_u
wprec_u=art1rec.prec_u
wpdesc=art1rec.pdesc
wimporte=art1rec.importe
wimporte=(wprec_u*wunid)
wpdesc=(wimporte*wdesc)/100
wimporte=wimporte-wpdesc

replace articulo WITH warticulo && sería lo mismo que poner REPLACE articulo WITH articulo && ??
replace unid WITH wunid && sería lo mismo que poner REPLACE unid WITH unid
replace prec_u WITH wprec_u
replace desc WITH wdesc
replace pdesc WITH wpdesc
replace importe WITH wimporte
O sea, si los REPLACE deben ocurrir en la tabla art1rec, deberías ahorrarte todas esas variables y trabajar con los campos de la tabla. Y no habiendo ninguna novedad (al menos visible) no vale la pena reemplazar el valor de un campo con el valor del mismo campo en la misma tabla o cursor.
Y si los REPLACE deberían ocurrir en otra tabla o cursor, pues aquí falta el SELECT OtraTabla.

Por otra parte, no se comprende (mirando el código) que papel juega el campo nrocomb en art1rec. Esto debería ser más explícito. Supongo que ese campo está en la tabla art1rec porque se deduce de SET FILTER.

3) Siempre que resulte posible, debe utilizarse el bucle SCAN / ENDSCAN en lugar de DO WHILE / ENDDO

Da la impresión de que todo ese código podría reemplazarse por este otro
1
2
3
4
5
6
7
8
LOCAL lnDescuento,lnImporte
SELECT art1rec
SCAN FOR nroComb = thisform.txtNroComb.Value
	lnDescuento = ROUND(prec_u * Unid * Desc/100,2)
	lnImporte = ROUND(prec_u * Unid,2) - m.lnDescuento
	REPLACE pdesc WITH m.lnDescuento,;
		importe WITH m.lnImporte
ENDSCAN
En esto falta la parte que determina la ganancia, porque tiras un SUM ALL sobre un campo que no se ve cómo se rellena.
En cuanto al código anterior sobre la determinación de la ganancia, no sé cuál es tu idea, o sea, qué necesitas informar en ese punto. Hablar de "ganancia" en esta etapa es algo estrepitoso, salvo que trabajes con tasa predeterminada de gastos o costo estándar, en cuyo caso podrá tener un valor estadístico más o menos confiable. Lo que se puede determinar es la contribución o margen bruto, siempre que tengas el dato del costo del producto, para lo cual también tendrías que definir un método de inventario (FIFO, LIFO, etc) y un "Kardex" que te permita saber cuáles son los vendidos y su costo de adquisición. De lo contrario, tendrás que resignarte a trabajar "a lo bruto", tal como se acostumbra en Argentina, donde siempre se toma el último valor de costo conocido.
De todos modos, lo que no me parece (según la rutina anterior) es que pueda ser un monto fijo, porque eso excluiría el descuento. O sea, el margen bruto debería determinarse sobre Precio Neto - Costo Neto.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 313
Bronce
Ha mantenido su posición en FoxPro/Visual FoxPro (en relación al último mes)
Gráfica de FoxPro/Visual FoxPro

Grid no graba la última vuelta en un campo luego de elegir el artículo de otro grid.

Publicado por Jose Francisco (166 intervenciones) el 16/12/2018 01:06:22
Hola Fidel Jose, están buenas tus observaciones, muy buena didáctica.
Tema ganancia la toma de la tabla artÍculos maestro (del formulario maestro de artículos) , donde se carga el articulo y la ganancia por cada uno.-
Luego ese dato de la ganancia lo tomo con el seek en ésta parte.-
Con el sum all sumo las correspondientes a ese registro de la tabla recibo.-
Si sabia lo del set filter , pero utilizo tablas locales.-
Tema Scan / End Scan ya lo he utilizado en otras rutinas (está muy bueno).-

Iré corrigiendo sobre las marcha.-
Muchas Gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar