Announcement

Collapse
No announcement yet.

GLOBAL string array

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

  • GLOBAL string array

    Why is it this statment wont work:
    GLOBAL Test(100) as STRING

    But This Does:
    LOCAL Test(100) as STRING

    Thanks

  • #2
    Originally posted by Lynn Wakefield View Post
    Why is it this statment wont work:
    GLOBAL Test(100) as STRING

    But This Does:
    LOCAL Test(100) as STRING

    Thanks
    Actually, neither should work. You should get an ERROR# 414 when you try to compile either statement. When you define a variable as GLOBAL, LOCAL, or STATIC, you are simply creating it's scope not its size. You use the DIM or REDIM to define the size of the array.
    Software makes Hardware Happen

    Comment


    • #3
      According to the help file, neither should work; so you shouldn't use them since that is likely to get fixed in a future release.

      GLOBAL and LOCAL statements only tell the compiler about the variable: it's type (STRING, LONG, etc), scope (GLOBAL, LOCAL or STATIC), and if it's an array or a scalar (does/does not have a set of empty parentheses following).

      To actually assign a number of elements to an array variable, you execute a DIM or REDIM statement. I always use REDIM, since "DIM" can also be used in lieu of a simple LOCAL/GLOBAL/STATIC statement and I get confused.



      MCM
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        GLOBAL string array

        You are right dim Test(100) as string works in a function or sub but not GLOBAL, ?

        Comment


        • #5
          See Michael's explanation and read it carefully, it has the information needed.

          The point is that array memory is not allocated by a GLOBAL statement. GLOBAL in this instance just declares the global scope and type of the named array. You will need to DIM or better as MCM points out REDIM the actual elements to be allocated later.

          Your help file, under the topic GLOBAL, emphasis added, says:
          GLOBAL declares the specified variable(s) as global to the entire program. This gives a Sub or Function access to variable(s), without having to pass them as parameters. To declare an array as a global variable, use an empty set of parentheses in the variable list:
          GLOBAL MyArray%()
          GLOBAL StringArray() AS STRING
          You must then use the DIM or REDIM statements to dimension the array inside a Sub or Function. A good place to do this is inside your WINMAIN or PBMAIN function.
          If an array is defined as GLOBAL outside a Sub or Function, you should include the GLOBAL keyword in the DIM statement for clarity, and compatibility with future versions of PowerBASIC:
          GLOBAL a() AS STRING
          FUNCTION PBMAIN
          DIM a(1 TO 500) AS GLOBAL STRING
          ...
          END FUNCTION
          The GLOBAL statement may accept a list of variables, all of which are defined by the type descriptor keywords which follow them. For example:
          GLOBAL aaa, bbb, ccc AS INTEGER
          GLOBAL vptr, aptr() AS LONG PTR

          This subject is further discussed in another thread or two, some many moons past.
          Rick Angell

          Comment


          • #6
            GLOBAL string array

            Hey Richard, Thanks, I think that straightened me out on the subject.

            Comment


            • #7
              Hi,

              I have the variable problem and need your help:

              I have sub1 to list 9 variable V1, and sub2 to print 9 items arayV2(V1)

              I could independently run 2 subs as sub1 or sub2 OK, and it is OK to run sub1 then run sub2, finish to end program then rerun both sub1 and sub2 OK.
              But I could not run sub2 then sub1. I have all local variables:

              local v1 as integer 'and
              local arrayV2() as string
              ....
              DIM arrayV2(30) as string

              Example:
              When I finished sub 2 then I run sub1, I finally have had only 1 value v1=9 from sub2, but then program stopped on the next step.

              Should I use REDIM or Erase arrayV2(v1) or arrayV2()="" to allocatively clear memory ?
              http://www.lecan.net

              Comment


              • #8
                Can,

                You need to post your code since the description is a bit vague to simply guess at.

                In order to access a local array in a SUB where it is not being DIM's and filled, you need to pass the array as an argument to the SUB.

                Please provide a code listing that is complete enough so we can see what the code is attempting to do, then you should get some quick answers.
                Rick Angell

                Comment


                • #9
                  Thank Richard,

                  I understood that a sub won't pass value but a function does, in my case subAsBlock1 and subAsBlock2 without end sub, 1 and 2 are both in mainPB() function. I run OK from sub1 to sub2 but not from sub2 to sub1!
                  I am checking the close file# and try to REDIM and Erase() memory of string array or try not to reopen the same openning file.

                  Finally I got it works with the old arrayV2, because I open file a second time. Thank you.
                  Last edited by Can Le; 16 Feb 2008, 04:40 PM.
                  http://www.lecan.net

                  Comment


                  • #10
                    You need to post your code since the description is a bit vague to simply guess at
                    A bit??? After 3 reads, I still have no clue what you're talking about
                    Software makes Hardware Happen

                    Comment


                    • #11
                      Can,

                      " I understood that a sub won't pass value but a function does,"

                      A sub does not return a value like a function does. However parameters, sch as an array in this case, can be accessed BYREF (the default) so the values can be used and changed in the sub.

                      "I understood that a sub won't pass value but a function does, in my case subAsBlock1 and subAsBlock2 without end sub, 1 and 2 are both in mainPB() function. I run OK from sub1 to sub2 but not from sub2 to sub1!"

                      "mainPB()"? I believe you mean PBMain()

                      " Finally I got it works with the old arrayV2, because I open file a second time. Thank you."

                      You would benefit more by copying you code here between the code tags. Use the # button in the toolbar to have the forum program insert these tags. The paste your text between them. I suspect that you may have a sequence situation that has previously made the information available in one SUB, but not the other. See simplistic example, no file i/o, but but SUBs and GOSUBs

                      Code:
                      #COMPILE EXE
                      #DIM ALL
                      SUB PrintIt (thedata() AS STRING)
                          LOCAL i&
                          PRINT "PrintIt"
                          FOR i& = UBOUND(thedata) TO UBOUND(thedata)-5 STEP -1
                              PRINT  VAL(thedata(i&))*1000
                          NEXT
                      END SUB
                      
                      SUB ViewIt (thedata() AS STRING)
                          LOCAL i&
                          PRINT "ViewIt"
                          FOR i& = 1 TO 5
                              PRINT VAL(thedata(i&))*2000
                          NEXT
                      END SUB
                      
                      FUNCTION PBMAIN () AS LONG
                          LOCAL i&
                          
                          DIM srcdata( 1 TO 30) AS STRING
                          
                          FOR i& = 1 TO 30 : srcdata(i&) = FORMAT$(i&):NEXT
                          GOSUB ASUB1
                          PrintIt srcdata()
                          GOSUB ASUB2
                          ViewIt srcdata()
                          
                          WAITKEY$
                          EXIT FUNCTION
                          
                          ASUB1:
                              PRINT "ASUB1"
                              FOR i& = 1 TO 5 : PRINT VAL(srcdata(i&)) : NEXT
                          RETURN
                          
                          ASUB2:
                              PRINT "ASUB2"
                              FOR i& = 12 TO 17 : PRINT VAL(srcdata(i&))*10  : NEXT
                          RETURN
                      
                      END FUNCTION

                      Joe,
                      If at first you don't succeed ....(W.C. Fields version) ...Heh heh
                      Rick Angell

                      Comment


                      • #12
                        Thank Richard!

                        It is a long program,
                        first I had them in 2 subs then I put them in FUNCTION PBMAIN () AS LONG

                        From your example and my 2 blocks, It should works in 2 ways: A and B:
                        Way A is working fine:

                        1. I execute sub1 PrintIt (thedata() AS STRING) , then
                        2. I do the next sub2: ViewIt (thedata() AS STRING)

                        However, way B is not working when I executed them in reverse order:
                        1. sub 2 ViewIt (thedata() AS STRING), then
                        2. sub1 PrintIt (thedata() AS STRING)

                        If they are 2 subs then just CALL sub1 and CALL sub2, or CALL sub2 then CALL sub1!

                        The reason is window memory! So I used the old array thedata() to pass values as in return of a fiunction or REDIM.

                        I am looking for a way to print the whole array thedata() as in Perl, without using sub nor function and a loop! If PBCC has it, please show, if not then please update to beat Perl.

                        Thank you all
                        http://www.lecan.net

                        Comment


                        • #13
                          Can,

                          Please post your code. We see long code many times here. Maybe you only need to post the relevant code portions that show what is happening before and during the calls to your subs. You can also send the file with reference to this topic to [email protected]

                          However, it makes no difference in my code example as to the order that the program calls either SUB or GOSUB. Reverse the order in which called and they still do their jobs, period.

                          Therefore, IMO, you must have something in your program that is erasing the data before you intended it to be erased. And unless you are really short on memory, it is probably quite doubtful that that would be the problem. When memory is really too short, Windows will page to disk.

                          Arrays can be printed to a file in one step. PRINT #foo&, thedata()

                          However, PB is clear about printing to screen, in the PRINT statement help, under restrictions: " It is not possible to directly PRINT a Variant, Object Variable, or an entire array (i.e., PRINT MyArr#()). For arrays, use a FOR/NEXT loop to iterate through the individual elements."

                          That said, without knowing what kind of data is in your arrays it is hard to say whether you might be able to print an entire array without a loop.

                          For example, in a fixed length string array you can get a columnar listing by code like this:
                          Code:
                          SUB TestIt (thedata() AS STRING * 20)
                              LOCAL i&,b$
                              DIM a(0) AS STRING * 600 AT VARPTR(thedata(1))
                              PRINT "TestIt"
                              b$ = a(0)
                              STDOUT b$
                          END SUB
                          There may be some other avenues, but they would be limited. Using a loop with either PRINT or STDOUT is going to be prudent for most applications.
                          Rick Angell

                          Comment


                          • #14
                            am looking for a way to print the whole array thedata() as in Perl, without using sub nor function and a loop!
                            ???

                            You can just do it in-line, but you need a loop
                            Code:
                            FOR Z =LBOUND( TheData,1) TO UBOUND(TheData,1)
                              PRINT TheData(Z)
                            NEXT
                            If you have to do this many times, you can create a MACRO or SUB/FUNCTION and call that each time to cut down on typing. And when you create that function, the name of the array in the function header is just a placeholder... the same SUB or FUNCTION function can be used to print any string array ...
                            Code:
                            SUB PrintWholeArray (S() AS STRING) 
                            
                            LOCAL Z AS LONG
                            
                             FOR Z = LBOUND (S,1) TO UBOUND(S,1)
                                PRINT S(Z)
                             NEXT
                            END SUB
                            
                            ...
                               PrintWholeArray v1()    ' print all elements of string array V1
                               PrintWholeArray v2()    ' print all elements of string array V2
                            ...
                            MCM
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              ActuallY, now the coffee has had time to work, here's an easy way to print a string array:

                              STDOUT JOIN$(thedata(),$CRLF)

                              Try this in the code:
                              Code:
                              SUB PrintIt (thedata() AS STRING)
                                  STDOUT JOIN$(thedata(),$CRLF)
                              END SUB
                              Make it a macro if needs be
                              MACRO PrintArray(arryname) : STDOUT JOIN$(arryname(),$CRLF)
                              or just use as it is, a single line in the main code.
                              Last edited by Richard Angell; 19 Feb 2008, 01:11 PM. Reason: Added:
                              Rick Angell

                              Comment


                              • #16
                                GLOBAL string array

                                Thanks all, I understand it now, Lynn

                                Comment

                                Working...
                                X