Passing variables by reference in nested functions

Passing variables by reference in nested functions

Postby Rick Lipkin » Mon May 21, 2012 8:09 pm

To All

Without giving any small contained example, I would like to know how deeply nested you can pass a variable by reference that can still be evaluated at the top level.

Please consider the below pseudo example .. I can not use any Static or Public variable declarations. It appears that xTotal can be modified in Function Level1 but not any deeper and still seen in Main() with the modified values.

Am I doing something wrong in syntactically passing the parameter below?

Thanks
Rick Lipkin

//------------------
Function Main()

Local xTotal,oTotal

xTotal := 10.00

REDEFINE GET oTotal var xTotal ID 183 of oWorkB PICTURE "999,999.99" READONLY

.. xTotal equals 10.00 here


Level1(@xTotal,oTtoal )



//-------------------
Static Func Level1( xtotal,oTotal)

xTotal := 20.00

oTotal:ReFresh()
SysreFresh() // should be seen in Main as 20.00 and it is


Level2( @xTotal,oTotal )

Return(nil)

//-----------------
Static Func Level2( xTotal,oTotal )

xTotal := 30.00

oTotal:ReFresh()
SysReFresh() // should be seen in Main as 30.00 and it is NOT

Level3( @xTotal,oTotal )

Return(nil)

//------------------
Static Func Level3( xTotal ,oTotal)

xTotal := 40.00

oTotal:ReFresh()
SysReFresh() // should be seen in Main as 40.00 and it is NOT


Return(nil)
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions

Postby Daniel Garcia-Gil » Tue May 22, 2012 3:05 am

Rick

the sample work fine to me

Code: Select all  Expand view  RUN

#include "fivewin.ch"

Function Main()

Local xTotal,oTotal

xTotal := 10.00
//define window oWnd

//@ 10, 10 GET oTotal var xTotal of oWnd PICTURE "999,999.99" READONLY size pixel

//.. xTotal equals 10.00 here
? xTotal, 1

Level1(@xTotal,nil )

? xTotal, 7


//-------------------
Static Func Level1( xtotal,oTotal)

? xtotal,2
xTotal := 20.00

//oTotal:ReFresh()
//SysreFresh() // should be seen in Main as 20.00 and it is


Level2( @xTotal,oTotal )

? xTotal, 6

Return(nil)

//-----------------
Static Func Level2( xTotal,oTotal )

? xtotal, 3
xTotal := 30.00

//oTotal:ReFresh()
//SysReFresh() // should be seen in Main as 30.00 and it is NOT

Level3( @xTotal,oTotal )
? xtotal, 5

Return(nil)

//------------------
Static Func Level3( xTotal ,oTotal)

xTotal := 40.00

//oTotal:ReFresh()
//SysReFresh() // should be seen in Main as 40.00 and it is NOT
? xtotal, 4

Return(nil)
 
User avatar
Daniel Garcia-Gil
 
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 pm
Location: Isla de Margarita

Re: Passing variables by reference in nested functions

Postby Rick Lipkin » Tue May 22, 2012 2:30 pm

Daniel

I have distilled my program down ( pardon the lengthy code ) to a show how my totals are not being updated on the main mdi screen. It appears from my debugging msginfo's that the values are being updated .. but not the values I see on the main screen after I reach the InvtFind routine.

I am sure there is a simple answer to my problem .. notice that I am opening a Mid and several MdiChildren .. please notice the screenshot and slide the second Mdichild to the right to be able to monitor the main screen variables.

Thanks
Rick Lipkin

Image

Main.prg
Code: Select all  Expand view  RUN

// Service Assistant Proof of Concept
//
//

#include "fivewin.ch"

Static oWndMain

//-----------
Function main()

local oButt1, oButt2, cTitle

Local cFile,aDir,dExe,nStart,cDefa
Local nScr1,nScr2,nYear,cRights,cRdd,cAuth

Local oBar,oBmap
Local lOk1,lRick

PUBLIC xLOGIN,xREAD,xWRITE,xSUPER,xEMPNUM
PUBLIC xPROVIDER,xSOURCE,xCATALOG,xUSERID,xPASSWORD,xCONNECT,xDATABASE

//fix for readonly gets
TGet():lDisColors := .f.

lRick := .f.  // local for valid close

//-- get timestamp on .exe //

cFILE := GetModuleFileName( GetInstance() )
aDIR  := DIRECTORY( cFILE )
dEXE  := aDIR[1] [3]

// where .exe started from is default directory //

nSTART := RAT( "\", cFILE )
cDEFA  := SUBSTR(cFILE,1,nSTART-1)

aDIR   := NIL

SET DEFA to ( cDEFA )

xDATABASE := "
A"      // access
// xDATABASE := "
S"   // sql server
// xCATALOG  := "
SERVICE"
// xUSERID   := "
serviceuser"

xPROVIDER := "
Microsoft.Jet.OLEDB.4.0"
xSOURCE   := cDEFA+"
\Service.mdb"
xPASSWORD := "
dec2011"

IF xDATABASE = "
A"
   xCONNECT := 'Provider='+xPROVIDER+';Data Source='+xSOURCE+';Jet OLEDB:Database Password='+xPASSWORD
ELSE
   xCONNECT := 'Provider='+xPROVIDER+';Data Source='+xSOURCE+';Initial Catalog='+xCATALOG+';User Id='+xUSERID+';Password='+xPASSWORD
ENDIF

REQUEST DBFCDX
rddsetdefault ( "
DBFCDX" )

nSCR1 := GetSysMetrics(0)
nSCR2 := GetSysMetrics(1)

SET DELETED on
SET CENTURY on
SET 3DLOOK on

nYEAR := ( year( DATE() )-30 )
SET EPOCH to ( nYEAR )

// global gradient
*LightGreyGrad()


cAUTH   := 'Y'

xREAD   := "
Y"
xWRITE  := "
Y"
xLOGIN  := "
Y"
xSUPER  := "
Y"
xEMPNUM := 11


IF xDATABASE = "
A"
   cRDD   := xPROVIDER+"
-- "+xSOURCE//+"\"+xCATALOG
ELSE
   cRDD   := xPROVIDER+"
-- "+xSOURCE+"\"+xCATALOG
ENDIF

cTITLE  :=  "
Parts Requisition and Sourcing Program"

cRIGHTS := _Rights()

xMESSAGE :=  "
User  "+xLOGIN+"    Rights  "+cRIGHTS+        ;
      "
    Default= "+cDEFA+"      Rdd= "+cRDD+            ;
      "
    Revision  "+DTOC(dEXE)+;
      "
 -r"+str(nSCR1,4)+" x "+STR(nSCR2,4)

DEFINE BITMAP oBMAP FILENAME (cDEFA+"
\LOGO.BMP") of oWndMain

SetBalloon( .T. )

cTITLE  := "
Service Assistant Proof of Concept"

DEFINE WINDOW oWndMain TITLE cTitle ;
       MENU BuildMenu();
       MDI

       DEFINE BUTTONBAR oBar OF oWndMain SIZE 45, 40 2010
       oBar:SetColor( 0)

       oBar:bClrGrad = { || { { 0.10,15724527,7303023 }, ;
       { 0.10,7303023,15724527 } } }

       DEFINE BUTTON oButt1 of oBar ACTION ( _WorkBrow( oWndMain ))  ;
             PROMPT "
Work" ;
             TOOLTIP "
Navigator"

       DEFINE BUTTON oButt2 of oBar ACTION oWndMain:End() ;
              PROMPT "
Quit" ;
              TOOLTIP "
Quit"

   SET MESSAGE OF oWndMain     ;
       to xMessage CLOCK 2010

Activate Window oWndMain MAXIMIZED ;
         ON INIT (IF( nSCR1 < 1024, _ResMessage(nSCR1, nSCR2), ));// 560,230
         VALID ( IIF( !lRick, ExitPgm(.T.,@lRick), .F. ))

Return( Nil )


//--------------------------
Static Func BuildMenu()

Local oMenu

MENU oMenu 2007

     MENUITEM "
&Quit" ;
         ACTION oWndMain:End()

ENDMENU

Return( oMenu )


//---------------------------
Static Func _Rights()

LOCAL cREAD,cWRITE,cSUPER,cRIGHTS

cREAD  := "
R"
cWRITE := "
"
cSUPER := "
"

IF xWRITE = 'Y'
   cWRITE := "
W"
ENDIF
IF xSUPER = "
Y"
   cSUPER := "
S"
ENDIF

IF cWRITE = "
" .and. cSUPER = " "
   cRIGHTS := "
(READ)"
ELSE
   cRIGHTS := "
("+cREAD+cWRITE+cSUPER+")"
ENDIF

RETURN( cRIGHTS )

//-------------------------
Static Func _ResMessage(nSCR1, nSCR2)

LOCAL SAYING

SAYING := "
It appears that your screen resolution is "+str(nSCR1,4)+"x"+STR(nSCR2,4)+" and is below"+chr(10)
SAYING += "
the minimum of 1024 x 768. This is not a critical error, however you will"+chr(10)
SAYING += "
find some screens and forms in this application that will be too large to fit"+chr(10)
SAYING += "
on your screen... just fair warning"+chr(10)

MsgInfo( saying )

RETURN(.T.)


//-----------------------
Static Func ExitPgm( lCLEAN,lRick )

LOCAL aDIR, cFILE, cDEFA, lOK1

cDEFA := SET(7)
lOK1  := .F.

IF lCLEAN = .T.
   lOK1   := .T.
   lRick  := .T.

   SET RESOURCES to

ENDIF

RETURN( lOK1 )

// end




WorkBrow.prg
Code: Select all  Expand view  RUN

// Workbrow.prg

#Include "FiveWin.ch"

//------------------
Func _WorkBrow( oWnd )

Local oWndChild,xTitle,lOk,oWork
Local oIco,oBtn1,oBtn2,oFontB,oFontBig

oFontB  := TFont():New("Ms Sans Serif",,-6,.F.,.T. ,,,,.F. )

lOk    := .f.
xTitle := "Service Navigator  -  Repairs, Estimates, & Service Calls"

DEFINE WINDOW oWndChild            ;
       FROM 0,0 to 39,120          ;
       MDICHILD                    ;
       OF oWnd                     ;
       TITLE xTITLE

       DEFINE DIALOG oWork RESOURCE "WORKBROW" of oWndChild


       REDEFINE BTNBMP oBtn1 ID 147 PROMPT "Add Repair Detail" CENTER ;
                of oWork 2007 ;
                ACTION( _WorkView( oWnd, oWndChild ) )


       REDEFINE BTNBMP oBtn2 ID 140 PROMPT "&Close" CENTER ;
                of oWork 2007 ;
                ACTION oWndChild:End()

       ACTIVATE DIALOG oWork NOMODAL ;
                VALID(!GETKEYSTATE( 27 ))

ACTIVATE WINDOW oWndChild ;
   ON INIT ( oWork:Move( 0,0, oWndchild:nWidth, oWndchild:nHeight, .T. ), ;
           oWndChild:bResized := {|| _ReSizeUm( oWork,oWndChild) }, ;
           oWork:refresh(.t.));
   VALID ( IIF( !lOK, ExitPgm(.T.,oWndChild,@lOk,oFontB ), .F. ))

RETURN( NIL )

//------------------------------
Static Func _ReSizeUm( oWork,oWndChild )


oWork:SetSize( oWndChild:nWidth, oWndChild:nHeight, .t. ) // frame and dialog link

// dialog controls
*oWork:bResized = { | nSizeType, nWidth, nHeight | ResizeControls( nSizeType, nWidth, nHeight, oWork )  }


Return(nil)

//-------------------------
Static Func ResizeControls( nSizeType, nWidth, nHeight, oDlg )


if nSizeType = 0 //SIZE_MAXIMIZED
                                                       // 277
   oDlg:aControls[ 1  ]:SetSize( nWidth - 37, nHeight - 247 ) //txbrowse

endif

Return(nil)

//--------------------------------
Static FUNCTION ExitPgm( lCLEAN,oWndchild,lOk,oFontB )

LOCAL lOK1

IF lCLEAN = .T.
   lOK  := .T.
   lOK1 := lOK

   oWndChild:End()
   oFontB:End()

ENDIF

RETURN( lOK1 )
// end
 


WorkView.prg
Code: Select all  Expand view  RUN

// WorkView.prg


#Include "FiveWin.ch"
#Include "xBrowse.ch"

//------------------
Func _WorkView( oWnd,oWndChild )

Local lOk,lOk1,lClosed,lTransfer,xMode,cMode
Local oFontB,oFontBig,xTitle

Local xLabor,xParts,xMisc,xTax,xTotal
Local oLabor,oParts,oMisc,oTax,oTotal

Local oWndChildB,oWorkB
Local oBtn1,oBtn2,oBtn3,oBtn4,oBtn5,oBtn6,oBtn7,oBtn8,oBtn9,oBtn10,oBtn11,oBtn12,oBtn13,oBtn14

Local Saying,nRepairNumber

lOk       := .f.  // trap valid close local
lOk1      := .f.  // used for close local
lOk3      := .f.  // used for invtfind
lClosed   := .f.  // use for close workedit
lTransfer := .f.  // used for close transfer

nRepairNumber := 100000

xLabor  := 0.00
xParts  := 0.00
xMisc   := 0.00
xTax    := 0.00
xTotal  := 0.00

oFontB        := TFont():New("Ms Sans Serif",,-6,.F.,.T. ,,,,.F. )
oFontBig      := TFont():New("Ms Sans Serif",,-14,.F.,.T. ,,,,.F. )

**** oWndChild:Hide()

lOk    := .f.
xTitle := "RO "+LTRIM( STR( nRepairNumber))

DEFINE WINDOW oWndChildB           ;
       FROM 0,0 to 39,120          ;
       MDICHILD                    ;
       OF oWnd                     ;
       TITLE xTITLE

       DEFINE DIALOG oWorkB RESOURCE "WORKVIEW" of oWndChildB

       REDEFINE GET oParts var xParts ID 170 of oWorkB PICTURE "999,999.99" READONLY
       REDEFINE GET oLabor var xLabor ID 173 of oWorkB PICTURE "999,999.99" READONLY
       REDEFINE GET oMisc  var xMisc  ID 175 of oWorkB PICTURE "999,999.99" READONLY
       REDEFINE GET oTax   var xTax   ID 177 of oWorkB PICTURE "999,999.99" READONLY

       REDEFINE GET oTotal var xTotal ID 183 of oWorkB PICTURE "999,999.99" READONLY


       REDEFINE BTNBMP oBtn1 ID 147 PROMPT "Lookup Parts" CENTER ;
                of oWorkB 2007 ;
               ACTION ( _InvtFind( oWnd,oWndChildB,oFontB,oFontBig,nRepairNumber,;
                         @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                         oLabor,oParts,oMisc,oTax,oTotal) )

       REDEFINE BTNBMP oBtn14 ID 140 PROMPT "Close" CENTER ;
                of oWorkB 2007 ;
                ACTION ( IF(cMODE = "V", lOK1 := .T., lOK1 := _busrules() ), ;
                         IF(cMODE = "V", lOK1 := .T. ,;
                           if(lOK1 = .T., _doit( cMODE),)),;
                         IF(lOK1  = .T., oWndChildB:end(), ))

       ACTIVATE DIALOG oWorkB NOMODAL ;
                ON INIT _ReCalcTotals( @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                         oLabor,oParts,oMisc,oTax,oTotal) ;
                VALID(!GETKEYSTATE( 27 ))

ACTIVATE WINDOW oWndChildB ;
   ON INIT ( oWorkB:Move( 0,0, oWndchildB:nWidth, oWndchildB:nHeight, .T. ),  ;
           oWndChildB:bResized := {|| _ReSizeUm( oWorkB,oWndChildB) }, ;
           oWorkB:refresh(.t.));
   VALID ( IIF( !lOK, ExitPgm(.T.,oWndChildB,oWndChild,@lOk,oFontB,oFontBig ), .F. ))


RETURN( NIL )

//---------------
Static Func  _busrules()

Return(.t.)


//------------------
Static Func _InvtLookUp( cMode, cStockno, oRsDetail,;
                        cItemDescription,nPrice,cInventoryId,cInventoryType)

Local oRsInvt, cSql, Saying

If cMode = "V"
   Return(.t.)
Endif

If cMode = "A" .or. cMode = "E"
   If empty(cStockno) .or. cStockno = " "
      Saying := "Sorry .. you can not leave the Part"+chr(10)
      Saying += "Number Blank"+chr(10)
      MsgInfo( Saying )
    *  oInventoryId:SetFocus()
      Return(.f.)
   Endif
Endif

If cMode = "E"
   If oRsDetail:Fields("Inventory Id"):Value = cStockno
      Return(.t.)
   Endif
Endif

oRsInvt := TOleAuto():New( "ADODB.Recordset" )
oRsInvt:CursorType     := 1        // opendkeyset
oRsInvt:CursorLocation := 3        // local cache
oRsInvt:LockType       := 3        // lockoportunistic

cSql := "Select [Inventory Id],Description,Price,Cost,[Inventory Type] From Inventory "
cSql += "where [Inventory Id] like '"+alltrim(cStockno)+"%'"

TRY
   oRsInvt:Open( cSQL,xCONNECT )
CATCH oErr
   MsgInfo( "Error in Opening INVENTORY table" )
   RETURN(.F.)
END TRY

If oRsInvt:eof
Else

   // added for cell edit
   cInventoryId        := substr(oRsInvt:Fields("Inventory Id"):Value+space(50),1,50)
   cInventoryType      := substr(oRsInvt:Fields("Inventory Type"):Value+space(50),1,50)
   cItemDescription    := substr(oRsInvt:Fields("Description"):Value+space(255),1,255)
   nPrice              := oRsInvt:Fields("Price"):Value

Endif

oRsInvt:CLose()


Return( .t. )

//--------------------------
Static Func _ReCalcTotals( xLabor,xParts,xMisc,xTax,xTotal,;
                           oLabor,oParts,oMisc,oTax,oTotal)

Local nStart,nTaxable,Saying

Saying := "In ReCalc"+chr(10)
Saying += " "+chr(10)
Saying += "xLabor before "+str(xLabor)+chr(10)
Saying += "xParts before "+str(xParts)+chr(10)
Saying += "xMisc  before "+str(xMisc)+chr(10)
Saying += "xTax   before "+str(xTax)+chr(10)
Saying += "xTotal before "+str(xTotal)+chr(10)

MsgInfo( saying )

/*
xLabor   := 0.00
xParts   := 0.00
xMisc    := 0.00
xTax     := 0.00
xTotal   := 0.00
*/


xLabor := xLabor+10.00
xParts := xParts+5.00
xMisc  := 0
xTax   := round((xParts *.07),2)
xTotal := xLabor+xParts+xMisc+xTax

oParts:ReFresh()
oLabor:ReFresh()
oMisc:ReFresh()
oTax:ReFresh()
oTotal:ReFresh()
SysReFresh()


Saying += "out ReCalc check screen"+chr(10)
Saying += " "+chr(10)
Saying += "xLabor after "+str(xLabor)+chr(10)
Saying += "xParts after "+str(xParts)+chr(10)
Saying += "xMisc  after "+str(xMisc)+chr(10)
Saying += "xTax   after "+str(xTax)+chr(10)
Saying += "xTotal after "+str(xTotal)+chr(10)

MsgInfo( saying )


Return( .T. )


//------------------------------
Static Func _ReSizeUm( oWorkB1,oWndChildB1 )

oWorkB1:SetSize( oWndChildB1:nWidth, oWndChildB1:nHeight, .t. ) // frame and dialog link

// dialog controls
*oWorkB1:bResized = { | nSizeType, nWidth, nHeight | ResizeControls( nSizeType, nWidth, nHeight, oWorkB1 )  }

Return(nil)

//-------------------------
Static Func ResizeControls( nSizeType, nWidth, nHeight, oWorkB1 )


if nSizeType = 0 //SIZE_MAXIMIZED

   oWorkB1:aControls[ 1 ]:SetSize( nWidth - 170, nHeight - 295 ) //txbrowse

endif

Return(nil)

//--------------------
Static Func _DoIt( cMODE )

Return(.t.)

//--------------------------------
Static FUNCTION ExitPgm( lOk3,oWndchildB,oWndChild,lOk,oFontB,oFontBig )

// olbx is from the repair screen
// obrw is from this repair detail screen

LOCAL lOK1


Msginfo( "ExitPgm")

IF lOk3 = .T.
   lOK  := .T.
   lOK1 := lOK

   oWndChildB:End()
   oFontB:End()
   oFontBig:End()

   oWndChild:Show()

ENDIF

RETURN( lOK1 )

//--------------------
Static Func _InvtFind( oWnd,oWndChildB,oFontB,oFontBig,nRepairNumber,;
                       xLabor,xParts,xMisc,xTax,xTotal,;
                       oLabor,oParts,oMisc,oTax,oTotal)

Local oIco,oBtn1,oBtn2,oBtn3,oBtn4
Local Saying,xTitle

Local lok3
Local oInvt,oWndChildD

xParts := 10.00
xLabor := 10.00
xMisc  := 20.00
xTax   := 0

xTotal := 40.00

oParts:ReFresh()
oLabor:ReFresh()
oMisc:ReFresh()
oTax:ReFresh()
oTotal:ReFresh()


SysReFresh()

Saying := "Check page totals"+chr(10)
Saying += "xParts "+str(xParts)+chr(10)
Saying += "xLabor "+str(xLabor)+chr(10)
Saying += "xMisc "+str(xMisc)+chr(10)
Saying += "xTax "+str(xTax)+chr(10)
Saying += "xTotal "+str(xTotal)+chr(10)

MsgInfo(Saying)

********oWndChildB:Hide()

lOk3   := .f.
xTitle := "Parts Selection Find Routine"

DEFINE WINDOW oWndChildD           ;
       FROM 0,0 to 39,120          ;
       MDICHILD                    ;
       OF oWnd                     ;
       TITLE xTITLE

       DEFINE DIALOG oInvt RESOURCE "INVTFIND" of oWndChildD



       REDEFINE BTNBMP oBtn2 ID 161 PROMPT "Transfer" CENTER ;
                of oInvt 2007 ;
                ACTION ( _Transfer( oWnd,oWndChildD,oFontB,oFontBig,nRepairNumber,;
                          @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                          oLabor,oParts,oMisc,oTax,oTotal))

       REDEFINE BTNBMP oBtn3 ID 162 PROMPT "Close" CENTER ;
                of oInvt 2007 ;
                ACTION (oWndChildD:End())


       ACTIVATE DIALOG oInvt NOMODAL ;
                VALID(!GETKEYSTATE( 27 ))

ACTIVATE WINDOW oWndChildD ;
   ON INIT ( oInvt:Move( 0,0, oWndchildD:nWidth, oWndchildD:nHeight, .T. ), ;
           oWndChildD:bResized := {|| _ReSizeUm1( oInvt,oWndChildD) }, ;
           oInvt:refresh(.t.));
   VALID ( IIF( !lOK3, ExitPgm3(.T.,oWndChildD,oWndChildB,@lOk3 ), .F. ))


RETURN( nil )

//-----------------------------------
Static Func _ReSizeUm1( oInvt,oWndChild )

Local Saying

// for inventory find

oInvt:SetSize( oWndChild:nWidth, oWndChild:nHeight, .t. ) // frame and dialog link

Saying := "Slide this window to the right to reveal totals"+chr(10)
Saying += "then proceed to the Transfer Button"+chr(10)

MsgInfo( saying )

Return(nil)


//--------------------------------------------
Static Func _Transfer( oWnd,oWndChildD,;
            oFontB,oFontBig,nRepairNumber,;
            xLabor,xParts,xMisc,xTax,xTotal,;
            oLabor,oParts,oMisc,oTax,oTotal,nAssignedTo,cLoc)



Local oDlgE,oButt1,oButt2,oButt3,cTitle,oWndChildE
Local lOk5,oIco
Local Saying
Local oP,oD,oQ,oR,oTran,nTran,oHand,nHand
Local lUpDt

Local oSay1,oSay2,oSay3,oSay4,oSay5,oSay6,oSay7
Local cItemDescription,nPrice,cInventoryId,cInventoryType,nExtend,nQty

Local lTransfer

Saying := "In Transfer passed values"+chr(10)
Saying += "xLabor "+str(xLabor)+chr(10)
Saying += "xParts "+str(xParts)+chr(10)
Saying += "xMisc "+str(xMisc)+chr(10)
Saying += "xTax "+str(xTax)+chr(10)
Saying += "xTotal "+str(xTotal)+chr(10)

msginfo( Saying )

xLabor := 5.00
xParts := 50.00
xMisc  := 5.00
xTax   := 0
xTotal := 60.00

oLabor:ReFresh()
oParts:ReFresh()
oMisc:ReFresh()
oTax:ReFresh()
oTotal:ReFresh()
SysReFresh()

Saying := "New Values Do not show up HERE"+chr(10)
Saying += "xLabor "+str(xLabor)+chr(10)
Saying += "xParts "+str(xParts)+chr(10)
Saying += "xMisc "+str(xMisc)+chr(10)
Saying += "xTax "+str(xTax)+chr(10)
Saying += "xTotal "+str(xTotal)+chr(10)

Msginfo( Saying )


nQty := 1

cItemDescription    := "USB 2.0 Ethernet Mini-Adapter"
nPrice              := 18.50
cInventoryId        := 524766
cInventoryType      := "Parts"
nExtend             := Round( (nPrice * nQty ),2 )
nHand               := 10

*LightGreyGrad()

lTransfer := .f.
lUpDt     := .f.
cTITLE    := "Inventory Transfer"

DEFINE ICON oIco RESOURCE "COMPASS"

DEFINE WINDOW oWndChildE           ;
       FROM 13,56 to 35,115        ;
       ICON oIco                   ;
       MDICHILD                    ;
       NOMINIMIZE                  ;
       NOZOOM                      ;
       OF oWnd                     ;
       TITLE cTITLE

   DEFINE DIALOG oDlgE RESOURCE "TRANSFER" of oWndChildE

       REDEFINE SAY oSay6 PROMPT "Transferring From Inventory"  ID 156 OF oDlgE UPDATE
                    oSay6:SetFont( oFontBig )
                    oSay6:nClrText := nRgb( 7,7,224 ) // blue

       REDEFINE SAY oSay1 PROMPT "Part Num"              ID 150 OF oDlgE UPDATE
                    oSay1:SetFont( oFontB )
       REDEFINE SAY oSay2 PROMPT "Description"           ID 152 OF oDlgE UPDATE
                    oSay2:SetFont( oFontB )
       REDEFINE SAY oSay3 PROMPT "Qty on Hand"           ID 154 OF oDlgE UPDATE
                    oSay3:SetFont( oFontB )
       REDEFINE SAY oSay4 PROMPT "To Repair Order"       ID 151 OF oDlgE UPDATE
                    oSay4:SetFont( oFontB )
       REDEFINE SAY oSay5 PROMPT "Quantity to Transfer"  ID 155 OF oDlgE UPDATE
                    oSay5:SetFont( oFontBig )
                    oSay5:nClrText := nRgb( 7,7,224 ) // blue

       REDEFINE SAY oSay6 ID 153 OF oDlgE UPDATE
                    oSay6:SetFont( oFontB )


       REDEFINE GET oP               VAR cInventoryId      ID 160 of oDlgE ;
                COLOR CLR_BLACK,14869218 READONLY
       REDEFINE GET oD               VAR cItemDescription  ID 162 of oDlgE ;
                COLOR CLR_BLACK,14869218 READONLY
       REDEFINE GET oHand            VAR nHand             ID 163 of oDlgE PICTURE "999,999" ;
                COLOR CLR_BLACK,14869218 READONLY
       REDEFINE GET oR               VAR nRepairNumber     ID 165 of oDlgE  ;
                COLOR CLR_BLACK,14869218 READONLY
       REDEFINE GET oQ               VAR nQty              ID 167 OF oDlgE UPDATE;
                PICTURE "9999" SPINNER MIN 1 MAX 1000


       REDEFINE BTNBMP oButt1 ID 180 of oDlgE  ;    // ok
         PROMPT "&Ok" CENTER 2007;
         ACTION ( lUpDt := .t., oWndChildE:END() )

       REDEFINE BTNBMP oButt2 ID 181 of oDlgE  ;    // cancel
         PROMPT "&Cancel" CENTER 2007;
         ACTION ( lUpDt := .f., oWndChildE:END() )


  ACTIVATE DIALOG oDlgE NOWAIT      ;
      ON INIT ( oDlgE:Move( 0, 0 )) ;
      VALID (!GETKEYSTATE( 27 ))  // do not allow esc key here

ACTIVATE WINDOW oWndChildE ;
   ON INIT (oWndChildE:SetSize( oDlgE:nWIDTH, oDlgE:nHEIGHT, .T. ),;
            oQ:SetFocus());
   VALID ( IIF( !lTransfer, ExitPgm4(.T.,oWndChildE,lUpDt,;
                oWndChildD,@lTransfer,@nQty,@nPrice,;
                @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                oLabor,oParts,oMisc,oTax,oTotal), .F.))


Return(lTransfer)

//-------------------------------------------
Static FUNCTION ExitPgm3( lOk2,oWndchildD,oWndChildB,lOk3 )

// from inventoryfind

LOCAL lOK1

msginfo("ExitPgm3")

lOk1 := .f.

IF lOk2 = .T.

   lOK3 := .T.
   lOK1 := lOK3

   oWndChildD:End()
   oWndChildB:Show()


ENDIF

RETURN( lOK1 )

//-------------------------------------------
Static FUNCTION ExitPgm4( lOk2,oWndchildE,lUpDt,oWndChildD,lTransfer,nQty,nPrice,;
       xLabor,xParts,xMisc,xTax,xTotal,;
       oLabor,oParts,oMisc,oTax,oTotal )

LOCAL lOK1,YesNo,nOk,cS

// lUpDt = .t.  save
// lUpDt = .f.  cancel

*msginfo( "e4")

msginfo("ExitPgm4")

lOk1 := .f.

IF lOk2 = .T.

   lTransfer := .T.
   lOK1 := lTransfer

   oWndChildE:End()  // transfer
   oWndChildD:End()  // invtfind

   _ReCalcTotals( @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                     oLabor,oParts,oMisc,oTax,oTotal)

   oLabor:ReFresh()
   oParts:ReFresh()
   oMisc:ReFresh()
   oTax:ReFresh()
   oTotal:ReFresh()

   SysReFresh()


ENDIF

RETURN( lOK1 )
// END

 

InvtFind.rc
Code: Select all  Expand view  RUN

INVTFIND DIALOG 12, 11, 618, 364
STYLE WS_CHILD
FONT 6, "MS Sans Serif"
{
 CONTROL "Close", 162, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 568, 8, 41, 48
 CONTROL "Transfer", 161, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 514, 8, 41, 48
}
 


Transfer.Rc
Code: Select all  Expand view  RUN

TRANSFER DIALOG 54, 20, 293, 198
STYLE WS_CHILD
FONT 6, "MS Sans Serif"
{
 CONTROL "&Ok", 180, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 195, 142, 37, 25
 EDITTEXT 167, 214, 120, 59, 16, ES_RIGHT | WS_BORDER | WS_VSCROLL | WS_TABSTOP
 EDITTEXT 160, 78, 34, 105, 12, ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 EDITTEXT 162, 78, 48, 199, 12, ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 EDITTEXT 163, 78, 62, 36, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 EDITTEXT 165, 78, 76, 64, 12, ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 CONTROL "&Cancel", 181, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 236, 142, 37, 25
 LTEXT "Part Num", 150, 6, 34, 49, 12
 LTEXT "To Repair Number", 151, 6, 76, 70, 12
 LTEXT "Description", 152, 6, 48, 49, 12
 LTEXT "Qty on Hand", 154, 6, 62, 48, 12
 LTEXT "Quantity to Transfer", 155, 6, 99, 184, 17
 LTEXT "Select the number of parts or labor hours ( in tenths ) you are placing on the repair", 153, 36, 117, 157, 21
 LTEXT "Transferring From Inventory", 156, 6, 6, 225, 19
}
 


WorkBrow.rc
Code: Select all  Expand view  RUN

WORKBROW DIALOG 12, 11, 629, 364
STYLE WS_CHILD
FONT 6, "MS Sans Serif"
{
 CONTROL "&Cancel", 140, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 555, 14, 67, 47
 CONTROL "Create New Repair", 147, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 445, 18, 67, 47
 GROUPBOX "", 199, 179, 9, 353, 61, BS_GROUPBOX
}
 


WorkView.Rc
Code: Select all  Expand view  RUN

WORKVIEW DIALOG 12, 11, 618, 364
STYLE WS_CHILD
FONT 6, "MS Sans Serif"
{
 CONTROL "Close", 140, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 563, 83, 41, 48
 GROUPBOX "", 197, 92, 76, 516, 62, BS_GROUPBOX
 CONTROL "Lookup Parts", 147, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 94, 87, 82, 15
 LTEXT "Parts", 169, 5, 274, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 170, 38, 273, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 LTEXT "Labor", 171, 5, 288, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 173, 38, 287, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 LTEXT "Misc", 174, 5, 302, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 175, 38, 301, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 LTEXT "Tax", 176, 5, 316, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 177, 38, 315, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 CONTROL "Cancel", 178, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 517, 83, 41, 48
 LTEXT "Total", 179, 5, 338, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 183, 38, 336, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 GROUPBOX "", 200, 1, 189, 85, 163, BS_GROUPBOX
 LTEXT "-------------------------------------------------", 185, 5, 327, 77, 6, SS_NOPREFIX | WS_GROUP
}
 
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions

Postby Daniel Garcia-Gil » Wed May 23, 2012 10:33 am

Rick

sorry, I could not understand the program flow, can you post a more simple test?
User avatar
Daniel Garcia-Gil
 
Posts: 2365
Joined: Wed Nov 02, 2005 11:46 pm
Location: Isla de Margarita

Re: Passing variables by reference in nested functions

Postby Rick Lipkin » Wed May 23, 2012 3:10 pm

Daniel

I have simplified the program considerably .. you will notice when you get to _InvtFind() the values on oWndCHildB are updated properly .. however when you go deeper to _Transfer() you will notice I am specifically changing the Variables passed by reference along with their objects and you will notice on oWndWhildB .. the values and objects are not updated.

Hope this code is simpler to follow and reproduce.

Rick Lipkin


Code: Select all  Expand view  RUN


#include "fivewin.ch"

Static oWndMain

//-----------
Function main()

local oButt1, oButt2, cTitle
Local oBar
Local lRick

//fix for readonly gets
TGet():lDisColors := .f.

lRick := .f.  // local for valid close

REQUEST DBFCDX
rddsetdefault ( "DBFCDX" )

SET DELETED on
SET CENTURY on
SET 3DLOOK on

nYEAR := ( year( DATE() )-30 )
SET EPOCH to ( nYEAR )

cTITLE  :=  "Parts Requisition and Sourcing Program"
SetBalloon( .T. )


DEFINE WINDOW oWndMain TITLE cTitle ;
       MENU BuildMenu();
       MDI

       DEFINE BUTTONBAR oBar OF oWndMain SIZE 45, 40 2010
       oBar:SetColor( 0)

       oBar:bClrGrad = { || { { 0.10,15724527,7303023 }, ;
       { 0.10,7303023,15724527 } } }

       DEFINE BUTTON oButt1 of oBar ACTION ( _WorkBrow( oWndMain ))  ;
             PROMPT "Work" ;
             TOOLTIP "Navigator"

       DEFINE BUTTON oButt2 of oBar ACTION oWndMain:End() ;
              PROMPT "Quit" ;
              TOOLTIP "Quit"

Activate Window oWndMain MAXIMIZED ;
         VALID ( IIF( !lRick, ExitPgm(.T.,@lRick), .F. ))

Return( Nil )


//--------------------------
Static Func BuildMenu()

Local oMenu

MENU oMenu 2007

     MENUITEM "&Quit" ;
         ACTION oWndMain:End()

ENDMENU

Return( oMenu )

//-----------------------
Static Func ExitPgm( lCLEAN,lRick )


IF lCLEAN = .T.
   lRick  := .T.

   SET RESOURCES to

ENDIF

RETURN( lRick )

//------------------
Static Func _WorkBrow( oWndMain )

Local oWndChildA,xTitle,lOkA,oWork
Local oBtn1,oBtn2

lOkA   := .f.
xTitle := "Service Navigator  -  Repairs, Estimates, & Service Calls"

DEFINE WINDOW oWndChildA           ;
       FROM 0,0 to 39,120          ;
       MDICHILD                    ;
       OF oWndMain                 ;
       TITLE xTITLE

       DEFINE DIALOG oWork RESOURCE "WORKBROW" of oWndChildA


       REDEFINE BTNBMP oBtn1 ID 147 PROMPT "Add Repair Detail" CENTER ;
                of oWork 2007 ;
                ACTION( _WorkView( oWndMain, oWndChildA ) )


       REDEFINE BTNBMP oBtn2 ID 140 PROMPT "&Close" CENTER ;
                of oWork 2007 ;
                ACTION oWndChildA:End()

       ACTIVATE DIALOG oWork NOMODAL ;
                VALID(!GETKEYSTATE( 27 ))

ACTIVATE WINDOW oWndChildA ;
   ON INIT ( oWork:Move( 0,0, oWndchildA:nWidth, oWndchildA:nHeight, .T. ), ;
             oWndChildA:bResized := {||oWork:SetSize( oWndChildA:nWidth, oWndChildA:nHeight, .t. )}, ;
             oWork:refresh(.t.));
   VALID ( IIF( !lOKA, ExitPgmA(.T.,oWndChildA,@lOkA ), .F. ))


RETURN( NIL )

//--------------------------------
Static FUNCTION ExitPgmA( lCLEAN,oWndchildA,lOkA )

IF lCLEAN = .T.
   lOKA  := .T.

   oWndChildA:End()

ENDIF

RETURN( lOKA )

//------------------
Static Func _WorkView( oWndMain,oWndChildA )

Local lOkB
Local xTitle

Local xLabor,xParts,xMisc,xTax,xTotal
Local oLabor,oParts,oMisc,oTax,oTotal

Local oWndChildB,oWorkB
Local oBtn1,oBtn2
Local Saying,nRepairNumber



nRepairNumber := 100000

xLabor  := 0.00
xParts  := 0.00
xMisc   := 0.00
xTax    := 0.00
xTotal  := 0.00


oWndChildA:Hide()

lOkB   := .f.
xTitle := "RO "+LTRIM( STR( nRepairNumber))

DEFINE WINDOW oWndChildB           ;
       FROM 0,0 to 39,120          ;
       MDICHILD                    ;
       OF oWndMain                 ;
       TITLE xTITLE

       DEFINE DIALOG oWorkB RESOURCE "WORKVIEW" of oWndChildB

       REDEFINE GET oParts var xParts ID 170 of oWorkB PICTURE "999,999.99" READONLY
       REDEFINE GET oLabor var xLabor ID 173 of oWorkB PICTURE "999,999.99" READONLY
       REDEFINE GET oMisc  var xMisc  ID 175 of oWorkB PICTURE "999,999.99" READONLY
       REDEFINE GET oTax   var xTax   ID 177 of oWorkB PICTURE "999,999.99" READONLY

       REDEFINE GET oTotal var xTotal ID 183 of oWorkB PICTURE "999,999.99" READONLY


       REDEFINE BTNBMP oBtn1 ID 147 PROMPT "Lookup Parts" CENTER ;
                of oWorkB 2007 ;
               ACTION ( _InvtFind( oWndMain,oWndChildB,nRepairNumber,;
                         @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                         oLabor,oParts,oMisc,oTax,oTotal,oWorkB) )

       REDEFINE BTNBMP oBtn2 ID 140 PROMPT "Close" CENTER ;
                of oWorkB 2007 ;
                ACTION ( oWndChildB:end())

       ACTIVATE DIALOG oWorkB NOMODAL ;
                ON INIT _ReCalcTotals( @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                         oLabor,oParts,oMisc,oTax,oTotal,oWorkB) ;
                VALID(!GETKEYSTATE( 27 ))

ACTIVATE WINDOW oWndChildB ;
   ON INIT ( oWorkB:Move( 0,0, oWndchildB:nWidth, oWndchildB:nHeight, .T. ),;
             oWndChildB:bResized := {||oWorkB:SetSize( oWndChildB:nWidth, oWndChildB:nHeight, .t. )}, ;
             oWorkB:refresh(.t.));
   VALID ( IIF( !lOKB, ExitPgmB(.T.,oWndChildB,oWndChildA,@lOkB ), .F. ))


RETURN( NIL )

//-----------------------------------------
Static FUNCTION ExitPgmB( lClean,oWndchildB,oWndChildA,lOkB)

IF lClean = .T.
   lOKB  := .T.

   oWndChildB:End()
   oWndChildA:Show()

ENDIF

RETURN( lOKB )

//--------------------------
Static Func _ReCalcTotals( xLabor,xParts,xMisc,xTax,xTotal,;
                           oLabor,oParts,oMisc,oTax,oTotal,oWorkB)

Local nStart,nTaxable,Saying

Saying := "In ReCalc"+chr(10)
Saying += " "+chr(10)
Saying += "xLabor before "+str(xLabor)+chr(10)
Saying += "xParts before "+str(xParts)+chr(10)
Saying += "xMisc  before "+str(xMisc)+chr(10)
Saying += "xTax   before "+str(xTax)+chr(10)
Saying += "xTotal before "+str(xTotal)+chr(10)

*MsgInfo( saying )

/*
xLabor   := 0.00
xParts   := 0.00
xMisc    := 0.00
xTax     := 0.00
xTotal   := 0.00
*/


xLabor := xLabor+10.00
xParts := xParts+5.00
xMisc  := 0
xTax   := round((xParts *.07),2)
xTotal := xLabor+xParts+xMisc+xTax

oParts:ReFresh()
oLabor:ReFresh()
oMisc:ReFresh()
oTax:ReFresh()
oTotal:ReFresh()

oWorkB:ReFresh()
SysReFresh()


Saying += "out ReCalc check screen"+chr(10)
Saying += " "+chr(10)
Saying += "xLabor after "+str(xLabor)+chr(10)
Saying += "xParts after "+str(xParts)+chr(10)
Saying += "xMisc  after "+str(xMisc)+chr(10)
Saying += "xTax   after "+str(xTax)+chr(10)
Saying += "xTotal after "+str(xTotal)+chr(10)

*MsgInfo( saying )

Return( .T. )

//--------------------
Static Func _InvtFind( oWndMain,oWndChildB,nRepairNumber,;
                       xLabor,xParts,xMisc,xTax,xTotal,;
                       oLabor,oParts,oMisc,oTax,oTotal,oWorkB)

Local oBtn1,oBtn2
Local Saying,xTitle

Local lokD
Local oInvt,oWndChildD

xParts := 10.00
xLabor := 10.00
xMisc  := 20.00
xTax   := 0

xTotal := 40.00

oParts:ReFresh()
oLabor:ReFresh()
oMisc:ReFresh()
oTax:ReFresh()
oTotal:ReFresh()


SysReFresh()

Saying := "Check page totals"+chr(10)
Saying += "xParts "+str(xParts)+chr(10)
Saying += "xLabor "+str(xLabor)+chr(10)
Saying += "xMisc "+str(xMisc)+chr(10)
Saying += "xTax "+str(xTax)+chr(10)
Saying += "xTotal "+str(xTotal)+chr(10)

MsgInfo(Saying)

********oWndChildB:Hide()

lOkD   := .f.
xTitle := "Parts Selection Find Routine"

DEFINE WINDOW oWndChildD           ;
       FROM 0,20 to 39,120         ;
       MDICHILD                    ;
       OF oWndMain                 ;
       TITLE xTITLE

       DEFINE DIALOG oInvt RESOURCE "INVTFIND" of oWndChildD



       REDEFINE BTNBMP oBtn1 ID 161 PROMPT "Transfer" CENTER ;
                of oInvt 2007 ;
                ACTION ( _Transfer( oWndMain,oWndChildD,nRepairNumber,;
                          @xLabor,@xParts,@xMisc,@xTax,@xTotal,;
                          oLabor,oParts,oMisc,oTax,oTotal,oWorkB))

       REDEFINE BTNBMP oBtn2 ID 162 PROMPT "Close" CENTER ;
                of oInvt 2007 ;
                ACTION (oWndChildD:End())


       ACTIVATE DIALOG oInvt NOMODAL ;
                VALID(!GETKEYSTATE( 27 ))

ACTIVATE WINDOW oWndChildD ;
   ON INIT ( oInvt:Move( 0,0, oWndchildD:nWidth, oWndchildD:nHeight, .T. ), ;
           oWndChildD:bResized := {|| oInvt:SetSize( oWndChildD:nWidth, oWndChildD:nHeight, .t. ) }, ;
           oInvt:refresh(.t.));
   VALID ( IIF( !lOKD, ExitPgm3(.T.,oWndChildD,oWndChildB,@lOkD ), .F. ))


RETURN( nil )

//-------------------------------------------
Static FUNCTION ExitPgm3( lClean,oWndchildD,oWndChildB,lOkD )

// from inventoryfind

IF lClean = .T.

   lOKD := .T.

   oWndChildD:End()
   oWndChildB:Show()


ENDIF

RETURN( lOKD )

//--------------------------------------------
Static Func _Transfer( oWndMain,oWndChildD,nRepairNumber,;
            xLabor,xParts,xMisc,xTax,xTotal,;
            oLabor,oParts,oMisc,oTax,oTotal,oWorkB)

Local Saying

// problem is here .. these values are not updating

Saying := "In Transfer passed values"+chr(10)
Saying += "xLabor "+str(xLabor)+chr(10)
Saying += "xParts "+str(xParts)+chr(10)
Saying += "xMisc "+str(xMisc)+chr(10)
Saying += "xTax "+str(xTax)+chr(10)
Saying += "xTotal "+str(xTotal)+chr(10)

msginfo( Saying )

xLabor := 5.00
xParts := 50.00
xMisc  := 5.00
xTax   := 0
xTotal := 60.00

oLabor:ReFresh()
oParts:ReFresh()
oMisc:ReFresh()
oTax:ReFresh()
oTotal:ReFresh()

oWorkB:ReFresh()
SysReFresh()

Saying := "New Values Do not show up HERE"+chr(10)
Saying += "xLabor "+str(xLabor)+chr(10)
Saying += "xParts "+str(xParts)+chr(10)
Saying += "xMisc "+str(xMisc)+chr(10)
Saying += "xTax "+str(xTax)+chr(10)
Saying += "xTotal "+str(xTotal)+chr(10)

Msginfo( Saying )

Return(.t.)

// end
 


WorkBrow.Rc
Code: Select all  Expand view  RUN

WORKBROW DIALOG 12, 11, 629, 364
STYLE WS_CHILD
FONT 6, "MS Sans Serif"
{
 CONTROL "&Quit", 140, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 90, 19, 67, 47
 CONTROL "Create New Repair", 147, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 17, 20, 67, 47
 GROUPBOX "", 199, 8, 10, 164, 61, BS_GROUPBOX
}
 


WorkView.Rc

Code: Select all  Expand view  RUN

WORKVIEW DIALOG 12, 11, 618, 364
STYLE WS_CHILD
FONT 6, "MS Sans Serif"
{
 CONTROL "Close", 140, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 141, 86, 41, 48
 GROUPBOX "", 197, 81, 79, 117, 62, BS_GROUPBOX
 CONTROL "Lookup Parts", 147, "TBtnBmp", 32 | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 94, 87, 41, 48
 LTEXT "Parts", 169, 5, 274, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 170, 38, 273, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 LTEXT "Labor", 171, 5, 288, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 173, 38, 287, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 LTEXT "Misc", 174, 5, 302, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 175, 38, 301, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 LTEXT "Tax", 176, 5, 316, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 177, 38, 315, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 LTEXT "Total", 179, 5, 338, 30, 11, SS_NOPREFIX | WS_GROUP
 EDITTEXT 183, 38, 336, 44, 12, ES_RIGHT | ES_AUTOHSCROLL | NOT WS_TABSTOP | WS_BORDER
 GROUPBOX "", 200, 1, 189, 85, 163, BS_GROUPBOX
 LTEXT "-------------------------------------------------", 185, 5, 327, 77, 6, SS_NOPREFIX | WS_GROUP
}
 
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions

Postby nageswaragunupudi » Thu May 24, 2012 5:21 pm

There is no limit to the number of levels.
I slightly modified your first program to demonstrate this.
Code: Select all  Expand view  RUN
#include "fivewin.ch"

function Main()

   local xTotal, oTotal, oDlg

   xTotal := 10.00

   DEFINE DIALOG oDlg

   @ 10,10 GET oTotal VAR xTotal SIZE 40,12 PIXEL OF oDlg PICTURE "99999" READONLY UPDATE

   @ 40,10 BUTTON "Change" SIZE 40,12 PIXEL OF oDlg ;
      ACTION ( Level1( @xTotal, oTotal ), oTotal:Refresh() )


   ACTIVATE DIALOG oDlg CENTERED

return nil


//-------------------
Static Func Level1( xtotal, oTotal )

   // xTotal is local to this function

   xTotal := 20.00
   oTotal:Refresh()
   msginfo( xtotal, "Level1" )
   Level2( @xTotal,oTotal )
   oTotal:Refresh()
   msginfo( xtotal, "Level1" )

Return(nil)

//-----------------
Static Func Level2( xTotal,oTotal )

   xTotal := 30.00
   oTotal:Refresh()
   msginfo( xtotal, "Level2" )
   Level3( @xTotal,oTotal )
   oTotal:Refresh()
   msginfo( xtotal, "Level2" )

Return(nil)

//------------------
Static Func Level3( xTotal ,oTotal)

   xTotal := 40.00
   oTotal:Refresh()
   msginfo( xtotal, "Level3" )

Return(nil)
 
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10690
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Passing variables by reference in nested functions

Postby Rick Lipkin » Thu May 24, 2012 5:36 pm

Rao

I am guessing my problem seems to have something to do with the base form being in focus .. I can see that the values are being updated, but when I refresh the ovariable the base form is not updated .. perhaps since it is out of focus ??

However, if I use statics without passing them as parameters .. I have no problems seeing the updated values to my base form... which is why I am at a loss.

Please take a quick look at my example with the above forms and see what you think.

Thanks
Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions

Postby Rick Lipkin » Thu May 24, 2012 8:22 pm

Rao

I compiled your example .. and it worked in a modal environment .. non-modal adds a level of complexity where you have to trigger a variable refresh on a valid close passing the parameters off to yet another function that closes your mdi children ..

I am at the point where I am very frustrated and I must have a mental block here .. Please copy and paste my previous example and tell me what in the world I am doing wrong. I don't mind eating 'crow' :)

Thanks
Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions

Postby Rick Lipkin » Thu May 24, 2012 10:11 pm

FYI

I just re-compiled the above program with the fwh debug option and walked the program through line by line and it appears that when you get to Transfer function .. the debugger does jump back to the objects where they were created .. but for some reason, the values are not updating ..

Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions

Postby Antonio Linares » Fri May 25, 2012 7:01 pm

Rick,

Please comment out all calls to SysRefresh() and try it again. I guess that your app is allowing the process of pending msgs and those msgs are invoking those functions agaian thus modifying those variables values.

Also, you say that you are using NON MODAL execution. Keep in mind that if you go out of the scope of a function then the original local varaible get destroyed and just their copy inside codeblocks (if any) remain alive. But they are not the original ones, they get converted into copies. i.e.:

function test()

local var

...

ACTIVATE DIALOG oDlg NOWAIT

return nil

Execution does not wait in the above ACTIVATE command, so once return nil is processed, var gets destroyed, unless it is copied into a codeblock. But such copy is not the original variable:

ACTIVATE DIALOG oDlg NOWAIT VALID ( var == ... )

as local var no longer exists.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42203
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Passing variables by reference in nested functions

Postby Rick Lipkin » Fri May 25, 2012 8:06 pm

Antonio

I am trying to grasp what you are saying .. it seems the problem is not so much the value of var but the refresh of the object associated with the var??. I do not necessarily understand the connection to the object and the var .. and perhaps what you are saying since the value of the var has gone out of scope .. the refresh to the object is nil ??

I can not use statics because this program must be able to open the same module twice .. granted I thought statics would be limited in value to the memory stack or the instance in which they were initialized. This does not seem to be so. If I open two instances of the same module when the _Recalc fires, it updates the second instance with the updated values.. which was VERY unexpected... so that is why I have to keep all my variables local in declaration.

It appears removing the SysRefresh()'s had no effect :( .. Tell me more about the codeblocks .. would eval( codeblock ) be one way to accomplish what I am trying to do ??

Any other possible work around ?

Thanks
Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions (solved)

Postby Rick Lipkin » Mon May 28, 2012 5:49 pm

To All

Here is the answer when anyone is dealing with passing vars and objects as parameters nested several functions deep that are tied back to Gets on a form you wish to update.

As Antonio pointed out ..
Keep in mind that if you go out of the scope of a function then the original local varaible get destroyed and just their copy inside codeblocks (if any) remain alive. But they are not the original ones, they get converted into copies. i.e.:

function test()

local var

...

ACTIVATE DIALOG oDlg NOWAIT

return nil

Execution does not wait in the above ACTIVATE command, so once return nil is processed, var gets destroyed, unless it is copied into a codeblock. But such copy is not the original variable:

ACTIVATE DIALOG oDlg NOWAIT VALID ( var == ... )

as local var no longer exists.



Rao has helped me and instead of passing the vars .. just pass the objects and then 'stuff' the objects with the values I wish to update on my form as in this example:

Code: Select all  Expand view  RUN

xLabor      := oLabor:VarGet()
xParts      := oParts:VarGet()
xMisc       := oMisc:VarGet()
xTax        := oTax:VarGet()
xTotal      := oTotal:VarGet()

// any code to manipulate the values

xLabor := 5.00
xParts := 50.00
xMisc  := 5.00
xTax   := 0
xTotal := 60.00

oLabor:cText   := xLabor
oParts:cText   := xParts
oMisc:cText    := xMisc
oTax:cText     := xTax
oTotal:cText   := xTotal
 


With this logic you do not need to know the original var just the object and send the value you wish back to the object and the form is correctly updated.

Again .. many thanks to Rao on this solution!

Rick Lipkin
User avatar
Rick Lipkin
 
Posts: 2666
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: Passing variables by reference in nested functions

Postby Antonio Linares » Mon May 28, 2012 6:51 pm

Rick,

Very good :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42203
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 16 guests