Nunca he utilizado un framework de tercero, quizá esto haya perjudicado mis tiempos de desarrollo, algo que no podré evaluar nunca (que hubiera pasado si).
Lo que sí puedo afirmar es que los sistemas que realizo los hago todos contra SQL SERVER definiendo CLASES que acceden a los datos y actualizan y borran sin necesidad de ningún framework. Pablo Oviedo, tu pregunta original era: "Hola, necesito hacer una aplicación vfox 9 + sqlserver. Pensé usar cursoradapter. No se como hacer un abm maestro-detalle usando cursor adapter, sí pude armar un abm para tablas simples usando cursorAdapter builder. Me puede dar algun ejemplo o algun link para ver? Como seria el manejo de transacciones con CA? saludos, muchas gracias." Seguís necesitando un ejemplo, algo podría pasarte. Saludos. -----Mensaje original----- De: [email protected] [mailto:[email protected]] En nombre de pablo.oviedo Enviado el: miércoles, 25 de julio de 2012 07:50 p.m. Para: GUFA List Member Asunto: [GUFA] CursorAdapter 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 <[email protected]> To: "GUFA List Member" <[email protected]> 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 >
