BASIC Programmers


FINALLY!   MapObjects and VB

VISUAL BASIC -- The Beginnings



PROBLEM #4 -- SUB-ROUTINES

Here we revisit the Aquarium membership problem with a more compact and "elegant" solution to the problem. In several parts of our original solution, we needed to re-initialize the MembershipCount by MembershipType ARRAY .. and we also wrote out the compiled array in a two or more places.

In this solution, we employ the powerful feature of all modern programming languages -- The SUBROUTINE.  Subroutines or sub-programs are smaller, separate, mini-programs which do special tasks. Often these tasks are needed in different parts of the MAIN PROGRAM or even in different programs (re-usable code).

Visual Basic will rely entirely on subroutines -- we will only write subroutines, the "main program" is generated by the "visual" part -- the Graphical User Interface we build with the visual tools. Actual "work" is done in subroutines .. the parts that we write.

We need to look more carefully at our VARIABLES and decide which will be "local" to a subroutine and which need to be "global" or SHARED.  SHARED variables (declared in the DIM statement) will have their current values known to all subroutines at the same time. Local variables are used within subroutines and do not affect other parts of the program.

Local variables are sometimes "passed" to another subroutine to be used by that program.  This is similar to the "functions" we have used already such as:
 

ITYPE = INT(MTYPE)   .. where INT( ** ) is the function [which returns the integer value of a real number, either single or double] and MTYPE is the "argument" or variable passed to the function.
In this version of our program, we will use both SHARED variables and local variables passed to the subroutine.

Notice that the Main Program is first (in VB, we never see the "main program per se") and all the SUBroutines follow.  We can edit them without changing anything in the Main Program -- VB is based on this principle, you edit your SUBroutines and leave the main program alone.

I think the "logic" of solving the membership types by zipcode problem described last week will be clearer with the use of subroutines -- you can see the program in its logical whole easier as much of the "work" is done in the subroutines.

STUDY the program and see if you understand the ways it works. The new program has been added to the ZIP and ready for download.

'-------------------------------------------------------
DECLARE SUB ADDMEMS (MTEMP AS SINGLE, NTEMP AS INTEGER)
DECLARE SUB INITNEW ()
DECLARE SUB MEMDUMP ()

OPTION BASE 1

DIM SHARED MEMTYP(5)  AS SINGLE   'ARRAY OF MEMBERSHIP TYPE COUNTS BY ZIPCODE
DIM SHARED ZIPCODE AS STRING    'ZIPCODE NUMBER AS A CHARACTER STRING
'---------------------------------------------------------
DIM MTEMP AS SINGLE      'TEMPORARY MEMBERSHIP TYPE
DIM ZTEMP AS STRING      'TEMPORARY ZIPCODE
DIM NTEMP AS INTEGER     'TEMPORARY MEMBERSHIP COUNT BY TYPE
DIM FIRST AS INTEGER     'CONTROL OF OUTPUT VARIABLE

' OPEN DISKFILES

OPEN "ZIP_RAW.TXT" FOR INPUT AS #1
OPEN "Z_TEMP.TXT" FOR OUTPUT AS #2

CLS   'CLEAR THE SCREEN
'-------------------------------------------------
' Initialize ZipCode Value and MemTyp Array Prior to Input
   ZIPCODE = "00000"
   FIRST = 1
   CALL INITNEW

' BEGIN DATA INPUT FROM DISKFILE IN ORIGINAL FORMAT
'      ZIPCODE, MemberType, MemberCount

WHILE NOT EOF(1)

  INPUT #1, ZTEMP, MTEMP, NTEMP
    'PRINT ZTEMP, MTEMP, NTEMP  'DEBUG TEMP PRINT --DELETE LATER

    IF ZTEMP <> ZIPCODE THEN  'NEW ZIP CODE

      IF FIRST THEN 'FIRST TIME THRU THE PROCESS -- SAVE INFO ONLY
        ZIPCODE = ZTEMP
        CALL ADDMEMS(MTEMP, NTEMP)
        FIRST = 0
      ELSE 'NEW ZIPCODE ENCOUNTERED, DUMP OLD ZIP MEMBERSHIP INFO
        CALL MEMDUMP
        ZIPCODE = ZTEMP
        CALL INITNEW
        CALL ADDMEMS(MTEMP, NTEMP)
      END IF

    ELSE ' SAME ZIP AS LAST RECORD, ADD INFOMATION TO MEMBERSHIP ARRAY

       CALL ADDMEMS(MTEMP, NTEMP)

    END IF

     ' INPUT KY$ ' DEBUG KEY INPUT -- DELETE LATER

WEND

'END OF INPUT FILE ENCOUNTERED --

     CALL MEMDUMP ' WRITE LAST ZIPCODE'S INFO TO FILE

CLOSE  'ALL FILES
END
 

SUB ADDMEMS (MTEMP AS SINGLE, NTEMP AS INTEGER)
DIM I, J AS INTEGER

  I = INT(MTEMP)
  MEMTYP(I) = NTEMP

END SUB

SUB INITNEW
  DIM I AS INTEGER
    FOR I = 1 TO 5
       MEMTYP(I) = 0
    NEXT I
END SUB

SUB MEMDUMP

  PRINT ZIPCODE, MEMTYP(1); MEMTYP(2); MEMTYP(3); MEMTYP(4); MEMTYP(5)

 'WRITE #2, ZIPCODE, MEMTYP(1), MEMTYP(2), MEMTYP(3), MEMTYP(4), MEMTYP(5)

END SUB
 
 
 

Problem #3: -- REAL WORK

Here is a real problem we encountered last week as part of the Austria-Exchange project with the Aquarium.  We needed to get counts of Membership Types (collapsed into 5 classes) into a Single Table with ZipCode as the Primary Key in order to make a Pie-Chart Map of Membership Types by ZipCode area.

Woody and Suzanne were able to summarize the membership types by ZipCode, but only to the extent that an ACCESS (database) table was produced that logically looked like this:
 

ZIPCODE | MEMCLASS | SUM
No one could figure out how to get ACCESS or ARCVIEW to reformat the table into a single row (record) with Zipcode and then the numbers of members in EACH CLASS.  So we exported the table into Comma-Delimited ASCII (text).

A portion of the "raw data" looks like this:

"90071",1.00,1
"90071",3.00,1
"90075",2.00,1
"90075",3.00,1
"90077",1.00,3
"90077",2.00,5
"90077",3.00,20
"90077",4.00,5
"90077",5.00,6
"90081",4.00,2
"90086",2.00,1
"90086",4.00,1
"90089",4.00,1
"90201",1.00,1
"90201",2.00,3
"90201",3.00,16
"90201",4.00,2
"90202",3.00,1
"90209",4.00,1
"90210",1.00,8
"90210",2.00,2
"90210",3.00,25
"90210",4.00,7
"90210",5.00,3


Getting the data into an text file allowed me to write a short program to read the data and output into the desired format, which logically looks like this:
 

ZIPCODE | TYPE1 | TYPE2 | TYPE3 | TYPE4 | TYPE5
A portion of the output, corresponding to the data sample above, is show here:
"90071",1,0,1,0,0
"90075",0,1,1,0,0
"90077",3,5,20,5,6
"90081",0,0,0,2,0
"90086",0,1,0,1,0
"90089",0,0,0,1,0
"90201",1,3,16,2,0
"90202",0,0,1,0,0
"90209",0,0,0,1,0
"90210",8,2,25,7,3
The complete data file (exported from ACCESS) [Z_mc_cnt.txt], the "edited Input File" [z_in.txt] cleaned up and ready to run, and the BASIC program [zip_bas.txt] are all found in this file zipcodes.zip -- available for your download.
 

The BASIC program contains a number of "tricks" which make the conversion pretty simple -- once you understand the underlying logic. STUDY this program. Not for its elegance, but for an example of how to work through the knarly logic necessary to solve the problem.

Try writing your own version. Viele Gluck.
 

#2







#1