Announcement

Collapse
No announcement yet.

Using Functions in PBCC4

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

  • Michael Mattias
    replied
    I have in the past found that I left click just before the first character on the first line of the code and then drag the mouse to the end of the code so it is all highlighted.
    I am generally not this effusive about software I find here, , but Adam Drake's clipboard-listener/forum source code copy utility is really, really well thought out and absolutely the easiest way to copy code from here.

    Not only does it work with IE6 (which does not support the 'easy select of a section' as does IE7), but if it's one of those posts with multiple messages (eg, a 'main', an 'include' a 'resource script' and a "binbas program to create an icon"), you get ALL the code blocks - from all posts of the thread! - with one simple "select all, copy", and each code block is then separately-pastable into a fresh source code file in the PB IDE (and other IDE/editors, too).

    PB/Win Source here:
    http://www.powerbasic.com/support/pb...ad.php?t=35818

    This one would really nice to compile and make available as 'exe' for PB/CC users.
    Last edited by Michael Mattias; 1 Jan 2008, 11:20 AM.

    Leave a comment:


  • Warren Sugden
    replied
    Using Functions and Subs in PBCC

    Joe Byrne and Mike Doty

    Thank you both. I now have a much clearing understanding of the processes.

    Mike, as to copying code I note your comments. I have in the past found that I left click just before the first character on the first line of the code and then drag the mouse to the end of the code so it is all highlighted. I then do a CTRL+C to copy, open a new file in PBCC4, delete all the default lines (if not required), do a CRTL+V to copy the code into the file and the program is ready to run.

    Leave a comment:


  • Mike Doty
    replied
    Code:
    REM See CALL statement in help file
    #DIM ALL
    #COMPILE EXE
    SUB Test1(BYREF Parameter AS LONG)   'BYREF (the default) returns values
        Parameter = 99
    END SUB
     
    SUB Test2(BYVAL Parameter AS LONG)   'BYVAL does not return valuess
        Parameter = 100
    END SUB
     
    FUNCTION PBMAIN AS LONG
      LOCAL dummy AS LONG
     
      dummy = 1
      Test1 dummy     'returns 99
      ? STR$(dummy)  
     
      dummy = 1
      Test2 dummy     'returns no value, dummy remains 1
      ? STR$(dummy)  
     
      SLEEP 3000
    END FUNCTION
    Last edited by Mike Doty; 29 Dec 2007, 02:51 AM.

    Leave a comment:


  • Joe Byrne
    replied
    Warren,

    Ok, let me see if I can explain this more clearly.

    When writing a Windows program, everything is either a SUB or a FUNCTION. The only exception to this is some general initialization commands that you need prior to the MAIN SUB or FUNCTION executing. These initializations include things like DECLARE statements, Compiler directives (#COMPILE EXE or #COMPILE DLL, etc), setting the scope of various variables such as GLOBAL variables, and some other things as needed.

    A FUNCTION returns a value to your calling code.

    * i.e.: a$ = UsersEnteredName

    In this case, code in the FUNCTION UsersEnteredName gets user input and returns that user input to your program which you save in variable A$

    Since a FUNCTION returns a value, you must tell the compiler what type of data the FUNCTION will be returning (be it a string, long, integer, etc)

    A SUB does not return a value to your calling code.

    Otherwise, they are (for all practical purposes) the same.

    The main purpose of SUBs and FUNCTIONs is to create 'blocks' of code that is used more than once. It can also be useful to make code easier to read and modify.

    Both SUBs and FUNCTIONs can have parameters passed to them. These parameters can be variables or constants. Each parameter must specify the TYPE of data it contains (strings, longs, integers, etc). There are two ways you can pass variables as parameters; By value (BYVAL) or By Reference (BYREF). By Reference is the default.

    IF you pass variable parameters BYREF, the values of those variable can/will be changed in the FUNCTION. If the variables are passed BYVAL, their values will not be changed upon returning from a FUNCTION.

    For example:
    Code:
    #COMPILE EXE
    
    FUNCTION MyFunction1(BYVAL var1 AS STRING, BYVAL var2 AS LONG) AS STRING
         var1$ = "Is Changed"
         var2& = -99
         FUNCTION = "Function-1"
    END FUNCTION
    
    
    FUNCTION MyFunction2(BYREF var1 AS STRING, BYREF var2 AS LONG) AS STRING
         var1$ = "Is Changed"
         var2& = -99
         FUNCTION = "Function-2"
    END FUNCTION
    
    
    FUNCTION MyFunction3(var1 AS STRING, var2 AS LONG) AS STRING
         var1$ = "Is Changed"
         var2& = -99
         FUNCTION = "Function-3"
    END FUNCTION
    
    
    FUNCTION PBMAIN() AS LONG
    
    100   var1$ = "No Change": var2& = 99
            A$ = MyFunction1(var1$, var2&)
            PRINT "BYVAL: A$= "; a$,"var1: ";var1$,"var2:";STR$(var2&)
         
    200   var1$ = "No Change": var2& = 99
            A$ = MyFunction2(var1$, var2&)
            PRINT "BYREF: A$= "; a$,"var1: ";var1$,"var2:";STR$(var2&)
         
            PRINT ""  'for clarity
    
    300  var1$ = "No Change": var2& = 99
           A$ = MyFunction3(var1$, var2&)
           PRINT "DEFAULT: A$= "; a$,"var1: ";var1$,"var2:";STR$(var2&)
         
         waitkey$
    END FUNCTION
    There are three functions, MyFunction1, MyFunction2, and MyFunction3. They all return a STRING value regardless of what the parameters passed to them are. In MyFunction1, the two parameters passed are var1$ and var2& and they are passed by value. As you can see, after returning from the FUNCTION call in block 100, the values of var1$ and var2& have not changed. However, after the calls in blocks 200 and 300, the values of these variables have been changed by the FUNCTION.

    In both cases however, the value returned BY THE FUNCTION itself is not dependent on any of the parameters. In other words, A$ in all 3 calls returns whatever value FUNCTION = is set to inside the corresponding FUNCTION block.

    All variables used INSIDE a SUB or FUNCTION, except those passed as parameters BYREF, are local only to that SUB or FUNCTION. In other words, I could use the variable A$ inside any/all of the three functions above without ever effecting the value of A$ outside the FUNCTION. The only time this is not true is when you specifically declare a variable as GLOBAL. GLOBAL variables (can/will) change their value anyplace within your program.

    There are a couple of "rules" I tend to follow when writing my code. Most of it is out of habit, but as Michael said, I try to do things with the most likelihood of having "proper syntax" in the future.
    • Always DECLARE every SUB and FUNCTION before using it (even though I didn't do this above to show that you don't need to DECLARE everything IF you have the actual SUB/FUNCTION before its used in your program). However, I normally put all my DECLARE statements in a separate file then use: #INCLUDE "declares.inc" in the top of my main program. (where "declares.inc" is the file name I used)
    • Always use AS {TYPE} when declaring variables in SUBs and FUNCTIONs, including the FUNCTION name: ie: FUNCTION MyFunction (var1 AS STRING, var2 AS LONG) AS STRING. It really doesn't take long to get used to this.
    • Always set the FUNCTION = value just prior to ending the function, even if there is no return value.
    • Use a SUB unless a specific return value is needed.

    Personally, I prefer to use variable type identifiers as I go (a$, var2&, etc) although others suggest using DIM ALL. With DIM ALL, you must pre-define all of your variables with DIM, LOCAL, STATIC or GLOBAL before you can use them. In this case, the type identifier is not necessary since the compiler already knows what type of data each variable is to have. I find DIM ALL to be overly burdensome, but others prefer the advantage of catching typo's by enforcing the DIM ALL command.

    I hope this is helpful. It sounds to me like you've got the basic idea of SUBs and FUNCTIONs down now. Again, I'd take a little time and read over the programming concepts section in the PB help file. There is a lot of good stuff in there that will help you get over the hump a lot easier.
    Last edited by Joe Byrne; 29 Dec 2007, 02:19 AM.

    Leave a comment:


  • Mike Doty
    replied
    Actually, I wrote it.

    Leave a comment:


  • Warren Sugden
    replied
    Using Functions and Subs in PBCC

    Mike Doty and Joe Byrne

    Thanks for your help. Joe, I will study your 'InputCC.bas'.

    I've made up a set of rules which I will keep by me when writing this type of program. They are:

    1) Function Names DO NOT have type specifiers, although parameters in the Function can, but FUNCTIONS must have AS TYPE ???? definition.
    Sub Names CANNOT have type specifiers NOR do they have AS TYPE ????, although parameters in SUBS can have Type Specifiers OR AS TYPE ???
    2) Functions must go before PBMAIN OR if after, must include DECLARE Function cc4Input (mode AS STRING) AS STRING before PBMain
    OR Declare FUNCTION cc4Input (mode$) AS STRING before PBMain
    SUBs can be placed before or after PBMain and DO NOT require DECLARE statements either way.
    3) Function headed and named as FUNCTION cc4Input (mode AS STRING) AS STRING
    OR FUNCTION cc4Input (mode$) AS STRING
    SUB headed and named as SUB cc4Input (mode AS STRING)
    OR SUB cc4Input (mode$)
    4) Function value returned with cc4Input = gg$ (OR Function = gg$) as last line (or near)to provide RETURN value
    NOTE : no brackets or parameters
    Subs do not return values
    SUBs are accessed by ; CALL cc4Input(gg,mode)
    OR CALL cc4Input(gg$,mode$)
    Note : no AS TYPE ???? declarations
    5) parameters in FUNCTIONS abd SUBs if NOT Type specified MUST be DIMensioned within PBMAin
    DIM Mode AS STRING within PBMain. (also DIM gg as string in SUB)
    DIM statement NOT required in PBMain if Mode$ includes type specifier, but is legitimate. DIM mode$ in PBMain is legitimate but NOT required.

    If you see any problem with these, let me know.

    Leave a comment:


  • Mike Doty
    replied
    Formatted input routine

    Here is a formatted input SUB you might find useful:
    http://www.powerbasic.com/support/pb...ad.php?t=24503

    Leave a comment:


  • Joe Byrne
    replied
    Warren,

    SUB and FUNCTIONS are similar, but not equal.

    A FUNCTION returns a value (usually) where a SUB does not. Therefore, when you declare a FUNCTION you need to tell the compiler what format the FUNCTION will return (String, Long, Integer, etc). Therefore the declare looks like this:

    DECLARE FUNCNAME(parameter1 as string) AS TYPE (where type is the 'kind' of value you want returned.)

    A SUB does not return a value, therefore you don't specify a TYPE when its used. ie:

    DECLARE SUBNAME(parameter1 as string)

    Your "failure" is due to the fact that you've included the return type (AS STRING) to a SUB.

    There is an excellent section on SUBs and FUNCTIONs in the help documents, and since these are the building blocks of PB, I would highly recommend you (re)read those sections until you fully understand the use.

    --Joe

    Leave a comment:


  • Warren Sugden
    replied
    Using Functions in PBCC

    I have got the program running correctly using FUNCTION CC4Input, however if I rewrite the code using a SUB instead I find it fails at line 19 (indicated in the code at that location), otherwise it is the same.

    I have REM'd out the code relevent to FUNCTION and added corresponding code to suit SUB using the same 'rules' as worked with FUNCTION.

    The rules I have learnt from those posting replies and my own efforts are :
    1) Function Names DO NOT have type specifiers, although parameters in the Function can
    2) Functions must go before PBMAIN OR if after, must include
    DECLARE Function cc4Input (mode AS STRING) AS STRING before PBMain
    OR Declare FUNCTION cc4Input (mode$) AS STRING before PBMain
    3) Function headed and named as FUNCTION cc4Input (mode AS STRING) AS STRING
    OR FUNCTION cc4Input (mode$) AS STRING
    4) Function value returned with cc4Input = gg$ as last line (or near)to provide RETURN value
    NOTE : no brackets or parameters
    5) parameters NOT Type specified DIMensioned with DIM Mode AS STRING within PBMain
    DIM statement NOT required if Mode$ includes type specifier

    [Code]

    #COMPILE EXE

    '#INCLUDE "Win32API.inc"
    '#RESOURCE "Hello.pbr"
    '#DIM ALL

    'DECLARE FUNCTION cc4Input (mode$) AS STRING '+++++++
    DECLARE SUB cc4Input (gg AS STRING,mode AS STRING) AS STRING '+++++++
    '&&&& COMPILE FAIL on above LINE 19 &&&&&&&&&&&&&&&&&&&

    SUB cc4Input (gg AS STRING,mode AS STRING) AS STRING '++++++
    'FUNCTION cc4Input (mode$) AS STRING '++++++

    DO
    g$ = INKEY$
    IF LEN(g$) = 1 THEN

    IF ASC(g$) = 13 THEN
    EXIT DO
    ELSEIF Mode$ = "" AND (ASC (g$) < 32 OR ASC(g$) > 127) THEN
    g$ = ""
    ELSEIF Mode$ = "A" AND (ASC(g$) < 65 OR ASC(g$) > 122) THEN
    g$ = ""
    ELSEIF Mode$ = "N" AND (ASC(g$) < 48 OR ASC(g$) > 57) THEN
    g$ = ""
    ELSEIF Mode$ = "N." AND (ASC (g$)< 46 OR ASC(g$) > 57 OR ASC(g$) = 47) THEN
    g$ = ""
    ELSEIF Mode$ = "AN" AND (ASC (g$) < 46 OR ASC(g$) > 122 OR ASC(g$) = 47) THEN
    g$ =""
    END IF
    PRINT g$;
    gg = gg + g$ '++++++++++++
    ELSEIF LEN( g$ ) = 2 THEN
    k% = ASC(g$,2)
    IF k% = 59 THEN gg = "F1" '++++++++++++
    IF k% = 72 THEN gg = "Cursor UP" '++++++++++++
    EXIT DO
    END IF
    LOOP

    'cc4Input = gg$ '+++++++++++++

    'END FUNCTION '++++++++++++
    END SUB '+++++++++++

    FUNCTION PBMAIN () AS LONG

    'DIM Mode AS STRING ' - required if MODE does not include type specifier ie. Mode$
    'DIM gg AS STRING ' - required if gg does not include type specifier ie. gg$

    BLACK% = 0: BLUE% = 1: GREEN% = 2: CYAN% = 3: RED% = 4: MAGENTA% = 5: brown% = 6: WHITE% = 7
    grey% = 8: LBLUE% = 9: LGREEN% = 10: LCYAN% = 11: LRED% = 12: Lmagenta% = 13: yellow% = 14: brightwhite% = 15
    bright% = 8

    COLOR Yellow%,Magenta%

    NoBorderRows% = 23
    NoBorderColumns% = SCREENX - 3

    STDOUT CHR$(201);
    STDOUT STRING$(NoBorderColumns% ,CHR$(205));
    STDOUT CHR$(187)
    FOR y% = 1 TO NoBorderRows%
    STDOUT CHR$(186);
    STDOUT STRING$(NoBorderColumns%," ");
    STDOUT CHR$(186)
    NEXT
    STDOUT CHR$(200);
    STDOUT STRING$(NoBorderColumns%,CHR$(205));
    STDOUT CHR$(188);

    LOCATE 7,20
    STDOUT "Hello World ! ";

    LOCATE 9,12
    STDOUT " What is your first Name ? " ;

    'mode$ = "A" '++++++++++++++++
    mode = "A" '++++++++++++++++

    'YourName$ = cc4Input (mode$)
    CALL cc4Input (gg, mode) '++++++++++++++
    yourName$ = gg '++++++++++++++++

    LOCATE 12,12
    PRINT " You responded that your Name is : "; YourName$,gg

    CURSOR OFF
    WAITKEY$

    'END FUNCTION
    END SUB

    [\code]

    Leave a comment:


  • Michael Mattias
    replied
    >But they are not invalid. I use "ThisFunction$" style syntax all the time.

    FuncName The name of the Function. A type-specifier may be appended (just like an ordinary variable name) to specify the data type of the Function's return value, in place of the [AS type] clause.

    · Future versions of PowerBASIC may not support type-specifier symbols for the Function return type, so specify the return data type with an explicit AS type clause in all DECLARE and FUNCTION definitions, to ensure future compatibility.

    Leave a comment:


  • Eddy Van Esch
    replied
    Warren,

    Change
    Code:
         YourName$ = cc4Input$()
    
        LOCATE 12,12
        PRINT " You responded that your Name is : "; gg$
    into:
    Code:
         YourName$ = cc4Input$()
     
         LOCATE 12,12
         PRINT " You responded that your Name is : "; YourName$
    I would use #DIM ALL ...

    Kind regards

    Leave a comment:


  • Warren Sugden
    replied
    Using Functions in PBCC

    Thank you everyone

    I placed the CC4Input function BEFORE the PBMain and also removed the 'AS Public' and the program is now running EXCEPT that while it allows me to enter a name it does not print it out after the text string 'You have responded with the name". Nor is there a fail message, just no YourName$ printed as a response.

    I had added the 'As Public' hoping it would solve the problem, but it didn't.

    I'm finding the debugger is difficult to use. Certainly, not as easy or as convenient as PBDOS or VB5.

    Leave a comment:


  • Mel Bishop
    replied
    ...>>>function names don't (generally) use a type declaration such as CCInput$<<<...

    But they are not invalid. I use "ThisFunction$" style syntax all the time.

    ...>>>AS PUBLIC is not a valid PB function type<<<...

    In CC and PB/win. The PUBLIC verb is valid in PB/DOS which is where I think he is migrating from.

    (The rest deleted as being redundant)
    Last edited by Mel Bishop; 28 Dec 2007, 03:26 AM.

    Leave a comment:


  • Joe Byrne
    replied
    I get a 'Failure' at the line 'Function CCInput$() if I run the program in its present form. Why ???.
    First of all, 'Failure' is not a PB error message AFAIK. Giving the specific message makes a world of difference when asking for help.

    Second, function names don't (generally) use a type declaration such as CCInput$

    Third, AS PUBLIC is not a valid PB function type.

    Try this:
    Code:
    FUNCTION CCInput() as STRING
       mode$ = "A"
       DO
          g$ = INKEY$
          IF LEN(g$) = 1 THEN
             IF ASC(g$) = 13 THEN
             EXIT DO
          ELSEIF Mode$ = "" AND (ASC (g$) < 32 OR ASC(g$) > 127) THEN
             g$ = ""
          ELSEIF Mode$ = "A" AND (ASC(g$) < 65 OR ASC(g$) > 122) THEN
             g$ = ""
          ELSEIF Mode$ = "N" AND (ASC(g$) < 48 OR ASC(g$) > 57) THEN
             g$ = ""
          ELSEIF Mode$ = "N." AND (ASC (g$)< 46 OR ASC(g$) > 57 OR ASC(g$) =47) THEN
             g$ = ""
          ELSEIF Mode$ = "AN" AND (ASC (g$) < 46 OR ASC(g$) > 122 OR ASC(g$) = 47) THEN
             g$ =""
         END IF
         PRINT g$;
         gg$ = gg$ + g$
         
         IF LEN( g$ ) = 2 THEN
             k% = ASC(g$,2)
             IF k% = 59 THEN gg$ = "F1"
             IF k% = 72 THEN gg$ = "Cursor UP"
             EXIT DO
         END IF
       LOOP
       FUNCTION = gg$
    END FUNCTION
    Note: Before leaving the function, you need to set FUNCTION = <something> in order for the function to return a value. You could also use a SUB instead, and pass gg$ as a parameter: SUB CCInput(gg as string).

    If you use the FUNCTION, then you also need to declare it before you call it. Before the PBMAIN() function, add: DECLARE FUNCTION CCInput() AS STRING

    If you want to pass "MODE$" as a parameter, then use this instead:

    FUNCTION CCInput(mode AS STRING) AS STRING

    and change the declare to:

    FUNCTION CCInput(STRING) AS STRING

    and remove Mode$ = "a" in the CCInput FUNCTION
    Last edited by Joe Byrne; 28 Dec 2007, 02:41 AM.

    Leave a comment:


  • Edwin Knoppert
    replied
    First, i have never seen 'as public' ??

    I guess:

    FUNCTION cc4Input$()

    And also place it on top like:

    Declare FUNCTION cc4Input$()

    Leave a comment:


  • Jerry Fielden
    replied
    Try putting that function ahead of the Main function, or you can declare it.

    Leave a comment:


  • Warren Sugden
    started a topic Using Functions in PBCC4

    Using Functions in PBCC4

    I have written a short program, which includes a Function which in turn includes a DO LOOP.

    I get a 'Failure' at the line 'Function CCInput$() if I run the program in its present form. Why ???.

    If instead I place the DO LOOP with the PBMain Function, the program runs fine, but if it is its own Function (which I prefer) it FAILS.

    [Code]

    #COMPILE EXE

    '#INCLUDE "Win32API.inc"
    '#RESOURCE "Hello.pbr"
    '#DIM ALL

    FUNCTION PBMAIN () AS LONG

    BLACK% = 0: BLUE% = 1: GREEN% = 2: CYAN% = 3: RED% = 4: MAGENTA% = 5: brown% = 6: WHITE% = 7
    grey% = 8: LBLUE% = 9: LGREEN% = 10: LCYAN% = 11: LRED% = 12: Lmagenta% = 13: yellow% = 14: brightwhite% = 15
    bright% = 8

    xx% = SCREENX
    yy% = SCREENY

    COLOR Yellow%,Magenta%

    NoBorderRows% = 23
    NoBorderColumns% = SCREENX - 3

    'NoBorderRows% = 31
    'NoBorderColumns% = 51

    STDOUT CHR$(201);
    STDOUT STRING$(NoBorderColumns% ,CHR$(205));
    STDOUT CHR$(187)
    FOR y% = 1 TO NoBorderRows%
    STDOUT CHR$(186);
    STDOUT STRING$(NoBorderColumns%," ");
    STDOUT CHR$(186)
    NEXT
    STDOUT CHR$(200);
    STDOUT STRING$(NoBorderColumns%,CHR$(205));
    STDOUT CHR$(188);

    LOCATE 7,20
    'COLOR white%,Red%
    STDOUT "Hello World ! ";

    LOCATE 9,12
    STDOUT " What is your first Name ? " ;

    'mode$ = "A"
    'DO
    ' g$ = INKEY$
    ' IF LEN(g$) = 1 THEN
    ' IF ASC(g$) = 13 THEN
    ' EXIT DO
    ' ELSEIF Mode$ = "" AND (ASC (g$) < 32 OR ASC(g$) > 127) THEN
    ' g$ = ""
    ' ELSEIF Mode$ = "A" AND (ASC(g$) < 65 OR ASC(g$) > 122) THEN
    ' g$ = ""
    ' ELSEIF Mode$ = "N" AND (ASC(g$) < 48 OR ASC(g$) > 57) THEN
    ' g$ = ""
    ' ELSEIF Mode$ = "N." AND (ASC (g$)< 46 OR ASC(g$) > 57 OR ASC(g$) = 47) THEN
    ' g$ = ""
    ' ELSEIF Mode$ = "AN" AND (ASC (g$) < 46 OR ASC(g$) > 122 OR ASC(g$) = 47) THEN
    ' g$ =""
    ' END IF
    ' PRINT g$;
    ' gg$ = gg$ + g$
    ' ELSEIF LEN( g$ ) = 2 THEN
    ' k% = ASC(g$,2)
    ' IF k% = 59 THEN gg$ = "F1"
    ' IF k% = 72 THEN gg$ = "Cursor UP"
    ' EXIT DO
    ' END IF
    'LOOP

    YourName$ = cc4Input$()

    LOCATE 12,12
    PRINT " You responded that your Name is : "; gg$

    CURSOR OFF
    WAITKEY$

    END FUNCTION



    FUNCTION cc4Input$() AS public

    mode$ = "A"
    DO
    g$ = INKEY$
    IF LEN(g$) = 1 THEN
    IF ASC(g$) = 13 THEN
    EXIT DO
    ELSEIF Mode$ = "" AND (ASC (g$) < 32 OR ASC(g$) > 127) THEN
    g$ = ""
    ELSEIF Mode$ = "A" AND (ASC(g$) < 65 OR ASC(g$) > 122) THEN
    g$ = ""
    ELSEIF Mode$ = "N" AND (ASC(g$) < 48 OR ASC(g$) > 57) THEN
    g$ = ""
    ELSEIF Mode$ = "N." AND (ASC (g$)< 46 OR ASC(g$) > 57 OR ASC(g$) = 47) THEN
    g$ = ""
    ELSEIF Mode$ = "AN" AND (ASC (g$) < 46 OR ASC(g$) > 122 OR ASC(g$) = 47) THEN
    g$ =""
    END IF
    PRINT g$;
    gg$ = gg$ + g$
    ELSEIF LEN( g$ ) = 2 THEN
    k% = ASC(g$,2)
    IF k% = 59 THEN gg$ = "F1"
    IF k% = 72 THEN gg$ = "Cursor UP"
    EXIT DO
    END IF
    LOOP

    END FUNCTION


    [\code]
Working...
X