There are several ways you can work directly with xBrowse .. the quickest way is to add FASTEDIT to your browse code..
Once you see that you can now edit cells, you will want to be able to leverage the bOnPreEdit and bOnPostEdit code blocks to add additional functionality to edit your cells.
Consider this code from an Invoicing program .. notice how you can make a very rich edit experience for any cell of your choice... This code is taken from the Invoice Detail.
REDEFINE xBROWSE oLBXB ;
RECORDSET oRsDetail ;
COLUMNS "QTY", ;
"INVENTORY ID", ;
"INVENTORY TYPE", ;
"ITEM DESCRIPTION", ;
"PRICE", ;
"LOCATION", ;
"COVERED BY WARRANTY" ;
COLSIZES 45,115,55,300,65,150,80,50 ; //120
HEADERS "Qty", ;
"Part Number", ;
"Type", ;
"Description", ;
"Price", ;
"Location", ;
"Warranty" ;
ID 172 of oWorkB ;
AUTOCOLS LINES CELL FASTEDIT
// row numbers
ADD oCol to oLbxB AT 1 DATA oLbxB:KeyNo() HEADER 'Ln' size 23 //PICTURE '9999'
oLbxB:aCols[1]:nDataStrAlign := AL_LEFT
oLbxB:aCols[1]:nHeadStrAlign := AL_LEFT
If cMode <> "V"
AEval( oLbxB:aCols, { |o| o:nEditType := EDIT_GET } )
// row number
oLbxB:aCols[1]:nEditType := EDIT_NONE
// qty
oLbxB:aCols[2]:bEditWhen := { || If(oRsDetail:fields("LockedDown"):Value = .f., .t.,.f.) }
oLbxB:aCols[2]:bOnPostEdit := {|o,v| If(_ChkSerial( v,oRsDetail,oLbxB),;
_InvtLook( v, oRsDetail, oRsRepair, "2", oLbxB, @lTaxable,oTaxable, cLoc,;
oLabor,oParts,oMisc,oTax,oTotal,nTaxNumber,nAssignedTo), ) }
// part number
oLbxB:aCols[3]:bEditWhen := { || If(oRsDetail:fields("LockedDown"):Value = .f., .t.,.f.) }
oLbxB:aCols[3]:bOnPreEdit := { || If(oRsDetail:Fields("Inventory Id"):Value = " ", , __Keyboard( Chr( VK_HOME ))) }
oLbxB:aCols[3]:bOnPostEdit := {|o,v| _InvtLook( v, oRsDetail, oRsRepair, "3", oLbxB, @lTaxable, oTaxable, cLoc,;
oLabor,oParts,oMisc,oTax,oTotal,nTaxNumber,nAssignedTo) }
// type
oLbxB:aCols[4]:nEditType := EDIT_LISTBOX
oLbxB:aCols[4]:aEditListTxt := aType
oLbxB:aCols[4]:bOnPostEdit := {|o,v| _GetPullDown( v,oLbxB,oRsDetail ) }
// description
oLbxB:aCols[5]:nEditType := EDIT_GET
oLbxB:aCols[5]:bOnPreEdit := { || If(oRsDetail:Fields("Item Description"):Value = " ", ,;
__Keyboard( Chr( VK_HOME )) )}
oLbxB:aCols[5]:bOnPostEdit := {|o,v| _GetText( v,oLbxB,oRsDetail ) }
// labor
ADD oCol to oLbxB AT 6 HEADER 'Labor' size 50 //60
oLbxB:aCols[ 6 ]:nEditType := EDIT_GET_BUTTON
oLbxB:aCols[ 6 ]:bEditBlock := {|row, col, oCol| ;
If(oRsDetail:Fields("Inventory Type"):Value = "Labor",;
( nAmount := _LabrBrow( ;
nRepairNumber,;
aEmp,;
aTech,;
oRsDetail,;
"","","","","","R","A",oRsDetail:Fields("Unique Line"):Value ),;
oRsDetail:Fields("Price"):Value := nAmount,;
oRsDetail:Update()), MsgInfo( "Type is not Labor")) } // repair
oLbxB:aCols[ 6 ]:addbmpfile( "clockview.bmp" )
oLbxB:aCols[ 6 ]:addbmpfile( "clockadd.bmp" )
oLbxB:aCols[ 6 ]:bBmpData := { | lValue | If( oRsDetail:Fields("IsLabor"):Value = .t., 1, 2 ) }
oLbxB:aCols[ 6 ]:lBtnTransparent := .t.
// Price
oLbxB:aCols[7]:nEditType := EDIT_GET
oLbxB:aCols[7]:bOnPostEdit := {|o,p| _GetPrice( p,oLbxB,oRsDetail,oRsRepair,lTaxable,oTaxable,;
oLabor,oParts,oMisc,oTax,oTotal,nTaxNumber) }
// extention
ADD oCol TO oLbxB AT 8 DATA {|x| x := _CalcExt( oRsDetail:Fields("Qty"):Value,;
oRsDetail:Fields("Price"):Value )} HEADER 'Ext' size 65
oLbxB:aCols[8]:nEditType := EDIT_NONE
oLbxB:aCols[8]:nDataStrAlign := AL_RIGHT
oLbxB:aCols[8]:nHeadStrAlign := AL_RIGHT
// serial number
ADD oCol to oLbxB AT 9 HEADER 'Serial Num' size 60
oLbxB:aCols[ 9 ]:nEditType := EDIT_GET_BUTTON
oLbxB:aCols[ 9 ]:bEditBlock := {|row, col, oCol| oLbxB:GoLeftMost(),_SerBrow(;
nRepairNumber,;
oRsDetail:Fields("Inventory Id"):Value,;
oRsDetail:Fields("Qty"):Value,;
oRsDetail:Fields("Unique Line"):Value,;
oRsDetail,;
"","","","","","R","A" ) } // repair
oLbxB:aCols[ 9 ]:addbmpfile( "zoom2.bmp" )
oLbxB:aCols[ 9 ]:addbmpfile( "adddbf.bmp" )
oLbxB:aCols[ 9 ]:bBmpData := { | lValue | If( oRsDetail:Fields("IsSerial"):Value = .t., 1, 2 ) }
oLbxB:aCols[ 9 ]:lBtnTransparent := .t.
// location
oLbxB:aCols[10]:nEditType := EDIT_NONE
// warranty
oLbxB:aCols[11]:nEditType := EDIT_GET
if ! empty(oCol := oLbxB:oCol( "WARRANTY" ))
oCol:SetCheck( { "ON", "OFF" } )
oCol:cSortOrder := nil
endif
* oLbxB:bClrStd := {|| {if(oRsDetail:fields("LockedDown"):Value = .t., CLR_BLUE, CLR_BLACK), CLR_WHITE } }
oLbxB:oCol( "Qty" ):bClrStd := {|| {if(oRsDetail:fields("LockedDown"):Value = .t., CLR_HBLUE, CLR_BLACK), CLR_WHITE } }
oLbxB:oCol( "Part Number" ):bClrStd := {|| {if(oRsDetail:fields("LockedDown"):Value = .t., CLR_HBLUE, CLR_BLACK), CLR_WHITE } }
oLbxB:oCol( "Type" ):bClrStd := {|| {if(oRsDetail:fields("LockedDown"):Value = .t., CLR_HBLUE, CLR_BLACK), CLR_WHITE } }
oLbxB:oCol( "Ext" ):bClrStd := {|| {if(oRsDetail:fields("LockedDown"):Value = .t., CLR_HBLUE, CLR_BLACK), CLR_WHITE } }
// add a new record
oLbxB:bPastEof = {|| _AddNewRow( oRsDetail,nRepairNumber,nAssignedTo,cLoc,oLbxB ) }
Endif