INSERT INTO usando propiedades de formulario

532 views
Skip to first unread message

Carton Jeston (9.0.0.7423)

unread,
May 15, 2015, 1:44:49 AM5/15/15
to publice...@googlegroups.com
Por culpa de Antonio Meza y de toda la legion de programadores adoradores de las buenas costumbres de programacion, estoy rediseñando mi aplicacion e intentando seguir todas las recomendaciones. :-)

El caso es que quiero sustituir append blank+replace del todo por insert into, que ya lo hacia en determinadas situaciones. El problema esta cuando quieres añadir el contenido de propiedades de formulario, por ejemplo:

thisform.tabla contiene CLIENTES
thisform.indice contiene CODIGO


Si lo escribes directo sin propiedades funciona sin problemas:

INSERT INTO CLIENTES (CODIGO) VALUES (CODIGO+1)

Si pones las propiedades te dara error:

INSERT INTO thisform.TABLA (thisform.INDICE) VALUES (thisform.INDICE+1)

Se puede evitar error en el thisform.TABLA si lo pones entre parentesis pero falla lo demas:

INSERT INTO (thisform.TABLA) (thisform.INDICE) VALUES (thisform.INDICE+1)

Las dos soluciones que he encontrado hasta ahora, a la espera de que alguien me enseñe otra mas sencilla o elegante:

Usar un parentesis para la propiedad tabla una variable para la propiedad indice

x=thisform.indice
INSERT INTO
(thisform.table) (&x) VALUES (&x+1)

Usar el metodo para construir sentencias sql:

x=""
TEXT TO x NOSHOW TEXTMERGE PRETEXT
8
INSERT INTO
<<thisform.tabla>> (<<thisform.indice>>) VALUES (<<thisform.indice>>+1)
ENDTEXT
&x

Tal vez haciendo una funcion personalizada o algo similar seria una tercera opcion, pero casi prefiero escuchar otras opciones.


Qsoft

unread,
May 15, 2015, 2:30:32 AM5/15/15
to publice...@googlegroups.com
x=""
TEXT TO x NOSHOW TEXTMERGE PRETEXT
8
INSERT INTO
<<thisform.tabla>> (<<thisform.indice>>) VALUES (<<thisform.indice>>+1)
ENDTEXT
&x

y asi?:

TEXT TO x NOSHOW TEXTMERGE PRETEXT 8
INSERT INTO
<<thisform.tabla>> (<<thisform.indice>>) VALUES (<<thisform.indice + 1>>)
ENDTEXT

EXECSCRIPT(x)

omitto la inizializacion de la variable porque lo hace ya el TEXT ENDTEXT. Solo si usas la opcion ADDITIVE(generalmente si esta dentro de un bucle)  la coloco para estar seguro che inicia vacia,



Enrique Vasquez B.

Carlos Miguel FARIAS

unread,
May 15, 2015, 7:45:54 AM5/15/15
to Grupo Fox
Hay muchas soluciones.
Podes pasar las variables del formulario a variables locales, o a un arreglo.

Indice = Thisform.Indice
INSERT INTO (thisform.TABLA) (INDICE) VALUES (INDICE+1)

Insert admite pasarle datos desde arreglos u objetos

Probaste de poner parentesis alrededor de las variables dentro del insert?
INSERT INTO (thisform.TABLA);
  ((thisform.INDICE)) VALUES ((thisform.INDICE)+1)

Saludos: Miguel, La Pampa (RA)

Carton Jeston (9.0.0.7423)

unread,
May 15, 2015, 1:26:51 PM5/15/15
to publice...@googlegroups.com, carlosmig...@gmail.com
Quiquev:

Lo de definir la X fue por clarificar un poco el ejemplo y donde iba cada cosa. Lo mas optimizado es justo como tu dices y el ADDITIVE lo uso posteriormente para añadir en consultas sql "where" u otros parametros a la consulta. En el momento que no pongas ADDITIVE X se reinicia.

A veces he usado el exescript para ejecutar varias lineas de codigo desde un archivo prg o memo, para estos casos uso &. Esto me hace pensar que pueda tener otras ventajas o ser mas compatible con el compilador VFP C++,que se que hay limitaciones con la forma de trabajar con macros. Tengo que investigarlo en este sentido para no llevarme sorpresas a la hora de la compilacion final pero ¿que ventajas le ves tu ademas de las mencionadas?

Miguel:

Si se escribe asi dice que la variable indice no se encuentra:
 
Indice = Thisform.Indice
INSERT INTO (thisform.TABLA) (INDICE) VALUES (INDICE+1)
 
Y de esta manera, error de sintaxis:

INSERT INTO (thisform.TABLA);
  ((thisform.INDICE)) VALUES ((thisform.INDICE)+1)

Hay que tener en cuenta que en thisform.indice se guarda el nombre del campo que uso de indice en una tabla, en este caso CODIGO podria ser el campo indice de un codigo de articulo, cliente, etc.
 
A todos:

Personalmente a pesar de ser mas aparatosa, la sentencia text to evita tener que crear variables temporales y se ve el codigo mas claro aunque sea mas compleja la sentencia.

Pero como ya sabeis, en fox hay muchas formas de hacer lo mismo, y muchas veces segun el caso es mejor una u otra, aunque yo quiero unificar una sola o ver la mas practica.

Gracias a los dos... pero dejare la cuestion en el aire a ver que usa cada uno... :-)

Antonio Meza

unread,
May 15, 2015, 2:20:14 PM5/15/15
to publice...@googlegroups.com, carton...@gmail.com
Como decía el Chavo del Ocho "todo yo todo yo" jajaja

Las buenas practicas han sido fomentadas por el maestro Fernando con sus diversos artículos, así que el es el culpable directo y en mi caso las eh seguido y recomendado así que soy culpable indirecto jajaj

Lo mejor de todo es que estas siendo visionario y tomando el camino adecuado, que pareciera ser mas difícil cuando en realidad es mas fácil.

En mi caso sigo usando Append Blank, replace y Insert Into, para el manejo de los cursores internos de VFP, no recuerdo haber sugerido usar solo Insert Into, donde lo viste? y que mejora hay?

saludos
Antonio Meza

Fernando D. Bozzo

unread,
May 15, 2015, 2:51:39 PM5/15/15
to publice...@googlegroups.com, carton...@gmail.com
Hola Carton,

Aquí uno de los culpables :)

Hay varias soluciones, como ya habrás visto, te dejo otra más usando un objeto registro:

oReg = createobject( "empty" )
addproperty( oReg, "nombre-campo-1", valor1 )
addproperty( oReg, "nombre-campo-2", valor2 )

INSERT INTO (tuTabla) FROM NAME oReg


Saludos :)

Víctor Hugo Espínola Domínguez

unread,
May 15, 2015, 5:42:28 PM5/15/15
to publice...@googlegroups.com
Hola Carton

>x=""
>TEXT TO x NOSHOW TEXTMERGE PRETEXT 8
>INSERT INTO <<thisform.tabla>> (<<thisform.indice>>) VALUES (<<thisform.indice>>+1)
>ENDTEXT
>&
x

Local lcInsert
TEXT TO
lcInsert NOSHOW TEXTMERGE PRETEXT 15

    INSERT INTO <<thisform.tabla>>
        (<<thisform.indice>>)
        VALUES (<<Evaluate(thisform.indice) + 1>>)
ENDTEXT
Execscript(m.lcInsert)

Para mi gusto esta es la forma más elegante y legible.

>
estoy rediseñando mi aplicacion e intentando seguir todas las recomendaciones. :-)

Ya que tomaste la decisión de cambiar tu estilo, entonces es un buen momento para hacerlo como corresponde, deberías separar el código en capas, como mínimo dos y mejor aún tres.

1) Interface de usuario (UI): Las instrucciones de manejo de datos, INSERT, UPDATE, DELETE, REPLACE, etc... deben aplicarse exclusivamente a cursores o tablas temporale de uso necesario para la UI.
Los datos que deben ser traidos/llevado desde/hacia las tablas del servidor se deben "pedir/enviar" a la capa de Reglas de negocio.

2) Reglas de negocio: Actúa de intermediario entre la UI y la capa de datos y se encarga de las validaciones de los datos. Uno de los aspectos a ser tenido en cuenta es la estructura de datos a utilizar para la comunicación entre las capas.
3) Capa de datos: Como su nombre lo indica se encarga del envío y recepción de los datos.

Deberías leer este artículo: http://fdbozzo.blogspot.com/2014/10/vfp-la-interfaz-las-reglas-de-negocio-y.html

Si te interesa el tema podemos seguir ampliando el hilo o abrir uno nuevo.

Saludos,
Víctor.
Lambaré - Paraguay.

Carton Jeston (9.0.0.7423)

unread,
May 24, 2015, 6:51:31 AM5/24/15
to publice...@googlegroups.com, vich...@gmail.com
Bueno amigos, he estado muy ocupado y no he tenido tiempo de contestar, al poner en practica algunas de vuestras recomendaciones. A cada pregunta que hago se me abren varias ramificaciones a seguir :-)

Antonio:

Como decía el Chavo del Ocho "todo yo todo yo" jajaja
En mi caso sigo usando Append Blank, replace y Insert Into, para el manejo de los cursores internos de VFP, no recuerdo haber sugerido usar solo Insert Into, donde lo viste? y que mejora hay?

Quizas seas el cabeza de turco, ya que eres el culpable de plantearme dejar los dbf e iniciar el gran cambio jajaja

Creo que el tema era prohibir el uso de appendblank+replace, especialmente en bases de datos y en un futuro usar comandos mas estandar para migrar a otros lenguajes. Como tu dices, con cursores no deberia haber problema, otra cosa son los cambios directos a la base de datos. Teniendo en cuenta que el acceso futuro sera con foxydb, es bueno saberlo :-)

Fernando:

Hay varias soluciones, como ya habrás visto, te dejo otra más usando un objeto registro:

Esta solucion no esta nada mal, aunque creo que encaja como un guante en otra rutina que tengo que hacer. Eres el rey de los objetos :-)

Victor:
VALUES (<<Evaluate(thisform.indice) + 1>>)
https://mail.google.com/mail/u/0/?tab=wm#drafts/14d561a96e02666b
Ya que tomaste la decisión de cambiar tu estilo, entonces es un buen momento para hacerlo como corresponde, deberías separar el código en capas, como mínimo dos y mejor aún tres. Si te interesa el tema podemos seguir ampliando el hilo o abrir uno nuevo.
 
He estado investigando sobre el compilador VFP C++ y la macrosustitucion, en algunos casos presentaria incompatibilidad, asi que el uso de evaluate() y execscript() no solo es recomendable sino necesario y de paso me va a ahorrar revisar mi aplicacion en el futuro arreglando este problema :-)

El enlace a google no logro leerlo.

Conozco el documento de Fernando, hay algunas partes como las validaciones que llegue a esa misma conclusion, pero quiero avanzar mas en este sentido y ver todas las posibilidades que ofrece. Cualquier ampliacion de este tema u otro hilo con mas informacion es bienvenido.

Creo que voy a abrir otro hilo porque este ha alcanzado su objetivo :-)
un saludo

Víctor Hugo Espínola Domínguez

unread,
May 24, 2015, 12:07:52 PM5/24/15
to publice...@googlegroups.com
Víctor.
Lambaré - Paraguay.

integral

unread,
May 24, 2015, 2:39:46 PM5/24/15
to publice...@googlegroups.com, carton...@gmail.com

Estimado Amigo CARTON :

No hechemos la culpa a los demás de algunas errores que podamos generar al implementar tal o cual rutina...

Creo que este foro sin lugar a equivocarme existen colaboradores que tienen una mayor experiencia y por ende conocen todas las variantes que se pueden codificar...

El tema esta en saber implementar o adaptar los códigos de los ejemplos mostrados...

Los códigos mostrados de los maestros conocedores de VFP Fernando y Victor Hugo me parecen una solución actual y moderna a tu problema.

atte., 

INTEGRAL  


El viernes, 15 de mayo de 2015, 7:44:49 (UTC+2), Carton Jeston (9.0.0.7423) escribió:

Fernando D. Bozzo

unread,
May 24, 2015, 3:06:22 PM5/24/15
to publice...@googlegroups.com
Gabriel, no está echando culpas en serio. Si lo lees bien es como decir que "ustedes tienen la culpa de que ahora me gustan los helados".



integral

unread,
May 24, 2015, 10:53:49 PM5/24/15
to publice...@googlegroups.com, carton...@gmail.com

No para nada  era una forma de decir lo que mencionaba el colega...

atte.,

INTEGRAL

El viernes, 15 de mayo de 2015, 7:44:49 (UTC+2), Carton Jeston (9.0.0.7423) escribió:

Carton Jeston (9.0.0.7423)

unread,
May 25, 2015, 1:32:23 AM5/25/15
to publice...@googlegroups.com, gabriel_...@hotmail.com, carton...@gmail.com
Integral, veo que lo entendiste mal, es lo que pasa por leer el foro en horas intempestivas :-)

Y hay que saber interpretar las ironias, los smiley y los jajaja (sino pregunta a Antonio Meza los problemas que esto ultimo le ha causado).

El tema de preguntar mas alla de "mi problema" era conocer todas las variantes que se les ocurriera o otros compañeros y el resultado es que en este hilo tenemos varias formas de hacerlo y el dia de mañana cualquiera que lo lea tendra la solucion de la forma que mejor le convenga.

Es mas, deduciendo de los ejemplos que mencionas he llegado a la conclusion que usando objetos o evaluate+execscript evitas problemas de macrosustitucion, asi que el objetivo del hilo ha sido mas que satisfactorio.

Y para acabar un par de reglas de "buenas costumbres" si el dia de mañana piensas usar el compilador VFP C++:

1. No usar STORE, solo definir variables con =
2. Para macrosustitucion no usar &, solo evaluate+execscript (Nota: creo que solo lo afecta en la linea donde pondriamos el exescript pero del otro modo es aun mas seguro).

un saludo

Carton Jeston (9.0.0.7423)

unread,
Aug 2, 2015, 5:55:24 AM8/2/15
to Comunidad de Visual Foxpro en Español
Han pasado dos meses, de los cuales uno casi no he podido tocar la nueva version de mi aplicacion separando capas, aplicando buenas practicas, etc.

Ahora vuelvo a la carga, segun me permita el tiempo disponible, pero tengo que decir que es mucho trabajo pero vale la pena.

No me resulta posible rehacer desde cero una aplicacion tan grande, pero lo que si estoy haciendo es un framework para formularios, usando clases para todo desde un principio y preparando para ncapas y asi saltar mas adelante a foxydb sin tanto trauma.

Asi que los pasos a seguir son:

1. Olvidarte de lo mucho que crees saber.
2. Leer y aprender a codificar segun buenas practicas (hasta donde puedas)
3. Aprender control de versiones.
4. Crear un framework a tu gusto que sirva para todo, fichas de clientes, facturas, etc. programando en ncapas y hazlo por clases. Todo el tiempo que le dediques a automatizar esta clase, es trabajo que te ahorraras (en proporcion 1 a 10).La ventaja es que si lo haces tu, siempre lo entenderas mejor, sabras como funciona para mejorarlo o resolver problemas.
5. Hazlo sobre una COPIA de tu aplicacion real, asi tendras problemas reales.
6. No tengas prisa.

El resto vendra sobre la marcha, en mi caso he expandidola vida del foxpro con el VFP C++ y pienso usar firebird o similar con la libreria foxydb y espero tener fox para rato.

un saludo

Fernando D. Bozzo

unread,
Aug 2, 2015, 6:22:52 AM8/2/15
to publice...@googlegroups.com
Muy buena noticia :)

Cuando te pongas a reestructurar o refactorizar módulos, tené siempre presente una cosa: Hacelo lo más sencillo posible.

Te puede pasar, como todo el que ha hecho su propio framework, que vas a querer que el framework lo controle "todo" y comiences a crear clases para hacerlo todo.
No caigas en la tentación, porque a veces pasa que terminás creando tantas dependencias del framework, que luego te es muy difícil o imposible ejecutar tus forms sin cargar unas cuántas cosas antes.

Simplicidad, funcionalidad mínima por método, métodos "orquestadores" de funcionalidades complejas, mucha encapsulación y siempre que puedas, Unit Testing!!


Como anécdota te puedo comentar que estas últimas semanas estoy rehaciendo la programación de unos programas de mantenimiento de tablas con una lógica particular del dominio del negocio al que dan servicio, y que gracias a haber aplicado Unit Testing con FoxUnit en varios métodos (no en todos), pude avanzar en la programación más rápido que si no los hubiera hecho.

Aunque parezca difícil de entender, hay veces que aplicando Unit Testing, con la programación extra que conlleva hacer casos de prueba, se puede ir más rápido, y el motivo es que gracias a esos casos de prueba (seleccionados porque aportan mucho valor al proceso de pruebas), pude testear el código mientras lo programaba muchas más veces que si lo hubiera probado todo manualmente, como suele hacerse tradicionalmente.

Un ejemplo:
Preparar una prueba manual de uno de los casos de uso, que hubiera requerido preparar un juego de datos particular, anotar los valores que esperaba encontrar al finalizar el proceso y luego ejecutar el programa y comparar los valores obtenidos, me podría haber tomado varias horas (más de 4 hs), y encima esa prueba no hubiera sido reutilizable, por lo que detectar un error y volver a probar hubiera requerido el mismo tiempo multiplicado pro la cantidad de veces que tuviera que repetirlo. Pero como automaticé el caso de prueba, con un juego de datos específico y la respuesta de valores esperados, me tomó 2 hs hacer el caso de prueba con FoxUnit, y luego me tomó 1 a 2 segundos cada ejecución de ese caso de prueba, por lo que cada error lo pude solucionar sobre la marcha y comprobar el resultado ejecutando los tests.


Saludos! :D

Carton Jeston (9.0.0.7423)

unread,
Aug 3, 2015, 10:44:38 AM8/3/15
to Comunidad de Visual Foxpro en Español
Fernando,

He tardado tanto porque aunque uso tu articulo como guia, aunque he probado diferentes caminos para determinar cual se ajustaba mejor para adaptarlo en mi aplicacion programando aun menos.

Por ejemplo, he usado scatter/gather para leer o guardar en el registro pero cuando hay campos que en vez de llamarse en el control loreg.recargo se llama oapp.orecargo.valor se complica un poco. Al final copio loreg.recargo en la etiqueta tag y en el control meto el oapp cuando son campos con validacion y usando metodos automatizados ya se encarga cuando lee o guarda de incluir estos campos.

Para eso he hecho metodos especializados como navread, navsave, navrefresh o navdefault (este pone todos los valores por defecto para que no se queden vacios al añadir uno nuevo) asi cuando necesito modificar un registro hago un navread-modifico lo que quiero-navsave. Esto ultimo seria un metodo orquestador como lo llamas tu :)

Es una manera de que el framework ahorre tiempo, aunque tengo que ayudarlo estandarizando nombres en las reglas de negocio, valor  (no c_valor o n_valor), validacion incluiria las reglas de validacion, que viene a ser como usar value o valid del formulario pero en las reglas de negocio y al usar siempre los mismos nombres, esos metodos automatizados lo gobiernan todo.

Me parecio un inconveniente tener que modificar un programa ya creado con mucho codigo en sus espaldas y lo sigo pensando. Lo que hay que hacer es hacer uno totalmente nuevo pero copiando las partes que se pueden aprovechar, campos de formularios, etc. Y la gran ventaja al tener una aplicacion hecha, es que la tomas como un prototipo y al hacer la nueva ya sabes todo lo que le vas a pedir a cada una de sus funcionalidades y ahi noto que estoy ahorrando muchisimo tiempo.

Respecto al Unit Testing, tengo el enlace guardado con tu articulo, pero eso lo tendre en cuenta cuando pase el verano, que con este calor no consigo meterme mas cosas en la cabeza jajaja

Es curioso, a finales de los 80 cuando aprendi clipper hice mucho codigo spaguetti porque no habia ni informacion ni manera de aprender como no fuera ensayo y error. Años mas tarde usando un editor de pantallas hice un generador que me permitia poner comandos simplificados tipo cogereg y luego creaba la aplicacion visual. Todo muy sencillo y optimizado. Que sabia yo que eso se llamaria mas adelante rad y lenguaje visual. En la entrada a foxpro 2.6  lo aprendi a golpe de guia de comandos y volvi a cometer el mismo error con las tecnicas de la churrera. La suerte es que ahora se puede aprender de gente que conoce el camino y creo que no hay mejor manera de agradecerlo que intentar aprender y seguirlo o incluso abrir uno nuevo.

Gracias por todo a ti al resto de evangelizadores foxeros de este foro :)

Carton Jeston (9.0.0.7423)

unread,
Aug 6, 2015, 4:18:42 PM8/6/15
to Comunidad de Visual Foxpro en Español
Cuanta razon tienes, cuando te pones a escribir lineas como un poseso se tiende a caer en los mismos errores de siempre. Ahora repaso y trato de eliminar lineas, por ejemplo:

Una simple rutina de tres lineas que va el final de la tabla y devuelve el ultimo+1 que se repite varias veces en un formulario, ahora la pongo en un metodo, porque si se ocurre añadir algo mas, como controlar si es caracter o numero, basta que se te olvide cambiar una vez para volver a lo de siempre.

Lo mismo pasa con la encapsulacion, es trabajar un poco mas hoy para no tener que trabajar mas mañana. :)

Creo que antes hacer un formulario me podia llevar una tarde o un dia, diseñar el framework siguiendo las buenas practicas (no al 100%) me lleva mas de un mes, pero cuando me ponga a convertir los viejos formularios, sera mucho mas rapido, mas facil de mantener, mas escalable y ampliable, etc.

No es facil encontrar el momento justo, quizas lo marca el propio mercado, en mi caso la necesidad de hacer la aplicacion tactil, trabajo en red y mas tarde foxydb. Calculo que por cada mes que lo dedique a rehacerlo desde cero con las buenas practicas, me ahorrare tres mas modificando lo que ya tengo.

Y todo esto lo digo para animar a otros a dejar el lado oscuro de la programacion :)

un saludo
Reply all
Reply to author
Forward
0 new messages