estoy intentando hacer un buffer de registro que me permita acceder al mismo con la notación dbf:campo. Una alternativa al clásico scatter/gather pero que pueda usar los nombres de campo para acceder. Me da igual una clase que funciones.
El primer ejemplo que he encontrado es de Maurizio, en este foro - viewtopic.php?f=3&t=14019&start=0&hilit=tdatabase
Pero el siguiente ejemplo no funciona con Harbour:
- Code: Select all Expand view RUN
Function MAin()
Local aVArs
USE "CUSTOMER.dbf"
aVars := LoadDbf()
? aVars:FIRST// := "ABCD"
? aVars:LAST
SaveDbf(aVars)
dbcloseall()
Return nil
Function LoadDbf() // Scatter()
Local aVars := {=>}
LOcal nField := FCount()
LOcal nX := 1
FOR nX := 1 TO nField
aVars[FIELDNAME(nX)] := FieldGet(nX)
NEXT
Return aVars
//--------------------------------------------------------------------------
Function SaveDbf(aVArs) //Gather(aVars)
lOCAL Nx := 1
FOR Nx := 1 TO LEN(aVars)
FieldPut(nX,aVArs[FIELDNAME(nX)] )
NEXT
Return TRUE
//--------------------------------------------------------------------------
Function Blank(aVars)
local i,nX
i := len(aVars)
for nX :=1 to i
do case
case valtype(aVars[FIELDNAME(nX)]) == "C" ; aVars[FIELDNAME(nX)] := space(len(aVars[FIELDNAME(nX)]))
case valtype(aVars[FIELDNAME(nX)]) == "N" ; aVars[FIELDNAME(nX)] := 0
case valtype(aVars[FIELDNAME(nX)]) == "D" ; aVars[FIELDNAME(nX)] := CTOD("00-00-00")
case valtype(aVars[FIELDNAME(nX)]) == "M" ; aVars[FIELDNAME(nX)] := space(200)
case valtype(aVars[FIELDNAME(nX)]) == "L" ; aVars[FIELDNAME(nX)] := .F.
endcase
next
Return aVars
Mirando en los fuentes de harbour, hay un ejemplo de clase pero tampoco me funciona como yo quiero, puedo acceder al campo por la posición en el buffer pero no por el nombre del campo:
- Code: Select all Expand view RUN
#include "FiveWin.ch"
FUNCTION Main()
LOCAL oCu
MsgInfo( "start" )
USE Customer ALIAS CU NEW
oCu := HbRecord():New("CU")
oCu:Get()
? oCu:Buffer[1]
? oCu:FIRST
RETURN nil
// código de C:\harbour\contrib\xhb\ttable.prg
CREATE CLASS HBField
VAR ALIAS INIT Alias()
VAR Name INIT ""
VAR TYPE INIT "C"
VAR Len INIT 0
VAR Dec INIT 0
VAR ORDER INIT 0
VAR Value
METHOD Get() INLINE ::value := ( ::alias )->( FieldGet( ::order ) )
METHOD Put( x ) INLINE ::value := x, ;
( ::alias )->( FieldPut( ::order, x ) )
ENDCLASS
CREATE CLASS HBRecord
VAR Buffer INIT {}
VAR ALIAS INIT Alias()
VAR Number INIT 0
VAR aFields INIT {}
METHOD New( cAlias )
METHOD Get()
METHOD Put()
ENDCLASS
METHOD NEW( cAlias ) CLASS HBRecord
LOCAL i
LOCAL oFld
LOCAL aStruc
LOCAL aItem
__defaultNIL( @cAlias, Alias() )
::Alias := cAlias
::Buffer := {} // {=>}
::aFields := Array( ( ::alias )->( FCount() ) )
aStruc := ( ::alias )->( dbStruct() )
FOR EACH aItem in ::aFields
i := aItem:__EnumIndex()
oFld := HBField()
oFld:order := i
oFld:Name := ( ::alias )->( FieldName( i ) )
oFld:Type := aStruc[ i, 2 ]
oFld:LEN := aStruc[ i, 3 ]
oFld:Dec := aStruc[ i, 4 ]
oFld:Alias := ::alias
aItem := oFld
NEXT
RETURN Self
METHOD PROCEDURE Get() CLASS HBRecord
LOCAL xField
FOR EACH xField IN ::aFields
xField:Get()
::buffer[ xField:__EnumIndex() ] := xField:value
NEXT
RETURN
METHOD PROCEDURE Put() CLASS HBRecord
LOCAL xField
FOR EACH xField IN ::aFields
IF !( xField:Value == ::buffer[ xField:__EnumIndex() ] )
xField:PUT( ::buffer[ xField:__EnumIndex() ] )
::buffer[ xField:__EnumIndex() ] := xField:value
ENDIF
NEXT
RETURN
Se que FWH tiene la clase DataRow, pero me parece matar moscas a cañonazos. Si alguien tiene una alternativa al clásico Scatter / Gather que permita acceder via nombre del campo, le agracederé que lo comparta.
Saludos,
José Luis