Continuation: Sequential File to Array.  How to jump to another array

shrimpman77
shrimpman77 used Ask the Experts™
on
'twalgrave or anyone, this is a continuation of another post with a new set of points.  Thanks.
'The sequential file below have been converted into ONE big array ( consisting of four columns) using a Private Type statement.

1, homer, 1, 2
1, bart, 1, 2
2, marge, 3, 3
2, maggie, 3, 3
4, lisa, 2, 4

First column is the flight # (1 – 4)
Second column is the person's name.
Third column is the different Class # (1 – 3)
         If I chose class 1, there will be 2 seat available
    ***If I chose class 2, then the person must switch to a secondary airplane to get 4 available seats***
         If I chose class 3, there will be 6 seat available
Fourth column is the # of seats that I will reserve for this person


I am trying to allocate seats on two airplanes (primary and secondary).  If the first airplane is full,
then the secondary one will take all seats for now.  

**My question: If class 2 is chosen using the SELECT CASE, how can tell my code to jump to another airplane (another array with user-defined type)  and assign the seat.  

--------------------------------------------------------------------
'code:
Private Type ScheduleStructure
   lngFlightNum As Long
   strName As String
   lngClass As Long
   lngSeatsToReserve As Long
End Type

Dim udtFlightSchRecord ( ) As ScheduleStructure

Private Sub Command1_Click()
   lngFlightNum2 As Long
   strName2 As String
   lngClass2 As Long
   lngSeatsToReserve2 As Long
   
   Dim udtCurrentRecord As ScheduleStructure
   Dim intArrayLoop As Long
   
   Open "c:\SimpsonSchedule.txt" For Input As #99
   
   Do While Not EOF(99)
     
      Input #99, lngFlightNum2, strName2, lngClass2, lngSeatsToReserve2
       udtCurrentRecord.lngFlightNum = lngFlightNum2
       udtCurrentRecord.strName = strName2
       udtCurrentRecord.lngClass = lngClass2
       udtCurrentRecord.lngSeatsToReserve = lngSeatsToReserve2
       
       intArrayLoop = intArrayLoop + 1
       ReDim Preserve udtFlightSchRecord (intArrayLoop)
       udtFlightSchRecord(intArrayLoop) = udtCurrentRecord
   Loop
   
   MsgBox udtFlightSchRecord(1).strName  
   Close #99
End Sub

----------------------
'i'm leaving the flight# variable out of the code for now.
FOR intArrayLoop = LBound(udtFlightRecord) to UBOUND(udtFlightRecord)
   udtCurrentRecord = udtFlightRecord(intArrayLoop)
   SELECT CASE udtCurrentRecord.lngClass
      CASE 1
        lngNumSeatsAvailable = 2
      CASE 2
        'Switch to another plane ******need help here!!!!********
      CASE 3
        lngNumSeatsAvailable = 6
   END SELECT
   
     IF udtCurrentRecord.lngSeatsToReserve > 0 THEN
          IF udtCurrentRecord.lngSeatsToReserve <= lngNumSeatsAvailable THEN
             lstDisplay.AddItem udtFlightSchRecord (intArray)
                   lstDisplay.ItemData (lstDisplay.NewIndex) = intCnt
                 lngNumSeatsAvailable = lngNumSeatsAvailable – lngNumSeatsAvailable
          ELSE
                    'MsgBox error message
                 'Switch to another airplane to fullfill request
          ENDIF
   ENDIF

NEXT


Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
shrimpman77 are you ethan211 as well?
If may help if we had just a little more detail in the spec example:

1) You have a file of passenger bookings

2) Each passenger has been given a flight number, a class and a number of seats required..

I am guessing from now....
3) You have a list of planes (does this link to the flight number?)
4) Each plane has a maxium number of people in each class.


etc.....can you confirm

Author

Commented:
Yes, we are in someway.  He is using my screen name.

1) Yes, we do have a list of passenger (in a sequential file)  who needs to be booked to an airplane.  If one is filled up, then we hop on to the next one.

2) Yes, each passenger is given a flight number, but another passenger may carry the same flight number.  On each flight, we have only two planes we can allocated seats to.

3) we have only two planes.  On each flight (say flight #3),  we have only two planes that we can allocated seats to.  If both planes are filled up, the we put up an error message and no more may be allocated.  No, the planes are not linked in a concete way to a particular flight.

4)
**The first plane:                                   second plane:  
class 1 has 2 seat  available          class 1 has 2 seat  available
class 3 has 6 seat  available          class 2 has 2 seat  available  
                                                              class 3 has 2 seat  available  

We really spent a long time looking at your example using a collection, but we could not understand it.   Thanks for any help.

Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

It's a shame you can't under stand it because it does what you want.  Is this an exercise where you are expected use UTD's?

But to make it work using UTD's you need to define the data for each plane:

Private Type PlaneDef
   PlaneID as Long
   SeatsAvailable(2) as Long ' by class
End Type

Dim Planes(1) as PlaneDef

' Now Create data for plane
Plains(0).PlaneID=1
Plains(0).SeatsAvailble(0) = 2 ' class 1
Plains(0).SeatsAvailble(1) = 0 ' class 2
Plains(0).SeatsAvailble(2) = 6 ' class 3

Now do the same for the other plane

Plains(1).PlaneID=2
Plains(1).SeatsAvailble(0) = 2 ' class 1
Plains(1).SeatsAvailble(1) = 2 ' class 2
Plains(1).SeatsAvailble(2) = 3 ' class 3


Why not add the plane no to the passenger array

Private Type ScheduleStructure
  lngFlightNum As Long
  strName As String
  lngClass As Long
  lngSeatsToReserve As Long
  PlaneID as Long ' add this field to the UTD structure
End Type

Now you code could look like this:

FOR intArrayLoop = LBound(udtFlightRecord) to UBOUND(udtFlightRecord)
  udtCurrentRecord = udtFlightRecord(intArrayLoop)
  PlaneID=0 ' try to put in plane 1 first
  lngNumSeatsAvailable=Planes(PlaneID).SeatsAvailable(udtCurrentRecord.lngClass)

 
    IF udtCurrentRecord.lngSeatsToReserve > 0 THEN
         IF udtCurrentRecord.lngSeatsToReserve <= lngNumSeatsAvailable THEN
            lstDisplay.AddItem udtFlightSchRecord (intArray)
                  lstDisplay.ItemData (lstDisplay.NewIndex) = intCnt
                lngNumSeatsAvailable = lngNumSeatsAvailable – lngNumSeatsAvailable
         ELSE
               PlaindID=1 'Switch to another airplane to fullfill request

         END IF
  ENDIF
 
' Save the plane ID back with the passenger data
  udtFlightRecord(intArrayLoop).PlaneID = PlaindID


NEXT


Hope this helps:~)
What your structure is missing is the total seats available for the plane. So I expect that this is more like a seat number allocation routine.

Author

Commented:
I have some follow up questions.

Private Type ScheduleStructure
 lngFlightNum As Long
 strName As String
 lngClass As Long
 lngSeatsToReserve As Long
 lngPlaneID as Long           'First Q:  I have a sequential file with 4   columns, will  cause any problem?
End Type


'Second Q:  Will this below code allow me to exit once I have allocated all seats in the second plan even though another person wants a seat(s).

'Now your code could look like this:

FOR intArrayLoop = LBound(udtFlightRecord) to UBOUND(udtFlightRecord)
 
 udtCurrentRecord = udtFlightRecord(intArrayLoop)
 lngPlaneID=1     'try to put in plane 1 first
 lngNumSeatsAvailable = udtPlanes(lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass)
 
   IF udtCurrentRecord.lngSeatsToReserve > 0 THEN
        IF udtCurrentRecord.lngSeatsToReserve <= lngNumSeatsAvailable THEN
                lstDisplay1.AddItem udtFlightSchRecord (intArray)
               lstDisplay1.ItemData (lstDisplay.NewIndex) = intCnt
               lngNumSeatsAvailable = lngNumSeatsAvailable – lngNumSeatsAvailable
          lngTotalSeat = lngTotalSeat + 1   'If able to allocate, count the seats that is being allocated
        ELSE
                IF lngTotalSeat > 15 THEN
              ExitFor
                ELSE
               lngPlaneID=2       'Switch to another airplane to fullfill request
                ENDIF
        END IF
 ENDIF
 
' Save the plane ID back with the passenger data array
 udtFlightRecord(intArrayLoop).lngPlaneID = lngPlaneID

NEXT

'Thanks for being patient with me.
Q1) No - becuase you move the data into the structure manually

Q2) That was the point I was making. You don't seem to have a total stock of available seats. You just seem to have a formula that says there are x seats in x class.

This could mean you have 2 seats in each row in class 1 and 6 seats in a row in class 3.

Or it could mean you have a total of 2 seats for all passengers in class 1 and 6 total seats in class 3.

I need more info....

Author

Commented:
Q2)
For Airplane 1, I have a total of 8 seats for all passengers.
(2 seats for all passengers in class 1)
( 6 seats for all passengers in class  3)

For Airplane 2, I have a total of 6 seats for all passengers.                  
So the answer for the seconds Q was you need to check the availabillity first.  You could do it like this:

For intArrayLoop = LBound(udtFlightRecord) To UBound(udtFlightRecord)

udtCurrentRecord = udtFlightRecord(intArrayLoop)
' set to no plane first
udtFlightRecord(intArrayLoop).lngPlaneID = -1
For lngPlaneID = 1 To 2
  lngNumSeatsAvailable = udtPlanes(lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass)

  If udtCurrentRecord.lngSeatsToReserve > 0 Then
       If udtCurrentRecord.lngSeatsToReserve <= lngNumSeatsAvailable Then
               lstDisplay1.AddItem udtFlightSchRecord(intArray)
              lstDisplay1.ItemData(lstDisplay.NewIndex) = intCnt

              udtPlanes(lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass) = udtPlanes(lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass) - udtCurrentRecord.lngSeatsToReserve
         lngTotalSeat = lngTotalSeat + 1   'If able to allocate, count the seats that is being allocated
         ' Save the plane ID back with the passenger data array
         udtFlightRecord(intArrayLoop).lngPlaneID = lngPlaneID

         Exit For
     End If
  End If
Next lngPlane

Next
End Sub



The question is now is how to allocate poepl into a different class are you allowed to do that?

Author

Commented:
I'm in the debugging phase right now.  I have been able to convert the sequential file into array.  The problems is that I am not getting the correct output into the listbox.  I not getting an MsgBox error when trying to add a seat to class 2 in flight 1.  Here is my code:

--------------------------

Option Explicit

Private Type ScheduleStructure
   lngFlightNum As Long
   strName As String
   lngClass As Long
   lngSeatsToReserve As Long
   lngPlaneID As Long
End Type

Dim udtFlightSchRecord() As ScheduleStructure

Private Type PlaneDefStructure
  lngPlaneID As Long
  lngSeatsAvailable(1 To 3) As Long     'By class
End Type

Dim udtPlanes(1 To 2) As PlaneDefStructure

Private Sub cmdAllocate_Click()
Dim lngFlightNum2 As Long
Dim strName2 As String
Dim lngClass2 As Long
Dim lngSeatsToReserve2 As Long

Dim lngNumSeatsAvailable As Long
   
Dim udtCurrentRecord As ScheduleStructure
Dim intArrayLoop As Long
   
Dim lngCnt As Long
Dim lngTotalSeat As Long

udtPlanes(1).lngPlaneID = 1
udtPlanes(1).lngSeatsAvailable(1) = 2 ' class 1
udtPlanes(1).lngSeatsAvailable(2) = 0 ' class 2
udtPlanes(1).lngSeatsAvailable(3) = 6 ' class 3

'Now do the same for the other plane
udtPlanes(2).lngPlaneID = 2
udtPlanes(2).lngSeatsAvailable(1) = 2 ' class 1
udtPlanes(2).lngSeatsAvailable(2) = 2 ' class 2
udtPlanes(2).lngSeatsAvailable(3) = 3 ' class 3

Open "I:\Day01.dat" For Input As #99
   
   Do While Not EOF(99)
     
      Input #99, lngFlightNum2, strName2, lngClass2, lngSeatsToReserve2
       udtCurrentRecord.lngFlightNum = lngFlightNum2
       udtCurrentRecord.strName = strName2
       udtCurrentRecord.lngClass = lngClass2
       udtCurrentRecord.lngSeatsToReserve = lngSeatsToReserve2
       
       intArrayLoop = intArrayLoop + 1
       ReDim Preserve udtFlightSchRecord(intArrayLoop)
       udtFlightSchRecord(intArrayLoop) = udtCurrentRecord
       'lstDisplay1.AddItem udtFlightSchRecord(intArrayLoop).lngFlightNum & Space(5) & _
                           udtFlightSchRecord(intArrayLoop).strName & Space(5) & _
                            udtFlightSchRecord(intArrayLoop).lngClass & Space(5) & _
                            udtFlightSchRecord(intArrayLoop).lngSeatsToReserve
   Loop
Close #99


For intArrayLoop = LBound(udtFlightSchRecord) To UBound(udtFlightSchRecord)
 
 udtCurrentRecord = udtFlightSchRecord(intArrayLoop)
 udtFlightSchRecord(intArrayLoop).lngPlaneID = 1 'try to put in plane 1 first
   
'Find the amount of available seats so that I can assign seats
 lngNumSeatsAvailable = udtPlanes(udtFlightSchRecord(intArrayLoop).lngPlaneID).lngSeatsAvailable(lngClass2)
 
   If udtCurrentRecord.lngSeatsToReserve > 0 Then     'IF seat2reserve > 0
        If udtCurrentRecord.lngSeatsToReserve <= lngNumSeatsAvailable Then  'IF seat2reserve < avail seat
             lstDisplay1.AddItem udtFlightSchRecord(intArrayLoop).strName 'THEN Add only name
             
        Else
             MsgBox "Not Enough or NO Seats!", vbOKOnly, "HELLO"
        End If
 End If
 
'Save the plane ID back with the passenger data array
 udtFlightSchRecord(intArrayLoop).lngPlaneID = 2

Next

End Sub
The problem is that lngClass2 was not being setup:



'Find the amount of available seats so that I can assign seats
lngNumSeatsAvailable = udtPlanes(udtFlightSchRecord(intArrayLoop).lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass)

Author

Commented:
Sorry, I tried it but I got an error.
"Run-Time error "9":Subscript out of range."

I replaced
"lngNumSeatsAvailable = udtPlanes(udtFlightSchRecord(intArrayLoop).lngPlaneID).lngSeatsAvailable(lngClass2)"

with:
"lngNumSeatsAvailable = udtPlanes(udtFlightSchRecord(intArrayLoop).lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass)"

You get error 9 when udtCurrentRecord.lngClass could be invalid. Or udtFlightSchRecord(intArrayLoop).lngPlaneID could be invalid.

Another tip, next time you write an app. I suggest that you use shorter names, the code would be simpler for you to understand.

Do you know how to use the F8 key.

Place a break point where the class data is being loaded. When the code stops you can see the value of the variables.

Author

Commented:
Still no luck,

For the first element in the array (1,"shrimp",1,2),
the value of "udtCurrentRecord.lngClass" is correct but
"udtCurrentRecord.lngClass)" is not. A value of 0 for the third is reported, not 1.

Author

Commented:
I got it.  I need to Declare "Option Base 1".
Thanks for all advice so far.

Author

Commented:
I got an Msgbox error message.  Now, I am trying to allocate the seats in class 2 to the 2nd airplane.  The problem lies in that the the second planeid value "2" is reset to the first planeid.



For intArrayLoop = LBound(udtFlightSchRecord) To UBound(udtFlightSchRecord)
 
 udtCurrentRecord = udtFlightSchRecord(intArrayLoop)
 udtCurrentRecord.lngPlaneID = 1
   
 lngNumSeatsAvailable = udtPlanes(udtCurrentRecord.lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass)
   If udtCurrentRecord.lngSeatsToReserve > 0 Then  
        If udtCurrentRecord.lngSeatsToReserve <= lngNumSeatsAvailable Then  
             lstDisplay1.AddItem udtFlightSchRecord(intArrayLoop).strName
udtPlanes(udtCurrentRecord.lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass) = _
udtPlanes(udtCurrentRecord.lngPlaneID).lngSeatsAvailable(udtCurrentRecord.lngClass) - udtCurrentRecord.lngSeatsToReserve

        Else
             MsgBox "Not Enough or NO Seats!", vbOKOnly
             udtCurrentRecord.lngPlaneID = 2
   
        End If
 End If
'Save the plane ID back with the passenger data array
udtCurrentRecord.lngPlaneID = udtCurrentRecord.lngPlaneID

Next
It is a good idea to have rules but the ones you have used are stopping you program from being easy for you to read. In future I would not use a 3 letter convention.


In every subroutine you should adopt similar variable names for similar functions example:


Dim RC As Long      ' Record count
Dim SQL As String
Dim CN As ADODB.Connection
Dim RS As ADODB.Recordset
Dim OK

You would also need your own code.

Also you are using 3 letters like:

Dim strName2 As String

Just sName2 would be better.

Further, instead of using a whole word like Avaiable, which is used al lot in programming you can also abreviate this word to Av and Passwnger to Pax.  If you always make this abreviation and you say that in your comments, any programmer who visits your code will thank you for that.

I will post an example.


Another words that are used alot in software:

Required - Req
Maximum - Max
Minimum - Min
Product - Prod

It is more common to keep objects prefixes example:
txtTexBox
lstListBox
etc.

Here is your simplified app.

Option Explicit
Option Base 0

Private Type ScheduleStructure
  lFlight As Long
  sName As String
  lClass As Long
  lSeatsReq As Long
  lPlaneID As Long
End Type

Dim uFSRecs() As ScheduleStructure ' Flight Schedule Records

Private Type PlaneDefStructure
 lPlaneID As Long
 lSeatsAv(1 To 3) As Long     'By class
End Type

Dim uPlanes(1 To 2) As PlaneDefStructure

Sub SetUpPlanes()

' setup plane data

uPlanes(1).lPlaneID = 1
uPlanes(1).lSeatsAv(1) = 2 ' class 1
uPlanes(1).lSeatsAv(2) = 0 ' class 2
uPlanes(1).lSeatsAv(3) = 6 ' class 3

'Now do the same for the other plane
uPlanes(2).lPlaneID = 2
uPlanes(2).lSeatsAv(1) = 2 ' class 1
uPlanes(2).lSeatsAv(2) = 2 ' class 2
uPlanes(2).lSeatsAv(3) = 3 ' class 3
End Sub


Private Sub cmdAllocate_Click()

Dim lSeatsAv As Long    ' Number of seats available

Dim RC As Long  ' record count
Dim PC As Long  ' plane count

'Dim lngTotalSeat As Long

' right click to view definition
SetUpPlanes     ' setup plane data
SetupPaxData    ' setup passenger requirements data

For RC = LBound(uFSRecs) To UBound(uFSRecs)
   
    ' Loop through each plane
   
    uFSRecs(RC).lPlaneID = -1 ' this pax has no plane yet
   
    For PC = LBound(uPlanes) To UBound(uPlanes)
   
        'Find the amount of available seats so that I can assign seats
        lSeatsAv = uPlanes(PC).lSeatsAv(uFSRecs(RC).lClass)
         
        If uFSRecs(RC).lSeatsReq > 0 Then ' skip if no seats req.
            If uFSRecs(RC).lSeatsReq <= lSeatsAv Then
                lstDisplay1.AddItem "Plane: " + CStr(PC) + " Class: " + CStr(uFSRecs(RC).lClass) + " Allocated: " + uFSRecs(RC).sName
                uPlanes(PC).lSeatsAv(uFSRecs(RC).lClass) = uPlanes(PC).lSeatsAv(uFSRecs(RC).lClass) - uFSRecs(RC).lSeatsReq
                uFSRecs(RC).lPlaneID = PC
                Exit For
            End If
        End If
    Next PC
Next RC

' display the pax that could not be allocated
lstDisplay1.AddItem "Could not allocate: "
For RC = LBound(uFSRecs) To UBound(uFSRecs)
   
    ' Loop through each plane
    If uFSRecs(RC).lPlaneID <= 0 Then
        lstDisplay1.AddItem "Class: " + CStr(uFSRecs(RC).lClass) + uFSRecs(RC).sName
    End If
   
Next RC
 
End Sub

Sub SetupPaxData()

' load pax data

Dim lfn As Long
Dim lFlight2, sName2, lClass2, lSeatsReq2



Dim RC As Long

lfn = FreeFile
Open "I:\Day01.dat" For Input As #lfn

ReDim Preserve uFSRecs(100) ' make this about as big as you need at the start
RC = -1

Do While Not EOF(lfn)
     
    Input #lfn, lFlight2, sName2, lClass2, lSeatsReq2
   
    RC = RC + 1
    if rc> ubound(uFSRecs) Then
        ReDim Preserve uFSRecs(RC)
    End If      

    uFSRecs(RC).lFlight = CLng(lFlight2)
    uFSRecs(RC).sName = Trim(CStr(sName2))
    uFSRecs(RC).lClass = CLng(lClass2)
    uFSRecs(RC).lSeatsReq = CLng(lSeatsReq2)

Loop

ReDim Preserve uFSRecs(RC)

Close #lfn

End Sub

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial