Page 1 of 1

René u otro usuario :ver solución al final

Posted: Thu Aug 30, 2007 10:16 pm
by metaldrummer
A ver:
Tengo el siguiente código:

Code: Select all

            temporal->(dbGotop())
            //aDatos:=AddRegistro( "DET_NOTA_VENTA")
            DO WHILE !temporal->(Eof())
               aDatos:=AddRegistro( "DET_NOTA_VENTA")
               IF aDatos[1]
                  aDatos[3]:AddNew()
                  aDatos[3]:Fields( "idnotadeventa"):value:=nIdNotadeVenta
                  aDatos[3]:Fields( "idproducto"):value:=temporal->idproducto
                  aDatos[3]:Fields( "pventa"):value:=temporal->pventa
                  aDatos[3]:Fields( "cantidad"):value:=temporal->cantidad
                  aDatos[3]:Fields( "total"):value:=temporal->total
                  TRY
                     aDatos[3]:Update()
                  CATCH oError
                     MsgStop( oError:Description, "Error")
                  END
                  TRY
                     aDatos[3]:Close()
                  CATCH oError
                     lError:=.T.
                     MsgStop( "Se ha producido un error al agregar el Detalle", "ERROR:Linea 992")
                  END
                  aDatos[2]:Close()
               ELSE
                  aDatos[2]:Close()
                  MsgStop( "Se ha producido un error al agregar el Detalle", "ERROR:Linea 997")
                  lError:=.T.
               ENDIF
               IF lError
                  EXIT
               ENDIF
               temporal->(dbSkip())
            ENDDO
            /*aDatos[3]:Update()
            TRY
               aDatos[3]:Close()
            CATCH oError
               lError:=.T.
               MsgStop( "Se ha producido un error al agregar el Detalle", "ERROR:Linea 1022")
            END
            aDatos[2]:Close()*/
Éste es el código de la función AddRegistro(cTabla):

Code: Select all

FUNCTION AddRegistro( cTabla)
   LOCAL lOK:=.T., aResultados:=Array(3)
   LOCAL oCon, oError, oDatos

   TRY
      oCon:=toleauto():new("adodb.connection")
   CATCH oError
      MsgStop( "Línea 125: Error al crear la conexión" + CRLF + ;
               "Sql()", "rutinasdeconexion.prg")
      lOK:=.F.
   END
   IF lOk
      oCon:ConnectionString:="Provider=OraOLEDB.Oracle;Data Source=192.168.0.150:1521/xe;User ID=usuario;Password=password;"
      oCon:ConnectionTimeout:=3600
      TRY
         oCon:Open()
      CATCH oError
         lOK:=.F.
      END
      IF lOk
         TRY
            oDatos:=TOleAuto():New("adodb.recordset")
         CATCH oError
            lOK:=.F.
            oDatos:=NIL
         END
         IF lOk
            oDatos:CursorLocation  := adUseClient //adUseServer
            //oDatos:CursorLocation  := adUseServer
            oDatos:LockType := adLockOptimistic
            oDatos:CursorType := adOpenKeyset
            oDatos:Source := cTabla
            oDatos:ActiveConnection(oCon)
            TRY
               oDatos:Open()
            CATCH oError
               lOK:=.F.
            END
         ENDIF
      ENDIF
   ENDIF
   aResultados[1]:=lOk
   aResultados[2]:=oCon
   aResultados[3]:=oDatos
RETURN aResultados
Mi Problema:
1.- Cuando agrego un único registro el proceso funciona espectacular!!.
2.- Si este mismo proceso lo realiza para más de un registro que tenga en una .DBF se cae y solamente me guarda en el servidor el primer registro. O sea, cuando utilizo el :addnew() más de una vez, el :update() falla.
3.- Intenté colocando la llamada a la función fuera del do while y solamente utilizando el addnew() y el update() dentro del do while y falló.
4.- Intenté lo mismo que en el punto 3, pero colocando el update() después del do while e igual se cae.

Intenté jugando con los valores de oDatos:CursorLocation y nada.

Agradeceré si me pueden ayudar. Debo estar pasando algo por alto.

Saludos y gracias
David Lagos S.
Coquimbo-Chile

Posted: Fri Aug 31, 2007 2:37 am
by R.F.
Lo que no entiendo es porque cierras el RecordSet ?????

Por eso solo puedes meter un solo registro, si depues del hacer el ::AddNew(), hacer la asignación de variables, y luego ::Update(), estoy viendo que haces un ::Close(), si cierras el record set YA NO EXISTE, luego entonces no puedes agregar nada mas a el.

Solucion, NO CIERRES EL RECORDSET hasta después del ENDDO.

Posted: Fri Aug 31, 2007 3:28 am
by metaldrummer
RF wrote:Lo que no entiendo es porque cierras el RecordSet ?????

Por eso solo puedes meter un solo registro, si depues del hacer el ::AddNew(), hacer la asignación de variables, y luego ::Update(), estoy viendo que haces un ::Close(), si cierras el record set YA NO EXISTE, luego entonces no puedes agregar nada mas a el.

Solucion, NO CIERRES EL RECORDSET hasta después del ENDDO.
Gracias René por tu ayuda.

Éste es el browse antes del error:
Image

y esta es la imagen del error con el browse de fondo.
Image

Esta es la imagen del error.log:
Image

Hice lo que me indicas y no resultó. Así dejé el código:

Code: Select all

temporal->(dbGotop())
aDatos:=AddRegistro( "DET_NOTA_VENTA")
DO WHILE !temporal->(Eof())
   aDatos[3]:AddNew()
   aDatos[3]:Fields( "idnotadeventa"):value:=nIdNotadeVenta
   aDatos[3]:Fields( "idproducto"):value:=temporal->idproducto
   aDatos[3]:Fields( "pventa"):value:=temporal->pventa
   aDatos[3]:Fields( "cantidad"):value:=temporal->cantidad
   aDatos[3]:Fields( "total"):value:=temporal->total
   aDatos[3]:Update()
   temporal->(dbSkip())
ENDDO
aDatos[3]:Close()
aDatos[2]:Close()
En la parte del Fields(cNombrecampo):value:=valor intenté con Fields(0):value:=valor y tampoco resultó.

Si te fijas tengo lo siguiente antes del do while:

Code: Select all

aDatos:=AddRegistro( "DET_NOTA_VENTA")
Esa función (código completo en el post anterior) crea el objeto conexión y el objeto recordset de ado y me deja en condiciones de utilizar el :addnew() y el :update().
El objeto conexión regresa a mí en aDatos[2] y el objeto recordset regresa en aDatos[3]. aDatos[1] solamente tiene un valor lógico que me indica si tuvo éxito la función en abrir el objeto conexión y el objeto recordset. Y luego del ENDDO sencillamente cierro la conexión al recordset (aDatos[3]) y al objeto conexión de ado (aDatos[2]).

O sea; haciendo lo que tú me indicas que es abriendo el recordset antes del DO WHILE y cerrándolo después del ENDDO tampoco funciona.

¿Puedes poner atención al código que está más abajo (FUNCTION AddRegistro( cTabla) del post anterior, e indicarme si todo está bién?, en especial esta parte:

Code: Select all

oDatos:CursorLocation  := adUseClient //adUseServer
//oDatos:CursorLocation  := adUseServer
oDatos:LockType := adLockOptimistic
oDatos:CursorType := adOpenKeyset
oDatos:Source := cTabla
oDatos:ActiveConnection(oCon)
TRY
   oDatos:Open()
CATCH oError
   lOK:=.F.
END
Infinitas gracias René
David

Posted: Fri Aug 31, 2007 2:32 pm
by metaldrummer
Podría ser un tema puntual con oracle? y eso que utilizo el proveedor oledb de oracle.
David

Posted: Fri Aug 31, 2007 8:26 pm
by metaldrummer
La solución fue muy simple:
Esta tabla que me daba el error es del detalle de las notas de ventas y el administrador no hayó nada mejor que asignar al idnotadeventa como llave primaria. Y todos sabemos que una llave primaria no se puede repetir. El administrador no tomó en cuenta el modelo de datos que le entregué.
Ahora me río. Anoche estuve hasta como las 4 am reventándome la cabeza.
Bueno espero que igual esto le sirva a alguien.
Saludos