Es una manera de hacer público mi agradecimiento por toda la ayuda que he recibido de este grandioso foro.
Agradeceré cualquier comentacio o mejora al código.
Espero que les sea de utilidad.
/*
Ejemplo de TXbrowse para edicion de comprobantes de diario.
Francisco Alegría P., Octubre 22/2008
1- Edicion automatica (lFastEdit = .t.)
2- Validacion de celdas (en este caso, cta y scta).
3- Salto sobre la celda cuando ésta no es editable (con tecla return)
Si la celda proxima no es editable, salta sobre ella a la siguiente.
4- Columnas de Debitos y Creditos:
Si debitos tiene valor, creditos no es editable y viceversa.
5- Cuando se edita la ultima columna, agrega nueva fila y se va a la primer columna.
6- Navegacion con las teclas direccionales, manteniendo el estado de edición.
7- Si se oprima flecha abajo en cualquier columna, y es la ultima fila del browse,
agrega un nuevo registro y se traslada a la primer columna en modo de edicion.
Si se oprime Escape, elimina el registro recien agregado, si este estaba vacio.
8- Para eliminar un registro con valor, se utiliza la tecla delete y presenta dialog para confirmar.
9- Edicion de cualquier columna editable sin necesidad de oprimir enter.
10 Totales y otros textos en footer
11- No admite salvar el registro si no validan .t., las funciones lCtaOK() y lDebHabOK()
Para accionar el salto sobre columna no editable, utilizar este codigo:
Introducirlo en la parte final del metodo function EditGetkeyDown( Self, nKey ),
o usarlo como parte del programa.
Local nNextCol
...
...
nNextCol := ::oBrw:nColSel + 1 // FranciscoA Sept/23/2008
if ::oBrw:aCols[nNextCol]:nEditType == 0 //Si prox col no es editable...
if nNextCol < Len(::oBrw:aCols) //Si no es la ult columna, salta a sig editable
::oBrw:nColSel := nNextCol + 1
::oBrw:Refresh()
endif
endif
*/
- Code: Select all Expand view RUN
- #include "FiveWin.ch"
#include "InKey.ch"
#include "xbrowse.ch"
//----------------------------
Function CDiario()
local oWnd, oBrw, oCol, cAlias
local n:=0
local nTotal1:=0, nTotal2:=0
DbUseArea(.T.,,"Datos","Datos",.F.)
cAlias:=Alias()
dbSelectArea(cAlias)
DEFINE WINDOW oWnd TITLE "EDITAR COMPROBANTE DE DIARIO" ;
FROM 0,0 TO 600,900 PIXEL ;
COLOR nRGB(247, 243, 232), nRGB(228, 213, 184)
oBrw := TXBrowse():New( oWnd )
oBrw:cAlias := cAlias
oBrw:nColDividerStyle := LINESTYLE_INSET
oBrw:nRowDividerStyle := LINESTYLE_INSET
oBrw:lColDividerComplete := .t. //completa pintado sobre el footer cuando lineas no llenan todo el browse
oBrw:nHeaderHeight := 30 //Altura cabeceras de col
oBrw:lFooter := .t. //Que tendrá footer
oBrw:nFooterLines := 1 //Lineas del footer
oBrw:nFooterHeight := 24 //Altura del Footer
oBrw:lRecordSelector := .t. //poner o no, COL de la flechita de la izq
oBrw:bClrHeader := {|| { nRGB(140, 0, 0), nRGB(229,0,0) } } // VERDECITO
oBrw:bClrFooter := oBrw:bClrHeader
oBrw:bClrStd := {|| { nRGB( 0, 0, 0), nRGB(255,248,220) } } // colores para lineas normales
oBrw:bClrSel := {|| { nRGB(255,255,255), nRGB(241,222,088) } } // para barra de linea selecc cuando el control no tiene el foco
oBrw:bClrSelFocus := {|| { nRGB( 0, 0, 0), nRGB(248,195, 34) } } // para barra de linea selecc cuando el control tiene el foco
oBrw:nMarqueeStyle := MARQSTYLE_HIGHLCELL //solo ilumina la celda actual
oBrw:nRowHeight := 20 //altura entre lineas
oBrw:lFastEdit := .t.
oBrw:bPastEof = {|| if( lCtaOK(oBrw) .and. lDebHabOK((cAlias)->debe+(cAlias)->haber) ,;
(Dbappend(), oBrw:GoLeftMost(), oBrw:Refresh(), oBrw:aCols[ 1 ]:Edit() ),) } //agrega registro y "oprime" enter
//Aqui uso DbPack() porque es una dbf pequeña y temporal. En grandes usar function de mantenimiento.
oCol = oBrw:AddCol()
oCol:bStrData = { || (cAlias)->cta }
oCol:cHeader = "CTA"
oCol:nEditType = EDIT_GET
oCol:bOnPostEdit = { | oCol, xVal, nKey | If( RecCount() == 0, ( DbAppend(), oBrw:Refresh() ),) ,;
If( nKey == VK_RETURN, (cAlias)->Cta := xVal, ) ,;
If( nKey == VK_ESCAPE .and. Empty((cAlias)->Cta), ( (cAlias)->(dbDelete()),(cAlias)->(__dbPack()),(cAlias)->(dbGoBottom()),oBrw:Refresh() ), ) }
oCol = oBrw:AddCol()
oCol:bStrData = { || (cAlias)->Scta }
oCol:cHeader = "SC4"
oCol:nEditType = EDIT_GET
oCol:bOnPostEdit = { | oCol, xVal, nKey | If( RecCount() == 0, ( DbAppend(), oBrw:Refresh() ),) ,;
If( nKey == VK_RETURN, if(lCtaOK(oBrw),(cAlias)->Scta := xVal, oBrw:GoLeftMost()),) }
oCol = oBrw:AddCol()
oCol:bStrData = { || (cAlias)->NOMBRE }
oCol:cHeader = "DESCRIPCION DE LA CUENTA"
oCol:cFooter = "BALANCE ---> "
oCol:nFootStrAlign := 1
oCol:nEditType = 0 //no editable
oCol = oBrw:AddCol()
oCol:bStrData = { || Transform((cAlias)->DEBE,"9,999,999,999.99") }
oCol:nDataStrAlign := 1 //alineado a la derecha
oCol:cHeader = "DEBITOS"
oCol:nEditType = EDIT_GET
oCol:lTotal := .t. //para totalizar cols a report y/o excel
oCol:bFooter = {|| TRANSFORM(nTotal1,"9,999,999,999.99") }
oCol:nFootStrAlign := 1
oCol:bEditWhen := {|| (cAlias)->Haber =0 }
oCol:bOnPostEdit = { | oCol, xVal, nKey | If( RecCount() == 0, ( DbAppend(), oBrw:Refresh() ),),;
If( nKey == VK_RETURN,;
if(lCtaOK(oBrw),( nTotal1+=(Val(xVal)-(cAlias)->DEBE), oCol:RefreshFooter(), (cAlias)->DEBE := Val(xVal) ), oBrw:GoLeftMost()) ,) }
oCol = oBrw:AddCol()
oCol:bStrData = { || Transform((cAlias)->HABER,"9,999,999,999.99") }
oCol:nDataStrAlign := 1
oCol:cHeader = "CREDITOS"
oCol:nEditType = EDIT_GET
oCol:lTotal := .t. //para totalizar cols a report y/o excel
oCol:bFooter = {|| TRANSFORM(nTotal2,"9,999,999,999.99") }
oCol:nFootStrAlign := 1
oCol:bEditWhen := {|| (cAlias)->Debe =0 }
oCol:bOnPostEdit = { | oCol, xVal, nKey | If( RecCount() == 0, ( DbAppend(), oBrw:Refresh() ),),;
If( nKey == VK_RETURN,;
if(lCtaOK(oBrw), ( nTotal2+=(Val(xVal)-(cAlias)->HABER), oCol:RefreshFooter(), (cAlias)->HABER := Val(xVal) ), oBrw:GoLeftMost()) ,) }
oCol = oBrw:AddCol()
oCol:bStrData = { || (cAlias)->CONCEPTO }
oCol:cHeader = "CONCEPTO"
oCol:nEditType = EDIT_GET
//Es la ultima columna, agrega nuevo registro en blanco y se va a primer columna,
//solo si la cta y/o valores están OK
oCol:bOnPostEdit = { | oCol, xVal, nKey | If( RecCount() == 0, DbAppend(),),;
If( nKey == VK_RETURN, (cAlias)->CONCEPTO := xVal ,) ,;
if( !lCtaOK(oBrw),(oBrw:GoLeftMost(), oBrw:Refresh()),;
if ( (cAlias)->(Recno())==(cAlias)->(Reccount()) .and. lDebHabOK((cAlias)->debe+(cAlias)->haber), (DbAppend(), oBrw:GoLeftMost(), oBrw:Refresh()),) ) }
oBrw:SetRDD()
oBrw:CreateFromCode()
oBrw:bKeyDown :={ | nKey | Teclas(nKey, oBrw, cAlias) }
oWnd:oClient := oBrw
ACTIVATE WINDOW oWnd ;
ON INIT oBrw:SetFocus()
RETURN NIL
//--------------------
Function Teclas(nKey, oBrw, cAlias)
Do Case
Case nKey == VK_DELETE
if MsgNoYes("¿Está seguro(a) de borrar este registro?","Borrar registro de "+cAlias)
(cAlias)->(dbDelete())
(cAlias)->(dbPack())
oBrw:GoBottom()
oBrw:Refresh()
endif
EndCase
Return nil
//----------------//
Function lCtaOK(oBrw)
//tu codigo de validacion
(oBrw:cAlias)->nombre := "Nombre de la Cuenta, si existe..."
oBrw:Refresh()
Return .t.
//----------------------------//No permitir registro sin valores
Function lDebHabOK(nValor)
if nValor = 0
MsgStop("Omision de Valores","Alto")
return .f.
endif
Return .t.
//ESTAS FUNCIONES SON PARA COLORES PERSONALIZADOS DEL XBROWSE YA PUBLICADAS
//No son necesarias a menos que quieras emplear las classes modificadas.
//-------------------COLOR BUTTONBAR
Function ClrMsgBar()
Return {nRGB(255,228,150),nRGB(167,128,0)}
//-------------------COLOR HEARDERS DEL TXBROWSE
Function ClrHeader()
Return { nRGB(255,248,220), nRGB(157, 138,0) } //VERDECITO
//-------------------COLOR FOOTER DEL TXBROWSE
Function ClrFooter()
Return { nRGB(255,248,220), nRGB(157, 138,0) } //VERDECITO
Lo probé antes de subirlo y me funciona bien.
Saludos
Francisco J. Alegría P[/img][/url]