Page 1 of 1

browse sobre array

Posted: Wed Dec 14, 2005 12:23 pm
by José Luis Sánchez
Hola:
Quiero hacer un mantenimiento de una tabla que tiene una relación a muchos sobre otra en un entorno multiusuario. Cuando edito un registro de la tabla principal quiero mostrar en un browse los registros relacionados. Como la edición se puede abandonar cancelando, no puedo mostrar directamente los registros de la tabla dependiente y estoy intentando montar un array con los registros dependientes para mostrarlos ahi y dar altas y bajas y luego refrescar la tabla real en caso de aceptar _.

Estoy intentando hacer un browse sobre este array que en algunos momentos puede estar vacio y me estoy encontrando que ni con twbrowse ni con xbrowse puedo hacerlo y que en cuanto el array está vacio me truena irremediablemente. ¿ Alguna idea de como atacar esto ? ¿ Con alguna clase de rdd sobre arrays ? ¿ Cual ?

Saludos,
José Luis

Posted: Wed Dec 14, 2005 12:41 pm
by AngelSalom
No quiero decir que los arrays sea una mala idea pero yo en _ desde siempre creo un fichero temporal con la estructura de la tabla relacionada y la lleno con los registros que cumplen los requisitos.
Una vez acabado el proceso, decides si actualizar o no la tabla.
Luego, se borra el fichero y, funciona perfecto.

Un saludo.

Posted: Wed Dec 14, 2005 2:34 pm
by DanielPuente
Jose Luis:

Yo uso esto con twbrowse, basta con pasarle cualquier vector:

FUNCTION MCHOICE(aNcampos,X,Y,ANCHO,ALTO,cTitulo)

Local oDlg, aBrw, RET:=0, nItem:=1,largo:=len(aNcampos)
DEFAULT cTitulo:="Seleccione..."

DEFINE DIALOG oDlg RESOURCE "MCHOICE" TITLE cTitulo
oDlg:lHelpIcon:=.f.

REDEFINE LISTBOX aBrw FIELDS ANCAMPOS[NITEM] id 999 of odlg;
FIELDSIZES 281 ON DBLCLICK (Ret:=nItem,oDlg:End()) //COLORS CLR_BLUE

aBrw:cAlias = "Array" // Just put something
aBrw:bLogicLen = { || Len( aNcampos ) }
aBrw:SetArray(aNCampos)
aBrw:bGoTop = { || nItem := 1 }
aBrw:bGoBottom = { || nItem := Eval( aBrw:bLogicLen ) }
aBrw:bGoBottom = { || nItem := Eval( aBrw:bLogicLen ) }
aBrw:bSkip = { | nWant, nOld | nOld := nItem, nItem += nWant,;
nItem := Max( 1, Min( nItem, Eval( aBrw:bLogicLen ) ) ),;
nItem - nOld }
aBrw:bKeyChar = { | nK | if( nK==VK_RETURN,(Ret:=nItem,oDlg:End()),) } // Controlling keystrokes
aBrw:lDrawHeader := .f.
aBrw:lcellstyle := .t.
aBrw:nlinestyle := 2
aBrw:nclrpane:= {|| iif( (nItem/2)-INT(nItem/2) > 0, CLR_LBLUE, CLR_LGRAY) }
* oBrw:nClrPane:={|| IIF((wAlias)->(OrdKeyNo())%2==0,CLR_LBLUE,CLR_LGRAY)}
aBrw:GoTop()
oDlg:SetControl(aBrw)

//ACTIVATE DIALOG oDlg ON INIT (aBrw:GoTop(),aBrw:Refresh(),oDlg:setsize(ANCHO,ALTO),oDlg:Move(X,Y))
ACTIVATE DIALOG oDlg ON INIT (oDlg:Move(X,Y),oDlg:setsize(ANCHO,ALTO))

RETURN Ret

Tambien podes browsear matrices:

Static Function TotPractica(cAlias,oBrw)

Local oDlg, aBrw, RET:=0, nItem:=1
Local X:=390,Y:=200,ANCHO:=454,ALTO:=140,cTitulo:=oemtoansi("Totales por Pr ctica")
Local nReg
Local aPractica:={},cCodPra:=(cAlias)->PRACTICA,largo:=0,I:=1,cTipo,cRecno:=(cAlias)->(RECNO())
Local aOrdenado:={},aPrueba:={}

DEFAULT cTitulo:="Seleccione..."

(cAlias)->(DBGOTOP())

DO WHILE ! (cAlias)->(EOF())

IF LEN(aPractica)==0
aadd(aPractica,{BUS_DES("PRACTICA",1,(cAlias)->PRACTICA,"NOMBRE"),1,(cAlias)->APAGAR})
ELSE
cTipo:=BUS_DES("PRACTICA",1,(cAlias)->PRACTICA,"NOMBRE")
nReg:=ASCAN( aPractica, { |aField| aField[1]==cTipo } )
IF nReg == 0
aadd(aPractica,{BUS_DES("PRACTICA",1,(cAlias)->PRACTICA,"NOMBRE"),1,(cAlias)->APAGAR})
ELSE
aPractica[nReg,2]+=1
aPractica[nReg,3]+=(cAlias)->APAGAR
ENDIF
ENDIF
(cAlias)->(DBSKIP())
ENDDO

(cAlias)->(DBGOTO(cRecno))
oBrw:Refresh()

FOR I:=1 TO LEN(aPractica)
aPractica[i,2]:=TRANS(aPractica[i,2],"@E 9,999")
aPractica[i,3]:=TRANS(aPractica[i,3],"@E 999,999.99")+" "
NEXT

IF LEN(aPractica)==0
Aadd(aPractica,{SPAC(30),SPAC(9),SPAC(10)})
ENDIF

DEFINE DIALOG oDlg RESOURCE "MCHOICE" TITLE cTitulo
oDlg:lHelpIcon:=.f.

aOrdenado:=ASORT(aPractica,,,{|x,y| x[1] < y[1]})

REDEFINE LISTBOX aBrw FIELDS aOrdenado[NITEM,1],aOrdenado[NITEM,2],aOrdenado[NITEM,3] ;
HEADER oemtoansi("Descripci¢n")," Cant."," Importe ";
id 999 of odlg;
FIELDSIZES 269,59,96 ON DBLCLICK (Ret:=nItem,oDlg:End()) //COLORS CLR_BLUE

aBrw:cAlias = "Array" // Just put something
aBrw:bLogicLen = { || Len( aOrdenado ) }
aBrw:SetArray(aOrdenado)
aBrw:bGoTop = { || nItem := 1 }
aBrw:bGoBottom = { || nItem := Eval( aBrw:bLogicLen ) }
aBrw:bGoBottom = { || nItem := Eval( aBrw:bLogicLen ) }
aBrw:bSkip = { | nWant, nOld | nOld := nItem, nItem += nWant,;
nItem := Max( 1, Min( nItem, Eval( aBrw:bLogicLen ) ) ),;
nItem - nOld }
aBrw:bKeyChar = { | nK | if( nK==VK_RETURN,(Ret:=nItem,oDlg:End()),) } // Controlling keystrokes
aBrw:lcellstyle := .t.
aBrw:nlinestyle := 2
aBrw:aJustify:={0,2,1}
aBrw:nclrpane:= {|| iif( (nItem/2)-INT(nItem/2) > 0, CLR_LBLUE, CLR_LGRAY) }
aBrw:lAdjLastcol:=.F.
aBrw:GoTop()
oDlg:SetControl(aBrw)
ALTO:=50+16.0*LEN(aOrdenado)
IF(ALTO > 550,ALTO:=550,)

IF LEN(aOrdenado) < 15
ACTIVATE DIALOG oDlg ON INIT (oDlg:Move(X,Y),oDlg:setsize(ANCHO,ALTO))
ELSE
ACTIVATE DIALOG oDlg ON INIT (oDlg:Move(X,Y),oDlg:setsize(ANCHO,ALTO),oDlg:Center())
ENDIF

Return nil

Saludos,

Posted: Thu Dec 15, 2005 8:09 am
by José Luis Sánchez
Angel: así es como lo hago normalmente, pero pensé que en red no es muy buena solución por el tema de crear temporales y borrarlos.

Daniel: gracias por la contestación. Voy a mirar el código detenidamente.

Saludos,

Posted: Thu Dec 15, 2005 11:46 am
by MarioG
José:
Con wBrwosede Checcarelli, y obviamente con el nativo, se pueden crear browse de array vacios sin problemas.
Un array del tipo aXX:= {{"i", "a"}, {"ii","b"}, {"iii","c" }}, podría adoptar la forma, o hacerlo desde el principio, como aXX:= {{"", ""}, {"",""}, {"","" }} y ser browseado sin problemas.
Para usar array, yo prefiero usar TArray, que crea un objeto array con metodos del tipo :GoTo(), :LastRec(); :Seek(), y otros.

saludos

Posted: Thu Dec 15, 2005 10:42 pm
by Willi Quintana
Hola,,
Con la TWBROWSE sale asi:
AADD(aProducto, {"Procesador","Pza"," 45.00"}
...
REDEFINE LISTBOX oLbx ;
FIELDS aProducto[oLbx:nAt, 1], ;
aProducto[oLbx:nAt, 2], ;
aProducto[oLbx:nAt, 3] ;
HEADERS "Producto", ;
"Unidad", ;
"Stock" ;
FONT oFont1 ;
SIZES 400,50,65 ;
COLOR CLR_BLACK, cColor1;
ID 220 OF oFld:aDialogs[1]

oLbx:SetArray( aProducto )

La ultima linea es muy importante,,,,

Salu2