Announcement

Collapse
No announcement yet.

Loading data into Globals

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Loading data into Globals

    There's a very good chance I'm over thinking this, but here it is. I'm moving a segment of code that loads data records from the database into a data structure into it's own include file. Splitting it out because I now have more than one program that needs to so work with this data. The program that originally used this logic put the data into global variables. The new programs will not; the data will be local to the function using it.

    Here's the over-thinking part: it just feels like I should not be passing the global variables as parameters to the load function. Sample code below, not the most beautiful code, but I think it shows my point. For some reason, option 2 seems more correct, but I can't really say why. Hoping to benefit from others experience.

    Code:
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE "windows.inc"
    
    TYPE MyheaderType
      Element1 AS LONG
      element2 AS LONG
    END TYPE
    
    TYPE MyDetailtype
      idx     AS LONG
      Squared AS QUAD
    END TYPE
    
    GLOBAL  gHeaderData          AS MyHeaderType
    GLOBAL  gDetailData()        AS MyDetailType
    GLOBAL gCS                   AS Critical_Section
    
    FUNCTION PBMAIN () AS LONG
    
      LOCAL Success           AS LONG
      LOCAL xLoop             AS LONG
      
      LOCAL lHeaderData       AS MyHeaderType
      LOCAL lDetailData()     AS MyDetailType
    
      REDIM lDetailData(0 TO 0)
      REDIM gDetailData(0 TO 0)
    
      ' Option 1
      Success = LoadData(gheaderData, gDetailData())
      IF ISTRUE(Success) THEN
        ? "loaded!"
      ELSE
        ? "Epic failure!"
      END IF
    
      ' option 2
      Success = LoadData(lHeaderData, lDetailData())
      IF ISTRUE(Success) THEN
        EnterCriticalSection gCS
        gHeaderData = lHeaderData
        REDIM gDetailData(1 TO UBOUND(lDetailData))
        FOR xLoop = 1 TO UBOUND(lDetailData)
          gDetailData(xLoop) = lDetailData(xLoop)
        NEXT xLoop
        LeaveCriticalSection gCS
        ? "loaded!"
      ELSE
        ? "Epic failure!"
      END IF
    
    
    END FUNCTION
    
    FUNCTION LoadData(DataHeader AS MyheaderType, DataDetail() AS myDetailType) AS LONG
    
      LOCAL xLoop      AS LONG
    
    ' get header data
      DataHeader.Element1 = 1
      DataHeader.Element2 = 2
    
    ' Load details
      REDIM DataDetail(1 TO 10)
      FOR xLoop = 1 TO 10
        DataDetail(xLoop).idx = xLoop
        DataDetail(xLoop).Squared = (xLoop ^ 2)
      NEXT xLoop
    
      FUNCTION = 1
    
    END FUNCTION​
    Last edited by Bud Durland; 16 May 2023, 03:51 PM. Reason: Edit: typos.
    Real programmers use a magnetized needle and a steady hand

  • #2
    1. To pass values, If you are not going to alter the variable, you may use the BYVAL or BYCOPY options.

    2. Why load up the header and ALL the lines? You can do each line as needed by putting in a FETCH loop.

    3. Number of lines = SELECT COUNT (*) FROM tablename WHERE orderNumber = Header.OrderNumber. You can then presize any PB array needed which will be much more efficient than REDIM PRESERVE for each line or even every "n" lines. Not the case here, but a reminder for lurkers,
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Here's the over-thinking part: it just feels like I should not be passing the global variables as parameters to the load functio
      No reason not to. But if you are going to pass it, why make it GLOBAL? Just define/declare it in some procedure and pass it as a param to all procedures further down the call chain. That's what I do.
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        Originally posted by Michael Mattias View Post
        1. To pass values, If you are not going to alter the variable, you may use the BYVAL or BYCOPY options.
        I realize that, but I need the data back to the caller. I'm sorry, I thought I mentioned that the purpose of the function is fetch data from the database and load it into variables.

        2. Why load up the header and ALL the lines? You can do each line as needed by putting in a FETCH loop.
        Because I need them all in memory at once to perform certain data manipulations

        3. Number of lines = SELECT COUNT (*) FROM tablename WHERE orderNumber = Header.OrderNumber. You can then presize any PB array needed which will be much more efficient than REDIM PRESERVE for each line or even every "n" lines. Not the case here, but a reminder for lurkers,
        Exactly what I'm doing in the real code (well, close enough, thanks to Eric Pearson and SQL_ResultRowCount() in SQL Tools) but I didn't think it was relevant to the core question of whether there is some subtle issue with passing the globals directly to the function. Depending on the program that is using this function, the variables used by the program may be globals, or they may be local to the calling procedure. Should I, when the program is using globals, use Option 2 to load the data, or is just passing the global var BYREF ok?
        Last edited by Bud Durland; 16 May 2023, 06:18 PM. Reason: typos
        Real programmers use a magnetized needle and a steady hand

        Comment


        • #5
          Originally posted by Bud Durland View Post
          . Should I, when the program is using globals, use Option 2 to load the data, or is just passing the global var BYREF ok?
          Perfectly OK to pass the global array BYREF. To do otherwise is just additonal work for no benefit.
          If you want to fill a global array, pass it - if you want to fill an array that is local to the calling function, just pass that.

          Comment


          • #6
            Originally posted by Stuart McLachlan View Post
            Perfectly OK to pass the global array BYREF.
            That's the question I had. Thanks for the input.
            Real programmers use a magnetized needle and a steady hand

            Comment

            Working...
            X