Gracias, empece con cursoradapter y me trabe. Se pueden usar un 
cursoadapter que incluya columnas de distintas tablas? me tira error 
cuando quiero refrescar algunos campos del cursor luego de una inserción.

También estoy viendo TierAdapter. Los link que me pasaron, es posible que 
esta información este en español?

Existe alguna documentación sobre TierAdapter que describa todas las 
clases, metodos y propiedades del frameworks a parte del diagrama de UML 
que esta en el sitio de Martin?

saludos


-----Original Message-----
From: Rafael Copquin <rcopq...@fibertel.com.ar>
To: "GUFA List Member"  <GUFA@mug.org.ar>
Date: Tue, 24 Jul 2012 16:32:07 -0300
Subject: [GUFA] CursorAdapter

> Te paso un ejemplo bien completo de cómo lo hago yo:
> 
> ** creacion de las tablas en sqlserver
> ** en la vida real tienen más campos, pero estos son los mínimos que 
> deberían tener
> 
> CREATE TABLE [dbo].[DETALLE](
>      [FECHA] [date] NOT NULL,
>      [TIPODOC] [char](3) NOT NULL,
>      [DOCNUM] [char](8) NOT NULL,
>      [CODIGO] [char](30) NOT NULL,
>      [CANTIDAD] [int] NOT NULL,
>      [PRECIO] [numeric](10, 4) NOT NULL,
>      [DT] [datetime] NOT NULL,
>      [IDETALLE] [int] IDENTITY(1,1) NOT NULL,
>      [IDCABECERA] [int] NOT NULL,
>   CONSTRAINT [PK_DETALLE] PRIMARY KEY CLUSTERED
> (
>      [IDDETALLE] ASC
> )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
> = 
> OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],
>   CONSTRAINT [CN_IDDETALLE] UNIQUE NONCLUSTERED
> (
>      [IDDETALLE] ASC
> )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
> = 
> OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
> ) ON [PRIMARY]
> 
> CREATE TABLE [dbo].[CABECERA](
>      [FECHA] [date] NOT NULL,
>      [CUENTA] [char](4) NOT NULL,
>      [TIPODOC] [char](3) NOT NULL,
>      [DOCNUM] [char](8) NOT NULL,
>      [IVA] [numeric](10, 2) NOT NULL,
>      [TOTAL] [numeric](10, 2) NOT NULL,
>      [IDCABECERA] [int] IDENTITY(1,1) NOT NULL,
>      [DT] [datetime] NOT NULL,
>   CONSTRAINT [PK_IDCABECERA] PRIMARY KEY CLUSTERED
> (
>      [IDCABECERA] ASC
> )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
> = 
> OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
> ) ON [PRIMARY]
> 
> 
> ** lo siguiente se hace en Visual FoxPro
> 
> ** generación de un cursor adapter para la tabla CABECERA
> 
> Local cCmd,cSch,cUFL,cUNL,lOK
> 
> Text to cCmd noshow pretext 15
> SELECT
>      FECHA ,
>      CUENTA ,
>      TIPODOC ,
>      DOCNUM ,
>      IVA ,
>      TOTAL ,
>      IDCABECERA ,
>      DT
>   FROM CABECERA WHERE 1=0
> EndText
> 
> Text to cSch noshow pretext 15
>      FECHA D,
>      CUENTA C(4),
>      TIPODOC C(3),
>      DOCNUM C(8),
>      IVA N(10,2),
>      TOTAL N(10,2),
>      IDCABECERA I,
>      DT T
> EndText
> 
> 
> Text to cUFL noshow pretext 15
>      FECHA ,
>      CUENTA ,
>      TIPODOC ,
>      DOCNUM ,
>      IVA ,
>      TOTAL ,
>      IDCABECERA ,
>      DT
> EndText
> 
> Text to cUNL noshow pretext 15
>      FECHA        CABECERA.FECHA,
>      CUENTA       CABECERA.CUENTA,
>      TIPODOC      CABECERA.TIPODOC,
>      DOCNUM       CABECERA.DOCNUM,
>      IVA          CABECERA.IVA,
>      TOTAL        CABECERA.TOTAL,
>      IDCABECERA   CABECERA.IDCABECERA,
>      DT           CABECERA.DT
> EndText
> 
> cUFL        = Chrtran( cUFL, Chr(13) + Chr(10), " " )
> cUNL       = Chrtran( cUNL, Chr(13) + Chr(10), " " )
> cSch        = Chrtran( cSch, Chr(13) + Chr(10), " " )
> cCmd      = Chrtran( cCmd, Chr(13) + Chr(10), " " )
> 
> Use in Select("")
> 
> lOK = .t.
> 
> If !PemStatus(thisform,'oCA',5)
>     thisform.AddProperty('oCA')
> EndIf
> 
> Try
> 
>      Thisform.oCA = Createobject("CursorAdapter")
> 
>      lOK = .t.
> 
> Catch to oErrores
> 
>      MessageBox("No se pudo generar el objeto CursorAdapter"+;
>      Chr(13)+oErrores.message,16,"Atención",2000)
> 
>      lOK = .f.
> 
> Finally
> EndTry
> 
> 
> If lOK = .t.
>     try
>         With thisform.oCA
>              .DataSourceType     = "ODBC"
>              .DataSource         = thisform.nHandle
>              .alias                 = "curCabecera"
>              .tables             = "cabecera"
>              .BufferModeOverride = 5
>              .keyfieldlist        = "idcabecera"
>              .sendupdates         = .T.
>              .usetransactions    = .f.   && si están en falso, no usa 
> transacciones y funciona entonces ponerlas en manual en SQL Server
>              .selectcmd             = cCmd
>              .updatablefieldlist = cUFL
>              .updatenamelist     = cUNL
>              .cursorschema       = cSch
>              .cursorfill()
>         EndWith
> 
>         Select curCabecera
> 
>     Catch to oErrores
> 
>          MessageBox("No se pudo generar el Cursor 
> "+Chr(13)+oErrores.message;
>          ,16,"Atención",2000)
> 
>          lOK = .f.
> 
>     endtry
> endif
> 
> Return lOK
> 
> **(hacer otro cursor adapter para la tabla DETALLE y obtener el cursor 
> curDetalle)
> 
> ** la sentencia where 1=0 genera un cursor vacío. Esto es para que 
> llenes el cursor adapter con los datos necesarios antes de
> ** grabar. Estos datos salen de textboxes, grillas, cálculos, etc.
> 
> ** rutina de grabación
> 
> Local lOK,nPK,cCmd,nResults,lBatchMode
> 
> SQLExec(thisform.nHandle,'BEGIN TRANSACTION')
> SQLSetProp(thisform.nHandle, "TRANSACTIONS", 2 )   && pone las 
> transacciones en manuales
> 
> Select curCabecera
> Scatter name oCab blank fields except idcabecera
> With oCab
>      .fecha    = Date()
>      .cuenta   = '1234'
>      .tipodoc  = 'FRA'
>      .docnum   = '12345678'
>      .iva      = 210.00
>      .total    = 1210.00
>      .dt       = Datetime()
> EndWith
> 
> ** grabación de la cabecera y obtención de la clave primaria generada
> ** el campo idcabecera es autoincremental
> 
> Insert into curCabecera from name oCab
> 
> lOK = TableUpdate(.t.,.t.,'curCabecera')
> 
> If lOK = .t.
> 
>      nPK      = 0
>      nResults = 0
>      cCmd     = [select @@IDENTITY as pk ]
> 
>      lBatchMode = SQLGetProp(thisform.nHandle,"BatchMode" )
> 
>      SQLSetProp(thisform.nHandle,"BatchMode" ,.f.)
> 
>      SQLExec(thisform.nHandle,cCmd,'curPK')
> 
>      Do while nResults <> 2
>         nResults = SQLMoreResults(thisform.nHandle)
>      enddo
> 
>      SQLSetProp(thisform.nHandle,"BatchMode" ,lBatchMode)
> 
>      nPK = curPK.pk
>      Use in Select('curPK')
> 
>      Select curFactura      && cursor auxiliar usado en el form para 
> insertar las lineas de detalle de la factura
>                                          && tiene la misma estructura 
> que la tabla detalle del sql server
> 
>      Scan all
>           Scatter name oDet fields except iddetalle
>           With oDet
>                .fecha      = Date()
>                .tipodoc    = 'FRA'
>                .docnum     = '12345678'
>                .idcabecera = nPK       && aqui pasa a ser la clave
> foránea
>                .dt         = Datetime()
>           *** los campos codigo, cantidad y precio ya están en el 
> objeto, obtenidos con SCATTER NAME
>           endwith
>           Insert into curDetalle from name oDet
>      EndScan
>      lOK = TableUpdate(.t.,.t.,'curDetalle')
> 
> endif
> 
> If lOK = .t.
> 
>     SQLCommit(thisform.nHandle)
> 
> Else
> 
>     SQLRollback(thisform.nHandle)
> 
> endif
> 
> SQLSetProp(thisform.nHandle,'Transactions',1 )     && transacciones 
> automáticas
> 
> A los cursor adapters les ponés la propiedad usetransactions en falso,
> para que no maneje las transacciones directamente. Acordate que en SQL 
> Server, las transacciones son automáticas a menos que las pongas en 
> manual. Esto hace que cada vez que insertás,borrás o modificás un 
> registro, se abra y cierre una transacción automáticamente. No te
> sirve 
> para el caso de una factura, porque si te da error alguna de las
> tablas, 
> no podés cancelar una transacción completa. En cambio, si las 
> transacciones las ponés en manual, solamente se completa la
> transacción 
> cuando le mandás un SQLCommit (o SQLRollback si falla)
> Tenés que poner las transacciones del SQLServer en manual antes de 
> comenzar a grabar y luego de cerrar la transacción las ponés
> nuevamente 
> en automáticas,para que el SQL Server siga funcionando normalmente
> 
> Fijate en estos artículos
> 
> http://www.universalthread.com/ViewPageArticle.aspx?ID=667
> 
> http://www.universalthread.com/ViewPageArticle.aspx?ID=817
> 
> Rafael Copquin
> 


Responder a