browse sobre array

browse sobre array

Postby José Luis Sánchez » Wed Dec 14, 2005 12:23 pm

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 los cambios.

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
User avatar
José Luis Sánchez
 
Posts: 556
Joined: Thu Oct 13, 2005 9:23 am
Location: Novelda - Alicante - España

Postby AngelSalom » Wed Dec 14, 2005 12:41 pm

No quiero decir que los arrays sea una mala idea pero yo en estos casos 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.
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 727
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Postby DanielPuente » Wed Dec 14, 2005 2:34 pm

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,
Daniel Puente
Mar del Plata, Argentina
danielpuente@speedy.com.ar
puenteda@hotmail.com
DanielPuente
 
Posts: 108
Joined: Sun Oct 09, 2005 6:12 pm
Location: Mar del Plata - Argentina

Postby José Luis Sánchez » Thu Dec 15, 2005 8:09 am

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,
User avatar
José Luis Sánchez
 
Posts: 556
Joined: Thu Oct 13, 2005 9:23 am
Location: Novelda - Alicante - España

Postby MarioG » Thu Dec 15, 2005 11:46 am

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
Resistencia - "Ciudad de las Esculturas"
Chaco - Argentina
User avatar
MarioG
 
Posts: 1380
Joined: Fri Oct 14, 2005 1:28 pm
Location: Resistencia - Chaco - AR

Postby Willi Quintana » Thu Dec 15, 2005 10:42 pm

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
User avatar
Willi Quintana
 
Posts: 1022
Joined: Sun Oct 09, 2005 10:41 pm
Location: Cusco - Perú


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 82 guests