Insertar un registro sin ir al final de la tabla

5,557 views
Skip to first unread message

Misael Rocha P

unread,
Apr 23, 2013, 1:37:30 AM4/23/13
to publice...@googlegroups.com
Hola buenas noches, espero me puedan orientar ayudar y/o resolver en mi duda jejeje, con el debido respeto por supuesto!!!
 
Veran necesito insertar un registro pero no al final de la tabla sino posterior al registro en el que se encuentre actualmente, es decir como ejemplo, suponiendo que esta en el registro mm... haber en el 38 de la tabla, ah pues que al insertar lo haga en el 39, cabe aclarar y mencionar que los registros no estan numerados consecutivamente pues su contenido no se basa en id_consecutivo por asi decirlo sino que el 38 que les hice mension fue donde el cursor se encontraba.
 
Me podrian ayudar indicandome que debo de hacer o como seria el codigo para hacer lo que requiero?
 
de antemano muchas gracias por su ayuda, espero haberme dado a entender en mi situacion.
 
Saludos.

Misael Rocha P

unread,
Apr 23, 2013, 3:11:38 AM4/23/13
to publice...@googlegroups.com
Hola buenos dias! siguiendo buscando encontre esta linea de codigo
INSERT BLANK pero manda el siguiente error "command cannot be issued on a table with cursors in table buffering mode para esto tengo
 
SET MULTILOCKS ON
 
CURSORSETPROP("Buffering", 5,"dbf_tabla")
 
AL QUITARLO MANDO OTRO ERROR
 
INSERT cannot be issued when de row or table buffering is enabled or when

Misael Rocha P

unread,
Apr 23, 2013, 3:12:35 AM4/23/13
to publice...@googlegroups.com
integrity constraints are in effect, y desconozco como solucionar esta incidencia!!!
 
 

arti...@gmail.com

unread,
Apr 23, 2013, 4:25:32 AM4/23/13
to publice...@googlegroups.com

Para poder insertar un registro en una tabla, la tabla no debe de tener índices, si los tiene  no funciona.
En  caso de que la tabla no tenga índices, posiciona el puntero en el registro en donde quieres insertar
y entonces haz un INSERT BLANK BEFORE y verás que ahora sí, se genera un registro en blanco en 
medio de la tabla. El motivo de porqué no lo hace cuando la tabla tiene algún índice, lo desconozco.

Carlos Miguel FARIAS

unread,
Apr 23, 2013, 6:11:41 AM4/23/13
to Grupo Fox

Insertar físicamente un registro en una tabla es algo tan viejo como dbase II .
Exige tabla en uso exclusivo.
No puede usarse ningún tipo de Buffer
El tiempo para insertar un registro en forma cuadrática al crecimiento de la tabla.
Es mas rápido.
Copiar la tabla hasta el registro anterior. Agregar el nuevo en la tabla destino y luego copiar el resto de la tabla.
Además, es una lógica que solo funciona con tablas nativas.
Y no si el tener índices impide hacer inserción física pero que cada índice te dobla el tiempo, fácil.
Y si la tabla no es local, te encargas de apagar la luz a la noche cuando te vayas, el día siguiente.
Saludos: Miguel, La pampa (RA)

Analyzer

unread,
Apr 23, 2013, 4:44:39 PM4/23/13
to Comunidad de Visual Foxpro en Español
Y Porqué quieres insertar un registro por enmedio de la tabla?...

Por qué el contenido de los registros no están numerados?..

No sería eso un error en el diseño de la BD?...

Estas usando tablas nativas o un manejador?..

Cuál es el escenario?..

Qué deseas lograr?...

Al menos yo no le veo mucho sentido a lo que intentas hacer.

En una situación normal con tablas nativas lo que hago es insertar el registro al final de la tabla y el índice se encargaría de ordenar el dato en la posición que le corresponda. Siempre uso un dato tipo id en todas las tablas.

No recuerdo haber usado una tabla sin un campo que sirva de clave tipo id.

Si aclaras un poco qué deseas lograr y por qué quieres hacerlo de eso forma, ayudaría.






Saludos!


El 23 de abril de 2013 00:37, Misael Rocha P <misael....@gmail.com> escribió:

RickDeCastro

unread,
Apr 23, 2013, 7:58:44 PM4/23/13
to publice...@googlegroups.com

Si te fijas en la ayuda, el comando INSERT [BEFORE][BLANK] solo sigue existiendo en Visual Foxpro para mantener compatibilidad hacia atrás.
Ya en la época del FoxPro 2.6 DOS/Windows era considerado un comando obsoleto y que ya no debería ser utilizado con las modernas "bases de datos". Se recomienda usar APPEND o INSERT - SQL.

Creo recordar que el comando INSERT solo trabaja correctamente sobre tablas LIBRES y sin índices. Si el archivo está indexado, el INSERT funcionará como un APPEND y mandará el registro al final de la tabla.

Si piensas bien, en la realidad a nivel de datos, no tiene importancia ninguna la posición en que se encuentre un registro en la tabla, ya que puedes ordenar la misma en muchísimas y variadas formas. Además, si utilizas INSERT con una tabla grande, la ejecución puede llevar mucho tiempo ya que deberá reescribir todos los registros. Solo debes tener un campo que se encargue de ello y listo (en tu caso, el ID_consecutivo).
 
---
Saludos insertados.
Ricardo De Castro Aquino
Asunción - Paraguay

Misael Rocha P

unread,
Apr 23, 2013, 8:33:53 PM4/23/13
to publice...@googlegroups.com
Hola buenas tardes a todos, les agradezco arti..., Miguel, Analyzer, RickDeCastro su apoyo, pues bueno si entiendo que tal vez no tenga logica del por que o para que necesito insertar un registro en medio de varios, lo que pasa que con la situacion de cobranza, pagos, cuentas por cobrar, resulta que si un registro de la tabla dbf_ctasxcobrar lo recuperan, lo busca en la tabla dbf_pagos, y lo añade al ultimo registro que tenga saldo y debe ser exactamente en esa posicion para que recalcule el saldo, que les comento que al mandar el error y dar ignorar lo hace, y pues si inserto el registro de manera convencional me lo posiciona al final y entonces se pierde continuidad y no recalcula el saldo pues de 14 registros puede que vaya en el decimo por decir algo y en ese decimo registro este el saldo actual, se que tal vez sea algo complicado la idea o el modo en que quiero que el programa funcione pero por la necesidad asi es como debe de ser!!! lamentablemente la tabla a la que se le va a añadir el registro tiene y debe de contener indice y buffering y el set exclusive off existe pues mas de uno ocupan el programa y como se ve en mi caso ese comando no resultaria obsoleto salvo casos muy especificos o raros que es el mio!!!
 
Entonces no hay alguna otra manera para qeu ese error no me aparezca? o puedo caputar el error y transformarlo en un messagebox? ¿Uds. que opinan?
 
Saludos y Gracias
 
 

Daniel Sánchez

unread,
Apr 23, 2013, 8:50:52 PM4/23/13
to Comunidad de Visual Foxpro en Español
No seria mejor al adicionar un nuevo pago que primero este ordenado por fecha del pago y que luego recupere los datos de pago del cliente es decir obtener todos los pagos realizados y ya con esos datos recalcular nuevamente los saldos visualizados, no se, se me ocurre, ahora para el caso de saldos por líneas, lo que yo hago es obtener los items en este caso seria tus pagos y una vez obtenidos realizo los cálculos de saldos por cada línea, así me evito estar recalculando los saldos por línea cada vez que adiciono un nuevo elemento, pudiendo ocurrir que me inserten un movimiento posterior o anterior al que tiene el ultimo saldo anterior cosa que creo que es lo que tienes y te complica la cosa.
Un ejemplo simple de algo parecido es un kardex de productos, cuando lo visualizo doy los saldos por línea pero en realidad en la BD dicho saldo no existe solo lo calculo al momento que lo visualizo, así si alguien se olvido de ingresar una compra en una fecha posterior solo lo adiciona y no tengo mayor inconveniente ya que al volver consultar y realizar el calculo de saldo por línea este se visualiza sin problemas ya que solo se hace en ese momento de la consulta.
Imágenes integradas 1

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

Carlos Miguel FARIAS

unread,
Apr 23, 2013, 9:16:59 PM4/23/13
to Grupo Fox

Misael. El comando insert necesita la tabla en exclusiva, y no puede usar Buffer. Y si la tabla es grande es impracticable,
Si quieres manejar registros en orden, crea un campo de orden. Puede ser un numerco con decimales.
Las operaciones las vas numerando de 1 en 1.
Cuando necesitas insertar, al nuevo registro le das un valor promedio de los números de orden entre los cuales quieres insertar (por ejemplo, quieres insertar entre el 14 y el 15. Entonces el numeró de orden le das un valor 14,5 (14.5) y con un índice sobre el campo orden,, al activar el correspondiente, obtienes el registro en la ubicación deseada.
Los registros los ubicas físicamente siempre al final, pero el campo orden te los ubica en la ubicación "lógica" requerida.
Saludos: Miguel, La Pampa (RA)

image.png

Misael Rocha P

unread,
Apr 24, 2013, 2:05:41 AM4/24/13
to publice...@googlegroups.com
Buenas Noches, ammm... veamos para no enredarlos la cosa esta asi, el por que lo hice asi? pues me resulto mas practico pero bueno funciona a todo esto va lo siguiente y del por que el origen de mi cuestion espero poder ser lo mas concreto especifico y entendible posible para poder darle solucion con su ayuda :D
 
Mi Base de Datos:
 
BDATOS_DBC
 
Mis Tablas:
 
dbf_clientes, dbf_empresas, dbf_contratos, dbf_cobranza, dbf_pagos, dbf_ctasxcobrar
 
en dbf_empresas tengo id_empresa y empresa
en dbf_clientes tengo id_empresa, id_cliente, cliente y muchos mas...
en dbf_contratos tengo id_contrato, id_empresa, cliente, empresa y muchos mas...
en dbf_cobranza tengo id_empresa, id_contrato, id_cobranza, folio, empresa, cliente y muchos mas...
en dbf_pagos tengo id_pago, id_empresa, empresa, cliente, fechapago, abono, saldo y muchos mas...
en dbf_ctasxcobrar tengo id_ctasxcobrar, numpago, cliente, empresa, folio, cliente, arecuperar, fechapago y varios mas...
 
el poner muchos mas... es para centrarme en lo que les continuo platicando y no por que no tengan importancia... :)
 
 
Ok el proceso inicia de la siguiente manera, previamente tengo la tabla dbf_empresa cargada con datos por ejemplo id_empresa = 1, empresa = MISAEL
id_empresa = 2, empresa = SANTIAGO
id_empresa = 3, empresa = LUIS
 
ok acto seguido yo al seleccionar por ejemplo la empresa 2 habilito el poder caputar clientes(dbf_clientes), contratos(dbf_contratos), con esto filtro todos lo que corresponde a MISAEL, SANTIAGO Y LUIS lo hago con SET KEY TO (Y EL NOMBRE DE LA EMPRESA)
 
Luego se capturan los contratos donde aparte de poner el monto del prestamo selecciono selecciono el cliente los cuales son estrictamente de la empresa seleccionada en este caso fue la 2 que refiere a SANTIAGO, por lo tanto puedo usar todos los clientes de esa empresa unicamente de esa despues al guardar el contrato los datos se van a 3 tablas dbf_contratos(funge como archivero de contratos), dbf_cobranza (su propio nombre lo dice, la cobranza total de la empresa de contratos activos) y dbf_pagos ( 14 pagos generado automaticamente cuando capture el contrato que son los 14 de base por cada cliente, este lleva el control de los pagos  saldos, fechas, abonos, si pago o no pago)
 
La relacion entre las tablas dbf_cobranza y dbf_pagos lo hace mediante el cliente, pudiera ser id_cliente pero opte por hacerlo por cliente visualmente entre tanto numero identificas a manera de revision o x y o z el cliente, entonces en pantalla visualmente al seleccionar un registro de cobranza al lado me muestra 14 registros ordenados numericamente por id_pago, 1, 2, 3...14, pero no por set order sino porque asi fueron generados y guardados, asi como la fecha de pago, el abono, el saldo y si pago o no pago, y uno mas recuperado estos 3 ultimos son campos logicos, entonces al seleccionar el cliente si realiza el pago pues bueno hace el calculo que era lo que me referia si debe 1400 su abono es de 100 por lo tanto añade los 100 se los resta a los 1400 y en el siguiente registro (2) coloca el nuevo saldo 1300,  solo es aplicarles el pago o no aplicarselos o recuperar, las fechas ya estan generadas, si paga a la fecha lo pone como pagosi, si no pago en la fecha indicada, coloca pagono y ese registro qeuda en abono 0 y el saldo lo pasa al siguiente registro, a partir de que este registro donde no se realizo el abono, se inserta uno nuevopero ahora en la tabla dbf_ctasxcobrar donde me almacena la informacion de dicho registro de dbf_pagos, por lo tanto al irme a la tabla dbf_ctasxcobrar resulta que por dar el ejemplo  ya pagó la persona dicho atraso, es decir en otras palabras lo recupera, bueno pues ese registro lo selecciono y recupero el abono, lo que deseo qeu haga es qeu se vaya al saldo actual añada el abono, reste al saldo y coloque el nuevo saldo en el siguiente registro, pero en ese registro que se recupero el id_pago seria el id_pago que no se llevo a cabo su pago, la fecha en que se recupera, entonces al insertar un nuevo registro convencionalmente si como bien esta lo hace al final pero como el orden esta por cliente por la relacion entre ambas tablas es asi, el id_pago no me añade en la posicion que le corresponderia, pues si lo ordeno por id_pago al ser muchos resgistros de 14 en 14 repetidamente no habria orden en los saldos, por eso la inquietud de poderlo insertar entre tantos registros y no al final, para muestra les adjuntare pantallas de hacerlo con el insert blak y/o con el insert, append blank
 
Saludos y Gracias por su paciencia.
 
 
 
 
 
PAGOS1.png
PAGOS2.png
PAGOS3.png

Carlos Miguel FARIAS

unread,
Apr 24, 2013, 7:38:51 AM4/24/13
to Grupo Fox
Se entiende lo que quieres hacer, pero me parece muy rebuscado.
Primero, fisicamente, es "imposible" que puedas hacer la inserción en el punto que quieres.
a) Si estas en red, NECESITAS LA TABLA EN FORMA EXCLUSIVA (si el entorno es multiusuario, olvidate de un INSERT FISICO).
b) Es correcto que trabajes con buffer, para reducir el tráfico de red.
c) Cuando anulas el error (o sea lo ignoras), el registro queda bien ubicado, ¡porque estas mirando el buffer!, en el momento que el buffer se transfiere a la tabla física, el registro se ubica al final.
d) Imagino que no tenes 10 clientes si no muchos más, según tus datos, una transacción genera 14 cuotas, ai tienes 1000 clientes, implica 14000 registros en la tabla donde quieres insertar. Si la tabla está en un servidor, para hacer un INSERT físico, la tabla completa debe ir y venir por la red. Entonces OLVIDATE DEL INSERT FISICO!!!

Soluciones:
a) Lo que te explique en un post previo, o sea, usando una columna adicional, donde guardas el orden lógico. Como veo que no lo entendiste, o no preguntaste, no lo relato de nuevo (salvo petición expresa).
b) Tu modelo de datos es complejo por lo que veo de lo que detallaste.
--> Cuando generas un contrato, generas todas las cuotas correspondientes. Pero esas cuotas son las que se cobran, se recuperan, o se deben.
Por lo que puedo deducir de tu modelo, por cada estado posible, creas un registro en una tabla aparte, lo que no tendría sentido, porque lo solucionas agregando una columna que te indique el estado del registro (pendiente, cobrado, recuperado, vencido, a vencer, etc.)
Y deberás agregar algún campo apropiado, como fecha, quien cobro, id documento con que se cobro, importe cobrado (por si difiere del real), intereses, etc.
Esos campos, al generar la cuota, tendrán un valor nulo (salvo estado, que será a vencer)
Y a medida que se cobra, o se recupera o lo que sea, vas cambiando el estado y completando los datos correspondientes.
Espero haberte dado una orientación de solución. En todo caso, seguimos con la tormenta neuronal (;-D
Saludos: Miguel, La Pampa (RA)


leonardo trujillo

unread,
Apr 24, 2013, 11:38:15 AM4/24/13
to grupo google vfp
en un entorno multiusuario, si pones el form en sesión privada de datos, haces lo que quieras y fox se encarga de los bloqueos, así que el "olvidate de un INSERT FÍSICO" no creo que aplique.
¿no les parece?
además, no me queda claro eso de que la tabla va y viene completa por la red al hacer el insert

Carlos Miguel FARIAS

unread,
Apr 24, 2013, 2:08:12 PM4/24/13
to Grupo Fox

Leonardo. Si la tabla es compartida, hasta el fox 2.0 para red te hace los bloqueos automáticos. No necesitas sesión privada para eso.
Acá se esta discutiendo el insert de dbase, no el de SQL.
El de SQL te inserta al final de la tabla. Igual que el append blank, con la diferencia que no usas luego replace.
El insert físico. Necesita uso exclusivo. bloqueos?
Y si supieras como trabaja, sabrias que el fox toda la tabla, inserta el registro correspondiente, y escribe la tabla de nuevo.
O sea. La tabla va y viene por toda la red.
Y no contesto más. Hasta que no haya un pregunta seria de este tema. Me arto.
Quieren comer una pizza, y se quejan de que se les quema la torta de manzanas usando peras


Saludos: Miguel, La Pampa (RA)

leonardo trujillo

unread,
Apr 24, 2013, 2:15:27 PM4/24/13
to grupo google vfp
Carlos, creo que no es para enojarse, si te fijás puse lo que creía y luego pregunté si no era así. Supongo que en las relaciones humanas cuando uno no sabe pregunta y cuando uno cree algo lo explicita y luego abre la duda, para que otros que saben o tienen posiciones diferentes las compartan y debatan.
Parece que estás algo "alterado", no es mi culpa.

Con respecto al tema ¿hablamos de entornos multiusuario? ¿hablamos de tablas nativas? ¿no necesitás sesión privada para bloqueos automáticos? me parece que eso no es lo que dice la ayuda de fox.

Y si no querés contestar preguntas, no las contestes y si te molestan los simples mortales no bajes del olimpo
salú

Analyzer

unread,
Apr 24, 2013, 3:38:09 PM4/24/13
to Comunidad de Visual Foxpro en Español
jaja.. Esa va a ser la frase de la semana. Muy buena !!

 "y si te molestan los simples mortales no bajes del olimpo.."


Saludos!

Carlos Miguel FARIAS

unread,
Apr 24, 2013, 6:15:40 PM4/24/13
to Grupo Fox

No me molestan los mortales. Solo los equivocados que creen tener razón sin argumentos.
Trato de dar una solución y salen cualquier p....s .
Indico una solución y no dicen no entendí. Hacen aseveraciones que ni siquiera corresponden a la pregunta inicial.
Entonces, me molesto porque veo que pierdo tiempo, ofreciendo ayuda, que encima te recriminan porque no les gusta, o peor, no la entienden.
Y la frase, me resbala, si no creo en dioses (mal) documentados, menos voy a creer en los sin documentos.
No me molestan las preguntas, me molestan los que se meten a opinar sin saber ni peor, sin razonar.
Saludos al resto del foro.

leonardo trujillo

unread,
Apr 24, 2013, 6:27:45 PM4/24/13
to grupo google vfp
Carlos, la verdad que no respondiste a mis dudas. Mirá que estoy armado con argumentos, si la querés seguir: a las órdenes, pero con berrinches de superdotado no puedo.
Te repito, intervine en algo que creo que me asiste la razón, pero puedo estar equivocado.
Si trabaja en entorno multiusuario, entonces lo mejor es trabajar con sesión privada de datos y dejar que los bloqueos sean automáticos, cada una de las instancias de los formularios abiertos tiene una copia de las tablas (en forma de cursores) en sus entornos de datos http://msdn.microsoft.com/es-es/library/cc466417%28v=vs.71%29.aspx
Así, hacés lo que querés con los datos y dejás al motor que se encargue.
Eso es lo que entiendo de la ayuda y de programar sistemas de este tipo, claro, hablo de INSERT sql, porque a esta altura no se me ocurre de hablar del otro, que según la ayuda

INSERT (Comando)

Se incluye por compatibilidad con versiones anteriores. Use APPEND o INSERT - SQL en su lugar.

Vos ves

Carlos Miguel FARIAS

unread,
Apr 24, 2013, 6:37:06 PM4/24/13
to Grupo Fox

La pregunta original era sobre el insert físico, no el de SQL.
Y no he necesitado usar sesiones privadas para multiusuario. La sesión privada independiza en una aplicación la forma en que se abren las tablas.
En una sesión la abres con alias, le activas un índice y te posicionas en cualquier registro, y en otra sesión, le podes dar otro alias ubicar te en otro lado sin alterar la primera sesión.
Dentro de la misma corrida. Por supuesto, que si en dos sesiones que res tener abierta la misma tabla. Debes abrir las compartidas.
Y el famoso insert físico exige uso exclusivo.
Seuo
Saludos: Miguel, La Pampa Argentina. El Olimpo esta en Grecia. (;-D

Ricardo Pina

unread,
Apr 24, 2013, 6:48:52 PM4/24/13
to Grupo VFP
Carlos
Estoy en casi todo de acuerdo con tus apreciaciones menos en una fundamental en toda esta discusión
El Monte Olimpo esta en Marte.!!
Leonardo
Si Carlos esta en el monte Olimpo, yo soy Thor .... pe
Ismael
Ya te dieron la solución y además te aconsejaron replantearte el problema buscando otra alternativa a lo cual me sumo.
 
Saludos all
--
            

                   Ricardo Pina

Desarrollo y Servicios Informáticos

                  Profesionales
               www.dsip.com.ar

 

 

Misael Rocha P

unread,
Apr 24, 2013, 8:24:27 PM4/24/13
to publice...@googlegroups.com
Hola buenas tardes por lo que veo aca se puso la cosa color de hormiga, pero bueno yo soy de mexico y aca hay una frase tipica viejisima que dice "a lo que te truje chencha"
 
lamento que haya digsutos eso es malo para el corazon y el estado de la salud. espero ya hayan pasado esos malos ratos, buenos deseos para todos y sobre todo gracias por su ayuda y paciencia.
 
En relacion al tema veo que no hay manera como lo dices Miguel de hacer exactamente y especificamente lo que pido, sin embargo comentas que hay alternativa, y si bien lei con atencion pues entonces no entendí, entonces pues asi como lo planteas deseo si me puedes decir o dar la alternativa en algun ejemplo practico por favor?
 
el hecho que posicione a donde debe de posicionarse radica en el siguiente codigo:
 
 
Titulo= '¿Desea recuperar este abono?'
Mensaje = '¡Atencion!'
BotonIcono = 4+32
Boton1 = "Recuperar"
Boton2 = "Cancelar"
respuesta = _msgbox(Titulo, BotonIcono, Mensaje, Boton1 , Boton2)

DO case
 
 CASE respuesta = 6
  SELE dbf_pagos
  LOCATE FOR ALLT(UPPER(dbf_ctasxcobrar.cliente)) = ALLT(UPPER(dbf_pagos.cliente))
  SCAN WHILE ALLT(UPPER(dbf_ctasxcobrar.cliente)) = ALLT(UPPER(dbf_pagos.cliente))
   IF !pago 
    
    nSaldo = saldo
     
--->    aqui es donde pretendia o pretendo insertar el registro 
    
    REPLACE abono WITH dbf_ctasxcobrar.arecuperar
    REPLACE pagosi WITH .F.
    REPLACE pagono WITH .F.
       
    REPLACE pago WITH .T.
    REPLACE pagoa WITH .T.
    
    replace fechapago WITH DATE()
    replace id_pago WITH dbf_ctasxcobrar.numpago
    replace cliente WITH dbf_ctasxcobrar.cliente
    replace empresa WITH dbf_ctasxcobrar.empresa
   
    nSaldo = nSaldo - abono
    nRecu = abono
    nRecuActual= dbf_cobranza.recuperado 
    nRecTot = nRecuActual + nRecu
    replace dbf_cobranza.recuperado WITH nRecTot
    SKIP 1
    REPLACE saldo WITH nsaldo
    
    TABLEUPDATE(1,.F.,'dbf_pagos')
    TABLEUPDATE(1,.F.,'dbf_ctasxcobrar')
    TABLEUPDATE(1,.F.,'dbf_cobranza')
    thisform.pageframe1.page1.grdDbf_pagos.Refresh()
    EXIT
    
   ENDIF
    
  ENDSCAN
  
  SELECT dbf_ctasxcobrar
  DELETE
  thisform.pageframe1.page2.grdDbf_ctasxcobrar.Refresh()
  
ENDCASE
  
 
 
 
 
 
 

Carlos Miguel FARIAS

unread,
Apr 24, 2013, 8:50:06 PM4/24/13
to Grupo Fox

Ricardo. El monte Olimpo original, esta en Grecia, Marte es el nombre de un dios de la mitología griega que ponía a sus dioses en el monte Olimpo. Si es cierto que en el planeta Marte hay un volcán (?) Denominado Olimpo y resulta ser el accidente geográfico solido conocido mas grande del sistema solar (30km de altura).
Y si es cierto, no estoy en el monte Olimpo ni me baje de el.
Y Thor que yo sepa, es un dios de la mitología nórdica y no griega,
Misa el, pasa me la estructuras de tus tablas y veo mañana de tirar te un solución. Ahora desde la tablet, me cuesta un contenedor de futura descendencia darte una respuesta apropiada.


Saludos: Miguel, La Pampa (RA)

Daniel Sánchez

unread,
Apr 24, 2013, 9:02:36 PM4/24/13
to Comunidad de Visual Foxpro en Español
Carlos F. disculpa mi intromisión pero Marte es el Dios de la Guerra en la cultura romana, en la griega es Ares.

Saludos

Ricardo Pina

unread,
Apr 24, 2013, 9:08:55 PM4/24/13
to Grupo VFP
Hola
 
jajaja, Eso de monte original me mató, me hizo acordar hace unos días atras intenté comprar una camiseta de futbol en una feria callejera y me quería cobrar un contenedor de los míos y se lo dije, a lo que el vendedor me dijo sin reirse "sale xx pesos porque es una replica original", jaja
pero bue, todo esto reafirma que soy bastante thor... pe
 
Saludos
 

Jairo Miranda

unread,
Apr 24, 2013, 9:42:13 PM4/24/13
to publice...@googlegroups.com

Existe una extructura de datos llamada PILAS , donde se aplica el algoritmo  para insertar o sacar registros del archivo en cualquier posición , no es aplicable a las DBF ya que estas manejan la estructura de datos de Filas  o listas , los registros se añaden al final de la fila o de la lista , cuando se quita un registro se reordena el archivo.  El caso de trabajar en EXCEl  para insertar un registro ,  o fila  notas que las celdas se reordena automáticamente.  , debes entonces utilizar un método o algoritmo de inserción que copie ese modelo.

JM

Misael Rocha P

unread,
Apr 24, 2013, 11:39:27 PM4/24/13
to publice...@googlegroups.com
Ok hecho, esta es la estructura de las tablas, te agradezco mucho tu apoyo,
 
Saludos y Buenas Noches a todos. 
 
 
DBF_PAGOS.png
DBF_CTASXCOBRAR.png

Carlos Miguel FARIAS

unread,
Apr 25, 2013, 7:13:31 AM4/25/13
to Grupo Fox
Con respeto a Marte y Ares tienes razón. En realidad la mitología romana copio toda la "historieta" de la mitología griega y le cambio los nombres a los dioses (igual que muchas otras religiones que llaman dios, jehova, ala, etc. y sería el mismo).
Pero eso es tema religioso y todavía no es viernes.
En cuanto a la estructura de datos llamada PILAS (STACK) no permite insertar datos en cualquier lado, solo en la parte superior (y al extraer, también se extrae de la parte superior), es una estructura LIFO, último entrada, primero salido (ejemplos, pila de platos para lavar, pila de ropa para planchar, pila de libros para estudiar estructuras de datos).
Tampoco serviría una estructura COLA, que agrega por un extremo y sale por el otro (ejemplo, cola del supermercado, cola para pagar en el banco, para comprar entradas para el futbol, para conseguir libros en la biblioteca sobre estructuras de datos).
Tampoco serviría una Deque, que es una Cola que pueden agregarse y sacarse elementos de ambos extremos.
A lo que te estarías refiriendo es a una lista encadenada, con encadenamiento simple o doble.
Pero no sirve para el caso.
Misael:
Viendo tus tablas, veo que tienes un problema de diseño muy significativo.
Pareciera que por cada cuota, repites todos los datos (clientes, teléfono, etc.), y esos datos se repiten en las dos tablas que me pasaste, y además, en una tabla tienes los datos dimensionados con distintos tamaños.
Entiendo que para resolver tu problema, primero deberías normalizar los datos (el material que pase, tiene una metodología práctica muy fácil de seguir (lo aprenden en 2do año de la carrera de contador en 7/8 clases de 3 horas)
O sea, pensé que tenías algo normalizado +/-, pero esto está muy desordenado y lo que debía ser una solución de de media carilla, implicará todo el proceso de normalización.
Bueno. Te pase como hacerla, si me das especificaciones medianamente detalladas de que tiene que informar el sistema, puedo darte un modelo tentativo, pero así, no me sirve ni para solucionarlo con una planilla de cálculo.
Saludos: Miguel, La Pampa (RA)

Misael Rocha P

unread,
Apr 25, 2013, 8:35:44 PM4/25/13
to publice...@googlegroups.com
Hola Miguel buenas tardes, bueno el hecho de que copié los datos a ctasxcobrar de dbf_pagos es por que es una tabla independiente sin ninguna relacion entre otras y en ella se almacenarian los registros que no se llevan a cabo el pago entonces si el pago se lleva a cabo se regresa ese registro y lo elimina, digamos que es temporal el hecho que comentas de la normalizacion pues tienes razon tienen diferente dimension, eso seria lo de menos que si definitivamente lo debo de hacer ya! es la razon del por que! igual si tienes alguna sugerencia de esta tabla temporal ctasxcobrar bienvenida :D

Misael Rocha P

unread,
Apr 26, 2013, 12:53:14 AM4/26/13
to publice...@googlegroups.com
Aclaro que si repito los todos los datos (clientes, teléfono, etc.) de la tabla dbf_pagos a dbf_ctasxcobrar como te comento por que fungiria como tabla temporal
 
Saludos. 

Carlos Miguel FARIAS

unread,
Apr 26, 2013, 7:12:15 AM4/26/13
to Grupo Fox
Estimado:
Te tiro una solución en función de lo que se puede extractar de tu requerimiento.
Tu generas una serie de registros, que quedan "fisicamente" ordenados, porque, circunstancialmente, dos usuarios no están generando registros a la vez.
Pero supongo que no es tu caso.
En realidad, lo que necesitas, es un orden lógico, derivado de, por ejemplo, el número de cuota, correspondiente a cada "contrato".
Entonces, como la inserción física para mantener el orden físico no es viable, si puedes proceder a hacer una inserción lógica, que respondería a tu requerimiento, de visualizar los registros afines uno al lado (o debajo) del otro.
Habría dos soluciones simples (al menos desde mi punto de vista).
a) Adiccionar un campo de orden en la tabla donde quieres mantener el "orden lógico", podes llamarlo, secuencia, número de orden, ordenador, etc. dicho campo debe tener decimales (depende de cuantas "inserciones" se deben hacer, yo sugiero 2, tu veras).
Sobre ese campo, debes crear un indice, preferentemente permanente.
- Cuando creas los registros, en dicho campo, guardas un valor secuencial, por ejemplo recno(), o ultimo valor más uno, tendrás que discernir cual te conviene.
- Cuando tienes que "insertar logicamente" un registro después de otro, tomas del registro que debe quedar adelante, su número de orden, le agregas por ejemplo 0.3 (3 décimos). y ese número calculado, es el que colocas en el campo de orden del registro insertado
- Luego, al leer la tabla con el indice sobre el campo orden activo, los registros van a aparecer en el orden lógico que tu requieres.
b) Otra solución, es adicionar decimales al campo cuota, el procedimiento es el mismo que con el campo orden, deberás tener la precaución de truncar el campo al mostrarlo y modificar el indice (para prever los decimales) que tengas sobre el campo cuota.

Estas soluciones serían viables aún en el caso de pasarte a un SGBD externo.

En mi opinión, deberías pensar en normalizar los datos, porque las tablas temporarias que permanecen en disco, no son temporarias, son una lacra.
Se justificaban en foxdos (bajo DOS) porque había limitaciones de cantidad de tablas abiertas (255 para fox) pero principalmente por parte del SO.
Ojo, distinto es si hablamos de cursores creados por código o emergentes de un select de sql. Eso no es problema mientras se configure bien el config.

Espero que esto puedas aplicarlo, o inferir una solución a partir de lo que te indique.

Saludos: Miguel, La Pampa (RA)

P.D: No te metas con Maria, DB (;-D

Misael Rocha P

unread,
Apr 27, 2013, 12:26:21 AM4/27/13
to publice...@googlegroups.com
Hola Miguel Buenas noches, ok entendido, voy a aplicar tu valiosa sugerencia, teniendo alguna duda, te molesto solo que me quedó una cuestion, tu post data que quieres decir? jajaja no lo entendi pero me imagino fue un sarcasmo!!!
 
Saludos.

Carlos Miguel FARIAS

unread,
Apr 27, 2013, 8:41:18 AM4/27/13
to Grupo Fox

El pos data, estaba asociado a la broma sobre el SGBD MariaDB que reembplazaria mysql.
Indique que No se metieran porque Maria DeBe y entonces. Quien paga?

Víctor Hugo Espínola Domínguez

unread,
Apr 27, 2013, 11:54:42 AM4/27/13
to publicesvfoxpro
Hola Misael

No entiendo porqué tienes que hacer un INSERT al "recuperar un abono". Creo que lo apropiado es hacer un UPDATE, lo puedes implementar con REPLACE, en tu tabla de pagos.

En cuanto al diseño de tu base de datos, yo lo haría de esta forma:

Empresa { IdEmpresa, RazonSocial, etc... }
Cliente { IdCliente, Nombre, etc... }  Fíjate que no tiene el campo IdEmpresa para que una persona pueda ser cliente de                                 una o más empresas.
Contrato { IdContrato, IdEmpresa, IdCliente, MontoPrestamo, CantCuotas, FechaVencimiento, IdGarante etc...}
Pago { IdPago, IdContrato, FechaPago, NroCuota, MontoMora, etc... }

Saludos,
Víctor.

Misael Rocha P

unread,
Apr 27, 2013, 12:28:54 PM4/27/13
to publice...@googlegroups.com
Hola Victor, Gracias buenos dias, la intencion de insertar dicho registro a la tabla pudiendo hacer un update como bien dices es por que quiero tener ese antecedente como registro, ya al final de que el cliente termine su adeudo, esos registros de pagos quedan como historial crediticio, de cuando realizó el pago, cuando no lo realizó, y cuando se recuperó, es por eso la intención de insertar un registro entre varios pero muy especificamente en el saldo que tenga ese cliente.
 
La parte que estoy trabajando ahorita es en la reestructura de la insercion de los 14 registros con un id consecutivo con decimal para insertarlo entre por decir el saldo esta en el registro 9 y el 10 es una fecha en blanco, pero el id_consecutivo seria por decir un ejemplo el 34.0 y 35.0, al momento de recuperar el abono lo insertaria como 34.5 solo es detallarlo que al insertar el 34.5 primero lo acomode para que tome el saldo de 34 que de los 14 seria 9,
ahora yo pensaba que el insert blank iba a ser una opcion sencilla, práctica y fiable pero resultó que no, todo lo contrario parece por lo que comentan es obsoleta.
 
en el caso del id_empresa en dbf_clientes y dbf_empresas es neceasrio ya que no puede ser cliente "x" persona de dos o mas empresas, esto fue a peticion, de contratos me agradó CantCuotas.
 
Como ves mi triste situacion :)
 
Saludos y Muchas gracias...
 
Saludos.

Víctor Hugo Espínola Domínguez

unread,
Apr 27, 2013, 12:56:23 PM4/27/13
to publicesvfoxpro
Hola Misael

Muéstranos la nueva estructura de la tabla de pagos.

Saludos,
Víctor.

GeoSys Diseño de Software

unread,
Apr 27, 2013, 1:14:12 PM4/27/13
to Comunidad de Visual Foxpro en Español
Misael Rocha, inserta un registro con Insert Into o con Append Blak, lógicamente con n campo fecha, luego ordenas por código de cliente+fecha.

Eso si usas tablas nativas.

Cero problemas, no veo cual es el inconveniente, te quedará ordenado por código de cliente más la fecha del abono, o sea irá en orden que creo que es lo que quieres.

Si es una consulta pues la ordenas igual, por código, fecha de abono.


Saludos

Anthony Contreras Peralta

Costa Rica.



Misael Rocha P

unread,
Apr 27, 2013, 1:33:32 PM4/27/13
to publice...@googlegroups.com
P

Misael Rocha P

unread,
Apr 27, 2013, 1:41:05 PM4/27/13
to publice...@googlegroups.com
Perdon se publico sin querer...
asi tengo la tabla dbf_pagos
 
Saludos.
DBF_PAGOS.png

Víctor Hugo Espínola Domínguez

unread,
Apr 27, 2013, 9:12:35 PM4/27/13
to publicesvfoxpro
Hola Misael

No ver el contrato en tu tabla de pagos, eso implica que un solo contrato puede tener el cliente en el sistema.

El siguiente código te servirá de guía para seguir con tu programa, no sé si tus índices están bien formulados.

Titulo= '¿Desea recuperar este abono?'
Mensaje = '¡Atencion!'
BotonIcono = 4+32
Boton1 = "Recuperar"
Boton2 = "Cancelar"
respuesta = _msgbox(Titulo, BotonIcono, Mensaje, Boton1 , Boton2)

Do Case

Case respuesta = 6
Sele dbf_pagos
Locate For Allt(Upper(dbf_ctasxcobrar.cliente)) = Allt(Upper(dbf_pagos.cliente))
Scan While Allt(Upper(dbf_ctasxcobrar.cliente)) = Allt(Upper(dbf_pagos.cliente))
If !pago

nSaldo = saldo

* --->    aqui es donde pretendia o pretendo insertar el registro

SCATTER NAME loPagos

loPagos.Id_Consecutivo = Id_Pago + 0.5
loPagos.Abono = dbf_ctasxcobrar.arecuperar
loPagos.FechaPago = DATE()
loPagos.loPago = .T.
loPagos.loPagoA = .T.
loPagos.Saldo = nSaldo

INSERT INTO dbf_Pagos FROM NAME loPagos
* Replace abono With dbf_ctasxcobrar.arecuperar
* Replace pagosi With .F.
* Replace pagono With .F.

* Replace pago With .T.
* Replace pagoa With .T.

* Replace fechapago With Date()
* Replace id_pago With dbf_ctasxcobrar.numpago
* Replace cliente With dbf_ctasxcobrar.cliente
* Replace empresa With dbf_ctasxcobrar.empresa

nSaldo = nSaldo - abono
nRecu = abono
nRecuActual= dbf_cobranza.recuperado
nRecTot = nRecuActual + nRecu
Replace dbf_cobranza.recuperado With nRecTot
*??? Skip 1
* Replace saldo With nSaldo

Tableupdate(1,.F.,'dbf_pagos')
Tableupdate(1,.F.,'dbf_ctasxcobrar')
Tableupdate(1,.F.,'dbf_cobranza')
Thisform.pageframe1.page1.grdDbf_pagos.Refresh()
Exit

Endif

Endscan

Select dbf_ctasxcobrar
Delete
Thisform.pageframe1.page2.grdDbf_ctasxcobrar.Refresh()

Endcase

Saludos,
Víctor.

Message has been deleted

Jose Mario

unread,
May 24, 2013, 5:55:33 PM5/24/13
to publice...@googlegroups.com
en la cuarta fila del grid dice 13 mas 10 = 24
estara bueno hace falta una salida de 1


El martes, 23 de abril de 2013 18:50:52 UTC-6, Daniel Sánchez escribió:
No seria mejor al adicionar un nuevo pago que primero este ordenado por fecha del pago y que luego recupere los datos de pago del cliente es decir obtener todos los pagos realizados y ya con esos datos recalcular nuevamente los saldos visualizados, no se, se me ocurre, ahora para el caso de saldos por líneas, lo que yo hago es obtener los items en este caso seria tus pagos y una vez obtenidos realizo los cálculos de saldos por cada línea, así me evito estar recalculando los saldos por línea cada vez que adiciono un nuevo elemento, pudiendo ocurrir que me inserten un movimiento posterior o anterior al que tiene el ultimo saldo anterior cosa que creo que es lo que tienes y te complica la cosa.
Un ejemplo simple de algo parecido es un kardex de productos, cuando lo visualizo doy los saldos por línea pero en realidad en la BD dicho saldo no existe solo lo calculo al momento que lo visualizo, así si alguien se olvido de ingresar una compra en una fecha posterior solo lo adiciona y no tengo mayor inconveniente ya que al volver consultar y realizar el calculo de saldo por línea este se visualiza sin problemas ya que solo se hace en ese momento de la consulta.
Imágenes integradas 1

Saludos


El 23 de abril de 2013 19:33, Misael Rocha P <misael....@gmail.com> escribió:
Hola buenas tardes a todos, les agradezco arti..., Miguel, Analyzer, RickDeCastro su apoyo, pues bueno si entiendo que tal vez no tenga logica del por que o para que necesito insertar un registro en medio de varios, lo que pasa que con la situacion de cobranza, pagos, cuentas por cobrar, resulta que si un registro de la tabla dbf_ctasxcobrar lo recuperan, lo busca en la tabla dbf_pagos, y lo añade al ultimo registro que tenga saldo y debe ser exactamente en esa posicion para que recalcule el saldo, que les comento que al mandar el error y dar ignorar lo hace, y pues si inserto el registro de manera convencional me lo posiciona al final y entonces se pierde continuidad y no recalcula el saldo pues de 14 registros puede que vaya en el decimo por decir algo y en ese decimo registro este el saldo actual, se que tal vez sea algo complicado la idea o el modo en que quiero que el programa funcione pero por la necesidad asi es como debe de ser!!! lamentablemente la tabla a la que se le va a añadir el registro tiene y debe de contener indice y buffering y el set exclusive off existe pues mas de uno ocupan el programa y como se ve en mi caso ese comando no resultaria obsoleto salvo casos muy especificos o raros que es el mio!!!
 
Entonces no hay alguna otra manera para qeu ese error no me aparezca? o puedo caputar el error y transformarlo en un messagebox? ¿Uds. que opinan?
 
Saludos y Gracias
 
 

Jose Mario

unread,
May 24, 2013, 5:59:12 PM5/24/13
to publice...@googlegroups.com
esta instruccion te saca el saldo por filas

SET DATE BRITISH

SET CENTURY on

 

CREATE cursor MiTabla (fecha d, Ingreso n(12,2),Egreso n(12,2),Saldo n(12,2))

 

INSERT INTO MiTabla VALUES(CTOD("30/04/2013"),167,0,0)

INSERT INTO MiTabla VALUES(CTOD("15/05/2013"),167,0,0)

INSERT INTO MiTabla VALUES(CTOD("20/05/2013"),50,0,0)

INSERT INTO MiTabla VALUES(CTOD("24/05/2013"),0,140,0)

 

 SELECT a.Fecha, a.SaldoAnterior, a.ingreso, a.egreso, sum(b.ingreso - b.egreso) AS saldo;

 FROM MiTabla AS a INNER JOIN MiTabla AS ON b.Fecha <= a.Fecha;

 GROUP BY  a.Fecha, a.ingreso, a.egreso, a.SaldoAnterior;

 ORDER BY 1 ASC

Carlos Miguel FARIAS

unread,
May 25, 2013, 9:05:01 AM5/25/13
to Grupo Fox

Jose. Respondes un mes después del hilo original!?

Ricardo Pina

unread,
May 25, 2013, 9:27:39 AM5/25/13
to Grupo VFP
viene con delay el amigo
Alguna vez explico que los lee todos juntos cada tanto
Por ahi sirve sirve para la gente que pregunta lo mismo que fue contestado hace un par de días atras.
 
Le dedico una rima a lo Belen Franchese (libre pensadora argentina)
Vamos Jose Mario tadavía
Ponte de una vez al día
 
jaja
 
Saludos

Mario Oviedo

unread,
May 25, 2013, 11:00:20 AM5/25/13
to publice...@googlegroups.com
es que leo todos los correos, no me pierdo ninguno, perdonenme
pero les creo interesantes, me apasina la programacion
bueno es mi unico pasion, quise poner joby, pero no se como se escribe

asi es que les pido perdon
algun dia ire al dia

en lugar de leer el periodico los leo a ustedes
ahh y oigo radio espn  en español
me apasiona el futbol

y si quieren oir musica en ingles
buena de los 80

Ricardo Pina

unread,
May 25, 2013, 11:08:30 AM5/25/13
to Grupo VFP
Hola Mario
 
La mayoria de los integrantes del foro debemos ser apasionados por el tema y algunos tenemos la suerte de vivir de esto que tanto nos gusta, aunque es un trabajo muy estresante creo que en el fondo lo hacemos porque nos gusta y sino tendriamos que trabajar, jajaj
 
Saludos
Reply all
Reply to author
Forward
0 new messages