Excuse my English, use google translator, not sure if this is what you want ... this example is billing, Greetings ...
// EMPIEZA xBROWSE FACTURA...
REDEFINE xBrowse oBrw ID 100 of oDlg ;
COLUMNS 1, 2, 3, 4, 5, 6, 7 ;
ARRAY aItems FASTEDIT LINES
// CONFIGURACION DEL xBROWSE
WITH OBJECT oBrw
:nColDividerStyle := LINESTYLE_BLACK
:nStretchCol := STRETCHCOL_LAST
:bRClicked := { || msginfo( "pulsastes boton derecho..." ) }
:lColDividerComplete := .t.
:nHeaderHeight := 30 // ANCHO CABEZERA
:l2007 := .t.
:lFooter := .t.
:lRecordSelector := .f.
:lAllowColHiding := .f.
:lAllowColSwapping := .f.
:bClrStd := {|| IF( oBrw:nArrayAt % 2 == 0, {CLR_BLACK, CLR_WHITE}, {0, RGB(203, 226, 254)} ) }
:bKeyDown := {| nKey | teclado( nKey, oBrw, aVar, aGet, oDlg ) } // CONTROLA VIRTUAL KEY
END WITH
// COL.1 - CODIGO PRODUCTO
WITH OBJECT oBrw:aCols[1]
:cHeader := "CODIGO"
:nWidth := 100
:nDataStrAlign := AL_LEFT
:bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
aItems[oBrw:nArrayAt, 1] ) }
:cEditPicture := "@!"
:nEditType := EDIT_GET_BUTTON
:bEditBlock := {|| leecodigo( oQryInv, , {"inv_codiarti", "inv_nombrearti"} ,;
{"Código", "Nombre"}, oBrw, aItems, 1 ) }
:bEditValid := {| oGet | buscacodigo( oGet:value(), oBrw, aItems ,;
oQryInv, "inv_codiarti" ,;
{"inv_codiarti", "inv_nombrearti"} ,;
{"Código", "Nombre"}, 1 ) }
:bOnPostEdit := { | oCol, xVal, nKey | IF( nKey <> VK_ESCAPE .and. !EMPTY( xVal ) ,;
( oCol:value := xVal ,;
oBrw:SelectCol( 3 ) ), ) }
:bLClickHeader := { || alert("pulsaste boton izq.sobre cabecera col.") }
:cToolTip := "usando ToolTips..."
END WITH
// COL.2 - NOMBRE/DESCRIPCION
WITH OBJECT oBrw:aCols[2]
:cHeader := "DESCRIPCION"
:nWidth := 200
:nDataStrAlign := AL_LEFT
:bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
aItems[oBrw:nArrayAt, 2] ) }
:nEditType := EDIT_BUTTON // EDIT_GET // EDIT_GET_LISTBOX
END WITH
// COL.3 - UNIDAD
WITH OBJECT oBrw:aCols[3]
:cHeader := "U/G/O"
:nWidth := 70
:cEditPicture := "@!"
:nDataStrAlign := AL_CENTER
:bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
aItems[oBrw:nArrayAt, 3] ) }
:cFooter := "ITEMS =>"
:nFootStrAlign := AL_RIGHT
:nEditType := EDIT_GET
:bEditWhen := {|| IF( EMPTY( aItems[oBrw:nArrayAt, 1] ), .f., .t. ) }
:bOnPostEdit := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
( oCol:value:= xVal ), ) }
END WITH
// COL.4 - CANTIDAD
WITH OBJECT oBrw:aCols[4]
:cHeader := "CANTIDAD"
:nWidth := 70
:nDataStrAlign := AL_RIGHT
:bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
TRANSFORM( aItems[oBrw:nArrayAt, 4], "@E 9,999,999" ) ) }
:nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
:lTotal := .t. // PARA TOTALIZAR COL.
:nTotal := 0 // PARA TOTALIZAR COL.
:nFooterType := AGGR_SUM // PARA TOTALIZAR COL.
:nEditType := EDIT_GET
:bEditValid := { | oGet, oCol | mayorqcero( oGet:value() ) }
:bOnPostEdit := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
( oCol:value:= xVal ) , ) }
:bEditWhen := {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) }
END WITH
// COL.5 - PVP
WITH OBJECT oBrw:aCols[5]
:cHeader := "COSTO"
:nWidth := 70
:nDataStrAlign := AL_RIGHT
* :bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
* TRANSFORM( aItems[oBrw:nArrayAt, 5], "@E 9,999,999.99" ) ) }
:bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
aItems[oBrw:nArrayAt, 5] ) }
:cEditPicture := "@E 9,999,999.99"
:nFootStrAlign := AL_RIGHT
:nEditType := EDIT_GET
:bEditBlock := { || alert("Seleccionar Varios Precios...") }
:bEditValid := { | oGet, oCol | mayorqcero( oGet:value() ) }
:bOnPostEdit := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
( oCol:value := xVal ,;
totalinea( oBrw, aVar, aGet, aLote ) ), ) }
:bEditWhen := {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) }
END WITH
// COL.6 - % DESCUENTO
WITH OBJECT oBrw:aCols[6]
:cHeader := "DESC"
:nWidth := 70
:nDataStrAlign := AL_RIGHT
:bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
TRANSFORM( aItems[oBrw:nArrayAt, 6], "@E 999.99 %" ) ) }
:cFooter := "SUB-TOTAL=>"
:nEditType := EDIT_GET
:bEditValid := { | oGet, oCol | IF( menorqcero( oGet:value() ) ,;
menorqcien( oGet:value() ), .f. ) }
:bOnPostEdit := { | oCol, xVal, nKey | If( nKey <> VK_ESCAPE ,;
( oCol:value := xVal ,;
totalinea( oBrw, aVar, aGet, aLote ) ,;
addrow( oBrw ) ) , ) }
:bEditWhen := {|| !EMPTY( aItems[oBrw:nArrayAt, 1] ) .and. ;
aItems[oBrw:nArrayAt, 5] > 0 }
END WITH
// COL.7 - TOTAL LINEA
WITH OBJECT oBrw:aCols[7]
:cHeader := "SUB-TOTAL"
:nWidth := 70
:nDataStrAlign := AL_RIGHT
:bStrData := {|| IIF( LEN( aItems ) = 0, SPACE(10) ,;
TRANSFORM( aItems[oBrw:nArrayAt, 7], "@E 9,999,999.99" ) ) }
:nFootStrAlign := AL_RIGHT // ALINEA DATA FOOTER
:lTotal := .t. // PARA TOTALIZAR COL.
:nTotal := 0 // PARA TOTALIZAR COL.
:nFooterType := AGGR_SUM // PARA TOTALIZAR COL.
:cToolTip := "Columna 7"
END WITH
oBrw:MakeTotals()
oBrw:Refresh()
funcion addrow
STATIC PROCEDURE addrow( oBrw ) // ADICIONO REGISTRO
IF LEN( oBrw:aArrayData ) > 0
oBrw:GoBottom()
IF oBrw:aArrayData[ oBrw:nArrayAt, 7] > 0
AADD( oBrw:aArrayData ,;
{ , , "U", 0, 0, 0, 0 } )
ENDIF
ELSE
AADD( oBrw:aArrayData ,;
{ , , "U", 0, 0, 0, 0 } )
ENDIF
oBrw:SetPos( , 1, ) // MUEVE PUNTO A COL.1
oBrw:SetFocus(); oBrw:GoBottom(); oBrw:Refresh()
RETURN
funcion delrow
STATIC PROCEDURE delrow( oBrw, aVar, aGet ) // ELIMINO REGISTRO
IF LEN( oBrw:aArrayData ) == 0
MSGINFO( "No hay Registro(s) para Eliminar...", oDatos:cTitMsg )
RETURN
ENDIF
IF MSGNOYES( "Seguro Desea ELIMINAR el Registro: " + ;
ALLTRIM( cValToChar( oBrw:aArrayData[oBrw:nArrayAt, 1] ) ) + " ?", oDatos:cTitMsg )
IF oBrw:nLen > 0
ADEL( oBrw:aArrayData, oBrw:nArrayAt )
ASIZE( oBrw:aArrayData, oBrw:nLen - 1 )
ENDIF
ENDIF
oBrw:GOTOP()
oBrw:SetFocus()
oBrw:MakeTotals()
oBrw:Refresh()
netopagar( oBrw:aCols[7]:nTotal, aVar, aGet ) // CALCULA NETO PAGAR
RETURN
funcion totalinea
STATIC PROCEDURE totalinea( oBrw, aVar, aGet, aLote ) // TOTAL POR RENGLON CON Y SIN DESC.
*? aLote[1], aLote[2], aLote[3], aLote[4]
// TOTAL = CANTIDAD * PRECIO
oBrw:aArrayData[oBrw:nArrayAt, 7] := ;
( oBrw:aArrayData[oBrw:nArrayAt, 4] * oBrw:aArrayData[oBrw:nArrayAt, 5] )
// TOTAL = TOTAL - MTO.DESCUENTO
oBrw:aArrayData[oBrw:nArrayAt, 7] := ;
oBrw:aArrayData[oBrw:nArrayAt, 7] - ;
( oBrw:aArrayData[oBrw:nArrayAt, 7] * oBrw:aArrayData[oBrw:nArrayAt, 6] / 100 )
// AGREGO DATOS DEL LOTE AL FINAL DEL REGISTRO
IF LEN( oBrw:aArrayData[oBrw:nArrayAt] ) < 8 .and. aLote <> NIL//LEN( aLote ) > 0
AADD( oBrw:aArrayData[oBrw:nArrayAt], aLote[1] ) // cod.lote
AADD( oBrw:aArrayData[oBrw:nArrayAt], aLote[2] ) // fch.exp.
AADD( oBrw:aArrayData[oBrw:nArrayAt], aLote[3] ) // fch.ven.
AADD( oBrw:aArrayData[oBrw:nArrayAt], aLote[4] ) // pvp
ENDIF
oBrw:MakeTotals()
oBrw:Refresh()
netopagar( oBrw:aCols[7]:nTotal, aVar, aGet ) // CALCULA NETO PAGAR
RETURN
funcion netopagar
STATIC PROCEDURE netopagar( nSTotal, aVar, aGet ) // CALCULA NETO PAGAR
//
// aVar[3] -> % DESC.GENERAL
// aVar[13]-> % IVA
// aVar[14]-> MTO.DESC.SOBRE MTO.BRUTO
// aVar[15]-> MTO.EXENTO
// aVar[16]-> MTO.BRUTO-EXCENTO(sobre lo q se aplica IVA)
// aVar[17]-> MTO.BRUTO
// aVar[18]-> MTO.TOT.DESC.
// aVar[19]-> MTO.IVA
// aVar[20]-> MTO.NETO PAGAR
//
LOCAL nFor := 0
aVar[17] := nSTotal // MTO.SIN IVA NI DESCUENTO
aVar[18] := aVar[14] + ( aVar[17] * aVar[3] ) / 100 // MTO.DESCUENTO GENERAL
aVar[16] := aVar[17] - aVar[18] - aVar[15] // MTO.SOBRE EL CUAL SE APLICA IVA(bruto-desc.-exce.)
aVar[19] := ( ( ( aVar[17]-aVar[18] ) * aVar[13] ) / 100 ) // MTO.IVA SEGUN TASA ACTIVA
aVar[20] := ( aVar[17] - aVar[18] ) + aVar[19] // NETO A PAGAR
FOR nFor := 14 TO 20
aGet[nFor]:REFRESH()
NEXT
RETURN
Dios no está muerto...
Gracias a mi Dios ante todo!