Adriano, este ejemplo que encontré por ahí, te puede ayudar. Es totalmente funcional.
Code: Select all
/------------------------------------------------------------------//
// EJEMPLO XBROWSE PARA FACTURA
//------------------------------------------------------------------//
#include "FiveWin.Ch"
#include "xbrowse.ch"
function Main()
local oDlg, oFont, oBrw, nPos, bPos, nIVA := 10.00, nMaxItems := 5
local aInvoice := { { 0, 0, 0 } }
local aBlank := { 0, 0, 0 }
local aTable := { {1, "Product Code 1 ", 10},;
{2, "Product Code 2 ", 20},;
{3, "Product Code 3 ", 30},;
{4, "Product Code 4 ", 40},;
{5, "Product Code 5 ", 50},;
{6, "Product Code 6 ", 60},;
{900, "Product Code 900 ",9000},;
{7, "Product Code 7 ", 70},;
{8, "Product Code 8 ", 80},;
{10, "Product Code 10 ", 100} }
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
DEFINE DIALOG oDlg SIZE 800,450 PIXEL TITLE "INVOICE" FONT oFont //600,400
@ 10,10 XBROWSE oBrw SIZE -10,-10 PIXEL OF oDlg ;
DATASOURCE aInvoice ;
COLUMNS 1, 1, 2, 3 ;
HEADERS "CODE", "ITEM", "QUANTITY", "PRICE" ;
PICTURES "9999", nil, "999,999.99", "9,999,999.99" ;
COLSIZES nil, 120 ;
CELL LINES FOOTERS NOBORDER FASTEDIT
bPos := {|| nPos := Ascan( aTable, {|a| a[1] == oBrw:Code:Value} ) } //Posicion del codigo en la tabla de productos
oBrw:Item:bEditValue := { || If( oBrw:Code:Value > 0, (Eval(bPos), if(nPos>0, aTable[ nPos, 2 ], "" )),"") }
oBrw:AMOUNT := { || oBrw:Quantity:Value * oBrw:Price:Value }
oBrw:Amount:cEditPicture := "999,999,999.99"
oBrw:IVA := { || ( oBrw:AMOUNT:Value * nIVA ) / 100 }
oBrw:Iva:cEditPicture := "999,999,999.99"
oBrw:TOTAL := { || oBrw:AMOUNT:Value + oBrw:IVA:Value }
oBrw:Total:cEditPicture := "999,999,999.99"
oBrw:nEditTypes := { EDIT_GET, EDIT_NONE, EDIT_GET, EDIT_GET, EDIT_NONE, EDIT_NONE, EDIT_NONE }
WITH OBJECT oBrw:Code
:bEditValid := { |oGet| oGet:VarGet() > 0 }
:bOnChange := { |oCol| Eval(bPos), if(nPos>0, oBrw:aRow[ 3 ] := aTable[ nPos, 3 ], 0) }
:bFooter := { || Ltrim( Str( oBrw:KeyNo() ) ) + " / " + LTrim( Str( oBrw:KeyCount() ) ) }
END
WITH OBJECT oBrw:Quantity
:bEditWhen := { || ! Empty( oBrw:Code:Value ) }
:bOnChange := { || oBrw:MakeTotals(), oBrw:RefreshFooters() } //oBrw:MakeTotals( oBrw:oCol( "Amount" ) ), oBrw:RefreshFooters() }
:bEditValid := { |oGet| oGet:VarGet() > 0 }
:nFooterType := AGGR_SUM
END
WITH OBJECT oBrw:Price // oBrw:aRow[ 3 ]
:bEditWhen := { || ! Empty( oBrw:Code:Value ) .and. ! Empty( oBrw:Quantity:Value ) }
:bOnChange := { || oBrw:MakeTotals(), oBrw:RefreshFooters() } //oBrw:MakeTotals( oBrw:oCol( "Amount" ) ), oBrw:RefreshFooters() }
:bEditValid := { |oGet| oGet:VarGet() > 0 }
END
oBrw:Amount:nFooterType := AGGR_SUM
oBrw:Iva:nFooterType := AGGR_SUM
oBrw:Total:nFooterType := AGGR_SUM
WITH OBJECT oBrw
:nStretchCol := STRETCHCOL_WIDEST
:bPastEof := { || If( len(oBrw:aArrayData) = nMaxItems, (MsgStop("Agotado maximo de lineas: "+Str(nMaxItems,3),"Alto"), oBrw:GoUp()) ,) ,;
If( Empty( oBrw:Amount:Value ), nil, ;
( AAdd( oBrw:aArrayData, AClone( aBlank ) ), ;
oBrw:GoDown(), oBrw:GoLeftMost(), oBrw:Refresh() ) ) }
:bChange := { || If( oBrw:nArrayAt < Len( oBrw:aArrayData ) .and. ;
ATail( oBrw:aArrayData )[ 2 ] == 0, ;
( ASize( oBrw:aArrayData, Len( oBrw:aArrayData ) - 1 ), ;
oBrw:Refresh() ), ;
nil ) , oBrw:RefreshFooters() }
:bKeyDown := {|nKey| Teclas(nKey,oBrw,aInvoice) }
:nHeadStrAligns := AL_CENTER
:CreateFromCode()
END
ACTIVATE DIALOG oDlg CENTERED ;
ON INIT ( oBrw:SetFocus(), .f. )
RELEASE FONT oFont
if ATail( aInvoice )[ 2 ] == 0
ASize( aInvoice, Len( aInvoice ) - 1 )
endif
xbrowser aInvoice title "Edited Invoice" setup ( oBrw:cHeaders := { "Code", "Qty", "Price" } )
return nil
//------------------------------------------------------------------//
Function Teclas(nKey,oBrw,aInvoice)
if nKey == VK_DELETE
if MsgNoYes("Esta seguro de borrar este registro?")
ADel(aInvoice, oBrw:nArrayAt, .t.)
oBrw:MakeTotals()
oBrw:Refresh()
endif
endif
Return nil
Saludos.