Page 1 of 1
AADD not working with GETS
Posted: Sat Feb 02, 2019 7:12 pm
by ellano
After noticing that a tabbed dialog only updated partially, I finally realize (5 hours later) that if I fill-up the culprit array using:
Code: Select all
aCalif:={}
...
AADD(aCalif,{chCta, Others[INT(chCta+.5)+1] ,thCta, Others[int(thCta+.5)+1], ;
(chCta+thCta)/2, Others[int((chCta+thCta)/2+.5)+1]})
AADD(aCalif,{cmCta, mCab[nInd] ,tmCta, Others[int(tmCta+.5)+1], ;
(cmCta+tmCta)/2, Others[int((cmCta+tmCta)/2+.5)+1]})
...
it will not work in the following dialog code (will not update, although it will show the correct data for the 1st register):
Code: Select all
REDEFINE GET oDbf:Number ID 301 OF oFld:aDialogs[6] READONLY UPDATE
REDEFINE GET aCalif[1][1] ID 101 OF oFld:aDialogs[6] PICTURE "#9.99" UPDATE FONT oFuente[2] //cbl
REDEFINE GET aCalif[1][2] ID 102 OF oFld:aDialogs[6] UPDATE READONLY FONT oFuente[2]
REDEFINE GET aCalif[1][3] ID 103 OF oFld:aDialogs[6] PICTURE "#9.99" UPDATE FONT oFuente[2] //tor
REDEFINE GET aCalif[1][4] ID 104 OF oFld:aDialogs[6] UPDATE READONLY FONT oFuente[2]
----
Things came back to normal when using this kind of assignment:
Code: Select all
LOCAL aCalif[25,6]
...
aCalif[1,1]:=chCta
aCalif[1,2]:=Others[INT(chCta+.5)+1]
aCalif[1,3]:=thCta
aCalif[1,4]:=Otros[int(thCta+.5)+1]
aCalif[1,5]:=(chCta+thCta)/2
aCalif[1,6]:= Others[int((chCta+thCta)/2+.5)+1]
aCalif[2,1]:=cm
aCalif[2,2]:=mCab[nInd]
aCalif[2,3]:=tm
aCalif[2,4]:=Others[INT(tm+.5)+1]
...
This is really a shame since the code changes from a compact, few-liner program, to a huge horrible monster.
Is there something that can be done in the version or code?
FWH 18.07
Emiliano Llano Díaz
Re: AADD not working with GETS
Posted: Sat Feb 02, 2019 8:20 pm
by Otto
Clear.
Re: AADD not working with GETS
Posted: Sat Feb 02, 2019 9:34 pm
by Otto
Re: AADD not working with GETS
Posted: Sun Feb 03, 2019 12:32 am
by nageswaragunupudi
It has to work.
This is a sample that works perfectly.
Code: Select all
#include "fivewin.ch"
function Main()
local aData := {}
local i, j
local oDlg
AAdd( aData, { 101, 102, 103 } )
AAdd( aData, { 201, 202, 203 } )
AAdd( aData, { 301, 302, 303 } )
DEFINE DIALOG oDlg SIZE 500,200 PIXEL TRUEPIXEL
for i := 1 to 3
for j := 1 to 3
@ 40 * i, 100 * j GET aData SUBSCRIPT i,j PICTURE "9999" SIZE 70,30 PIXEL OF oDlg RIGHT
next j
next i
ACTIVATE DIALOG oDlg CENTERED
XBROWSER aData
return nil
If you are still not convinced, please post a sample which we can build and test at our end.
Re: AADD not working with GETS
Posted: Sun Feb 03, 2019 7:16 am
by ellano
I'm not saying that it does not works. IT works to show the dialog the 1st time, but as the user skips from register to register the dialog does not update, it keeps the old values.
Doing it assigning values to a predefined array, on the other hand, works perfectly showing the values every time.
Re: AADD not working with GETS
Posted: Sun Feb 03, 2019 9:23 am
by nageswaragunupudi
I'm not saying that it does not works. IT works to show the dialog the 1st time, but as the user skips from register to register the dialog does not update, it keeps the old values.
No, please.
It works correctly.
Please re-check.
Re: AADD not working with GETS
Posted: Mon Feb 04, 2019 5:36 pm
by ellano
Here is a mini working example:
To notice before you answer:
1. I do not use browse in this example, but my tabbed dialogs are full of them as well as lists, images, comboboxes, date fields, buttons, slide-shows, reports, Excel conversion, SQL queries, and everything else that works correctly
2. I cannot change to browse since there are zillions of discrete fields that should be fill-in by the user depending on previous answers
3. The problem is only with ARRAYS (using AADD as explained) and nothing else
4. This is an incomplete example missing a lot of functionalities only done as proof of concept. It will work to show the update problem if you place the DB and required icons (even if they do not correspond)
Code: Select all
// the problem here is ONLY with GETS and SAYS using arrays
#include "fivewin.ch"
STATIC oDlg
FUNCTION Main()
LOCAL aData, ;
oDbfC, ;
aText[3][3]
USE clientes //this DB is located in the samples path of FW
DATABASE oDbfC
oDbfC:LOAD()
oDbfC:GoTop()
Load_Data(@aData, @aText, oDbfC)
DEFINE DIALOG oDlg SIZE 800,400 PIXEL TRUEPIXEL
Show_Dialog(aData, aText, oDbfC)
ACTIVATE DIALOG oDlg CENTERED ON INIT (HB_SYMBOL_UNUSED(self), ;
Main_bar(@aData, @aText, oDbfC) )
RETURN nil
STATIC PROCEDURE Show_Dialog(aData, aText, oDbfC)
LOCAL i, j
*? HB_valtoExp(aData)
FOR i := 1 to 3
FOR j := 1 to 3
@ 40 * i, 200 * j GET aData SUBSCRIPT i,j PICTURE "9999" UPDATE SIZE 120,30 PIXEL OF oDlg
NEXT j
NEXT i
for i := 1 to 3
for j := 1 to 3
@ 150+ (40 * i), 200 * j GET aText SUBSCRIPT i,j PICTURE "9999" UPDATE SIZE 120,30 PIXEL OF oDlg
next j
next i
RETURN
************ Fill arrays as needed **********
STATIC PROCEDURE Load_Data(aData, aText, oDbfC )
LOCAL i
aData:={}
FOR i:=1 TO 3
AAdd( aData, { oDbfC:Nombre, oDbfC:Direccion, oDbfC:Telefono } )
oDbfC:Skip(1)
NEXT i
FOR i:=1 TO 3
aText[i][1]:=oDbfC:Nombre
aText[i][2]:=oDbfC:Direccion
aText[i][3]:=oDbfC:Telefono
oDbfC:Skip(1)
NEXT i
RETURN
***** Create button bar (use any image just to ilustrate the point)
STATIC PROCEDURE Main_bar(aData, aText, oDbfC)
LOCAL oBar, oBtn
DEFINE BUTTONBAR oBar OF oDlg SIZE 30,30
DEFINE BUTTON oBtn OF oBar ;
FILE ".\icons\previous.bmp" ;
ACTION (HB_SYMBOL_UNUSED(this), ;
nAccion(1,aData, @aText, @oDbfC) ) ;
TOOLTIP "Next"
DEFINE BUTTON oBtn OF oBar ;
FILE ".\icons\next.bmp" ;
ACTION (HB_SYMBOL_UNUSED(this), ;
nAccion(2,aData, @aText, @oDbfC) ) ;
TOOLTIP "Previous"
DEFINE BUTTON oBtn OF oBar ;
FILE ".\icons\exit.bmp" ;
ACTION (HB_SYMBOL_UNUSED(this), ;
oDlg:END() ) ;
TOOLTIP "Exit"
RETURN
//****** All actions from different button bar go here ***********************************************************
STATIC PROCEDURE nAccion(nAccion, aData, aText, oDbfC)
DO CASE //several possibilities here
CASE nAccion=1 //prev
dbSKIP(-1)
IF BOF()
dbGoTop()
ENDIF
CASE nAccion=2 //next
dbSKIP(1)
IF EOF()
dbGoTop()
ENDIF
ENDCASE
oDbfC:LOAD()
Load_Data(@aData, @aText, oDbfC )
oDlg:Refresh()
oDlg:Update()
RETURN
//----------------------------------------------------------------------------//
Re: AADD not working with GETS
Posted: Mon Feb 04, 2019 6:33 pm
by Otto
Hello,
after deleting PICTURE "9999" your code is working fine.
Clientes.dbf has only 20 records.
Everytime you you load_data you move 6 records. But your backbutton is only skip(-1).
Therefore you get empty records.
Best regards
Otto
Re: AADD not working with GETS
Posted: Tue Feb 05, 2019 3:26 am
by nageswaragunupudi
Mr. Ellano
Yes.
We can not refill the data using aData := {} and AAdd.
Because when we assign aData := {} again, this is a new array different from the array used in the Gets.
Also in Add,
AAdd( aData, { ..... } )
the array { ... } is again a new array which is different from the array used in the Gets.
So, the only way to refresh data is the assign each item individually as in the case of aText.
Re: AADD not working with GETS
Posted: Tue Feb 05, 2019 9:53 am
by ellano
OK. Understood. New array=will not update (strange that will show the old one).
Mr. Otto, of course I only skip 1 and -1, as I explain, this is only a test program, Nothing to do with a real case.
Just done to illustrate AADD vs array assignation and how they show (or not) in a Dialog.
And no, deleting PICTURE "9999" will not fix the issue (AADD will not update vs direct array assignation updates)
Thanks
Emiliano Llano Díaz
Re: AADD not working with GETS
Posted: Tue Feb 05, 2019 12:44 pm
by nageswaragunupudi
Array variable points to a memory location holding the data.
a1 := {}
a2 := a
Now both a1 and a2 refer to the same memory location. Any changes made to an element in array a1 are also seen in the array a2, because both refer to the same memory location.
? a1 == a2 // --> .t.
a1[ n ] := 100
? a2[ n ] // 100
Now let us assign
a1 := {} // or a1 := Array( x )
now a1 is a new array pointing to a different location in the memory.
a1 is not equal to a2 any more.
Changes made to a1 no longer reflect in a2.
Re: AADD not working with GETS
Posted: Thu Feb 07, 2019 2:07 pm
by ellano
After reading carefully your answer, I try something similar to pointers in C which worked perfectly:
Code: Select all
// Problem solved here using AADD to fill arrays
#include "fivewin.ch"
STATIC oDlg
FUNCTION Main()
LOCAL aData[3][3], ; //MUST be the same dimensions as the final array
oDbfC
USE clientes //this DB is located in the samples path of FW
DATABASE oDbfC
oDbfC:LOAD()
oDbfC:GoTop()
Load_Data(@aData, oDbfC)
DEFINE DIALOG oDlg SIZE 800,200 PIXEL TRUEPIXEL
Show_Dialog(aData, oDbfC)
ACTIVATE DIALOG oDlg CENTERED ON INIT (HB_SYMBOL_UNUSED(self), ;
Main_bar(@aData, oDbfC) )
RETURN nil
STATIC PROCEDURE Show_Dialog(aData, oDbfC)
LOCAL i, j
FOR i := 1 to 3
FOR j := 1 to 3
@ 40 * i, 200 * j GET aData SUBSCRIPT i,j UPDATE SIZE 120,30 PIXEL OF oDlg
NEXT j
NEXT i
RETURN
************ Fill arrays as needed **********
* This is practical for big arrays that need to be updated back in dialog
* since will give a compact code (completely useless and non-sense for small arrays)
STATIC PROCEDURE Load_Data(aData, oDbfC )
LOCAL i, j, aText:={}, aItem, nItem
FOR i:=1 TO 3
AAdd( aText, { oDbfC:Nombre, oDbfC:Direccion, oDbfC:Telefono } )
oDbfC:Skip(1)
NEXT i
// re-assign back to original array to update in dialog aCopy does not work
i:=1
FOR EACH aItem IN aText
j:=1
FOR EACH nItem IN aItem
aData[i][j]=nitem
j++
NEXT
i++
NEXT
RETURN
***** Create button bar (use any image just to ilustrate the point)
STATIC PROCEDURE Main_bar(aData, oDbfC)
LOCAL oBar, oBtn
DEFINE BUTTONBAR oBar OF oDlg SIZE 30,30
DEFINE BUTTON oBtn OF oBar ;
FILE ".\iconos\previous.bmp" ;
ACTION (HB_SYMBOL_UNUSED(this), ;
nAccion(1,aData, @oDbfC) ) ;
TOOLTIP "Next"
DEFINE BUTTON oBtn OF oBar ;
FILE ".\iconos\next.bmp" ;
ACTION (HB_SYMBOL_UNUSED(this), ;
nAccion(2,aData, @oDbfC) ) ;
TOOLTIP "Previous"
DEFINE BUTTON oBtn OF oBar ;
FILE ".\iconos\exit.bmp" ;
ACTION (HB_SYMBOL_UNUSED(this), ;
oDlg:END() ) ;
TOOLTIP "Exit"
RETURN
//****** All actions from different button bar go here ***********************************************************
STATIC PROCEDURE nAccion(nAccion, aData, oDbfC)
DO CASE //several possibilities here (incomplete code)
CASE nAccion=1 //prev
dbSKIP(-1)
IF BOF()
dbGoTop()
ENDIF
CASE nAccion=2 //next
dbSKIP(1)
IF EOF()
dbGoTop()
ENDIF
ENDCASE
oDbfC:LOAD()
Load_Data(@aData, oDbfC )
oDlg:Refresh()
oDlg:Update()
RETURN
//----------------------------------------------------------------------------//
Thanks for your time.
Re: AADD not working with GETS
Posted: Thu Feb 07, 2019 3:01 pm
by nageswaragunupudi
Mr. ellano
I prepared a very simple solution for you a few days back, but forgot to post.
Here it is:
In your first program, instead of
Code: Select all
aData:={}
FOR i:=1 TO 3
AAdd( aData, { oDbfC:Nombre, oDbfC:Direccion, oDbfC:Telefono } )
oDbfC:Skip(1)
NEXT i
Replace this code:
Code: Select all
DEFAULT aData := Array( 3, 3 )
FOR i:=1 TO 3
ACopy( { oDbfC:Nombre, oDbfC:Direccion, oDbfC:Telefono }, aData[ i ] )
oDbfC:Skip(1)
NEXT i
This works as you expected.
Re: AADD not working with GETS
Posted: Thu Feb 07, 2019 4:35 pm
by Otto
Dear Mr. Rao,
can you please post the whole prg file.
Thank you in advance
Otto
Re: AADD not working with GETS
Posted: Mon Feb 11, 2019 7:50 am
by nageswaragunupudi
Otto wrote:Dear Mr. Rao,
can you please post the whole prg file.
Thank you in advance
Otto
Here it is:
Code: Select all
#include "fivewin.ch"
REQUEST DBFCDX
FUNCTION Main()
local oDbf
local oDlg, oBar, i, j
local aData[ 3, 3 ]
local aText[ 3, 3 ]
oDbf := TDatabase():Open( nil, "CLIENTES", "DBFCDX", .t. )
Load_Data( aData, aText, oDbf )
DEFINE DIALOG oDlg SIZE 800,400 PIXEL TRUEPIXEL
DEFINE BUTTONBAR oBar OF oDlg SIZE 60,30 2007
DEFINE BUTTON OF oBar RESOURCE 0X30076 ;
ACTION ( oDbf:Skip( -1 ), If( oDbf:Bof(), oDbf:GoTop(), ), ;
Load_Data( aData, aText, oDbf ), ;
oDlg:Update() )
DEFINE BUTTON OF oBar RESOURCE 0X30077 ;
ACTION ( oDbf:Skip( 1 ), If( oDbf:Eof(), oDbf:GoTop(), ), ;
Load_Data( aData, aText, oDbf ), ;
oDlg:Update() )
DEFINE BUTTON OF oBar RESOURCE 0x100A5 ACTION oDlg:End()
for i := 1 to 3
for j := 1 to 3
@ 40 * i, 200 * j GET aData SUBSCRIPT i,j UPDATE SIZE 120,30 PIXEL OF oDlg
next j
next i
for i := 1 to 3
for j := 1 to 3
@ 150+ (40 * i), 200 * j GET aText SUBSCRIPT i,j UPDATE SIZE 120,30 PIXEL OF oDlg
next j
next i
ACTIVATE DIALOG oDlg CENTERED
oDbf:Close()
return nil
static procedure Load_Data( aData, aText, oDbf )
local i, nRec := oDbf:RecNo()
FOR i:=1 TO 3
ACopy( { oDbf:Nombre, oDbf:Direccion, oDbf:Telefono }, aData[ i ] )
oDbf:Skip(1)
NEXT i
FOR i:=1 TO 3
aText[i][1]:=oDbf:Nombre
aText[i][2]:=oDbf:Direccion
aText[i][3]:=oDbf:Telefono
oDbf:Skip(1)
NEXT i
oDbf:GoTo( nRec )
return