Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Help with adding functionality to existing code
Message
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00619646
Message ID:
00619731
Views:
9
>I'm hoping that someone can help me place some additional logic in the code below. First this code is ran from a form. The purpose is to locate available time slots for a given set of procedures. As it is, it works. BUT (there's always one of these), it currently finds the earliest time in the first resource, even if the second potential resource has an earlier opening. I'm not sure where I need to set a flag and check. For example, if there are two rooms available to do this procedure (RM1,RM2) and RM1 is busy from 0700 to 1200, but RM2 is open from 0700 to 1700, the code right now will find the first available slot as RM1 at 1215. What I'd like it to do is find that RM2 is open at 7AM. This logic currently processes multiple procedures, in other words, it may have to find time slots for 2,3,4 or even 5 procedures that happen after each other and maybe in different resources and even on diffent days (offset from the ending time of the first procedure). So finding the earliest
>slot only applies to the first procedure.
>
>Anyway, here is the current code, any help or suggestions greatly appreciated:
>
>
>* Program: ctSetSlots2.prg
>* Purpose: Return a result set of available times to schedule a procedure set
>PARAMETERS tiSetID,tdStartDate,tdEndDate
>* Load Our Library
>SET PROCEDURE TO ctsch3fun addi
>ldStartOn=tdStartDate
>ldEndOn=tdEndDate
>lnDaysToSearch=tdEndDate-tdStartDate
>lcStartDate=DTOC(tdStartDate)
>lcEndDate=DTOC(tdEndDate)
>PUBLIC gcResultString
>
>gcResultString=""
>* Create our Temp Canidate Table
>SQLEXEC(gnConnHandle,[Select * from coCan],"CurTemp")
>SELECT * from curTemp INTO CURSOR xCurTemp readwrite
>* Get all cases between the daterange
>
>* Get the requirements for the set
>lcCmd=[SELECT dbo.procstg1.proccode, dbo.procstg1.description, dbo.procstg1.initialproctime, dbo.procstg1.tue, dbo.procstg1.mon, dbo.procstg1.wed, ]
>lcCmd=lcCmd+[ dbo.procstg1.thu, dbo.procstg1.fri, dbo.procstg2.procstg2ID, dbo.procstg2.procID, dbo.procstg2.minoffset, dbo.procstg2.maxoffset, dbo.coproc.dcode, ]
>lcCmd=lcCmd+[ dbo.coproc.description AS Expr1, dbo.coRoomToGroup.RoomID, dbo.corooms.roomname,dbo.coRooms.DeptID,dbo.coRooms.schedFrom,dbo.coRooms.SchedTo ]
>lcCmd=lcCmd+[ FROM  dbo.corooms INNER JOIN ]
>lcCmd=lcCmd+[ dbo.coRoomToGroup ON dbo.corooms.roomid = dbo.coRoomToGroup.RoomID INNER JOIN ]
>lcCmd=lcCmd+[ dbo.coproc INNER JOIN ]
>lcCmd=lcCmd+[ dbo.procstg2 ON dbo.coproc.procid = dbo.procstg2.procID INNER JOIN ]
>lcCmd=lcCmd+[ dbo.coProcRoomGrp ON dbo.coproc.procid = dbo.coProcRoomGrp.procID INNER JOIN ]
>lcCmd=lcCmd+[ dbo.procstg1 ON dbo.procstg2.procstgid = dbo.procstg1.procstgid ON dbo.coRoomToGroup.coRoomGrpID = dbo.coProcRoomGrp.coRoomGrpID ]
>lcCmd=lcCmd+[ where dbo.procstg1.procstgid=?tiSetID]
>lcCmd=lcCmd+[ order by procStg2.ProcStg2ID ]
>
>IF SQLEXEC(gnConnHandle,lcCmd,"curSetData") < 1
>	=sqlerror()
>ELSE
>	* Next Step
>	* Determine How Many Differnt Strings we have
>	SELECT dist procstg2ID as stgID FROM curSetData INTO CURSOR curStrings
>	ltInitialDT={}	
>	PUBLIC ARRAY laSlots[RECCOUNT("curStrings"),7]
>	SELECT curStrings
>	llFirstProc=.t.
>	lnSlotPtr=1
>	llSlotFound=.f.
>	lnProcCtr=1
>	lnMinOff=0
>	ltInitialProcEnd=0
>	* Loop through each procedure finding a slot
>	SELECT curStrings
>	SCAN
>		* Get the Min OffSet
>		* Get an array of room id's we can do this procedure in
>		lnCurrID=curStrings.stgID
>		SELECT dist roomid,schedfrom,schedto,0,deptid,minoffset,procid,roomname,expr1  FROM cursetdata WHERE curSetData.procstg2id=lnCurrID INTO ARRAY laRooms
>		llFirst=.t.
>		* Get Required Procedure Time (minutes)
>		lcCmd=[SELECT  dbo.coproc.setup, dbo.coproc.cleanup, dbo.coproc.defaulttime ]
>		lcCmd=lcCmd+[FROM dbo.procstg2 INNER JOIN ]
>        lcCmd=lcCmd+[dbo.coproc ON dbo.procstg2.procID = dbo.coproc.procid ]
>        lcCmd=lcCmd+[where dbo.procstg2.procStg2ID = ?lnCurrID ]
>        SQLEXEC(gnConnHandle,lcCmd,"curDefaTime")
>        lnMinutesRequired=IIF(ISNULL(defaulttime),30,defaulttime)
>        SELECT curSTrings
>        ltSearchStart=CTOT(DTOC(ldStartOn)+[ ]+formattime(360))
>        *!* Loop through the number of days available in the search
>        llFirstDaysLoop=.t.
>		FOR lnDays=1 TO lnDaysToSearch
>			SET MESSAGE TO [Searching lnDays=]+TRANSFORM(lnDays)
>			* Advance the search date
>			IF !llFirstDaysLoop
>				ldStartOn=ldStartOn+1
>			ELSE
>				llFirstDaysLoop=.f.
>			ENDIF
>			* Loop through each room
>			IF lnProcCtr=1
>				ltEarly=0  && Need to store the earliest one if it is the first procedure we are search for
>			endif
>			FOR lnRoomLoop = 1 TO ALEN(laRooms,1)
>				* get the available number of 15 minutes slots we can search for this room
>				lnSlots=((((laRooms[lnRoomLoop,3]-laRooms[lnRoomLoop,2])/100)*60)/15)
>				* Store Starting Time For Room
>				* Not all rooms will have the same open periods
>				lnRoomStart=((laRooms[lnRoomLoop,2]/100)*60)
>				lnRoomID=  laRooms[lnRoomLoop,1]
>				lnDeptID=  laRooms[lnRoomLoop,5]
>				lnOffSet=  laRooms[lnRoomLoop,6]
>				lnProcID=  laRooms[lnRoomLoop,7]
>				lcRoomName=laRooms[lnRoomLoop,8]
>				lcProcDesc=laRooms[lnRoomLoop,9]
>				llFirstSlotLoop=.t.
>				* Loop through each available slot for a match
>				FOR lnSlotLoop=1 TO lnSlots
>					* Set the search dateTime parameters
>					IF llFirstSlotLoop
>						ltSearchFrom=CTOT(DTOC(ldStartOn)+[ ]+formattime(lnRoomStart))
>						llFirstSlotLoop = .f.
>					ELSE
>						ltSearchFrom=ltSearchFrom+900
>					ENDIF
>					* Check the required offset (minutes) from the end of the first
>					* procedure.  If we are not meeting the offset, skip and let it advance the datetime
>					ltSearchTo  =ltSearchFrom+(lnMinutesRequired*60)
>					IF lnProcCtr > 1 AND ltSearchFrom < (ltInitialProcEnd+(lnOffSet*60))
>						* We Need to Advance the time
>					ELSE
>						* Build the string to search for existing cases in the time slot
>						lcCmd=[SELECT meetingnumber from meetings ]
>						lcCmd=lcCmd+[WHERE roomid = ?lnRoomID ]
>						lcCmd=lcCmd+[AND (begintime between ?ltSearchFrom and ?ltSearchTo ]
>						lcCmd=lcCmd+[OR endtime between ?ltSearchFrom and ?ltSearchTo) ]
>						* Exec the sqlexec
>						IF SQLEXEC(gnConnHandle,lcCmd,"curConflict") < 1
>							=sqlerror()
>						ELSE
>							* Check to see if we have a conflict (Reccount > 0)
>							IF RECCOUNT("curConflict") > 0
>								* No Good, there is already something booked in this timeslot and room
>								llSlotFound=.f.
>							ELSE
>								* Create Temporary records to show this slot as used in case someone else
>								* tries to search this period
>								=ctManageLocks(lnRoomid,lnDeptID,ltSearchFrom,ltSearchTo,lnLockID,DATETIME(),.t.)
>								IF lnProcCtr=1
>									* IF it is the first procedure, then we need to store the time slot we found
>									* so we have a baseline for the offset on the rest of the procedures
>									ltInitialProcEnd=ltSearchTo
>								endif
>								* Store into a public array so we can show it to the user in the calling form.
>								laSlots[lnSlotPtr,1]=TRANSFORM(ltSearchFrom)
>								laSlots[lnSlotPtr,2]=TRANSFORM(ltSearchTo)
>								laSlots[lnSlotPtr,3]=TRANSFORM(lcRoomName)
>								laSlots[lnSlotPtr,4]=TRANSFORM(lcProcDesc)	&& Proc Description
>								laSlots[lnSlotPtr,5]=TRANSFORM(lnProcID)
>								laSlots[lnSlotPtr,6]=TRANSFORM(lnRoomID)
>								laSlots[lnSlotPtr,7]=TRANSFORM(lnDeptID)
>								* Advance the Array Pointer
>								lnSlotPtr=lnSlotPtr+1
>								* Set the flag that we found a slot
>								llSlotFound=.t.
>							ENDIF
>						ENDIF
>					ENDIF
>					IF llSlotFound
>						EXIT
>					endif
>				ENDFOR && timeslot
>				*IF llSlotFound
>				*	EXIT
>				*endif
>			ENDFOR && room
                        *retain LowestTimeSlot
                        * re-assign timeslot
>			IF llSlotFound
>				EXIT
>			endif
>		ENDFOR && day
>		llSlotFound=.f.
>		lnProcCtr=lnProcCtr+1
>	ENDSCAN
>ENDIF
>
>
Yes, your logic hyaerchy is
                FOR day  
                        FOR room && endfor allrooms assign low timeslot
                                For timeslot && do not endfor .t.
Find 'Time Slot' available within 'Room' within 'Day', then assign ConferenceCall.
Does not take into account otherrooms with ealier timeslot.

Keep lSlotFound = .f. until
all rooms are processed.

While processing rooms determine if timeslot of room is better than recent timeslot and retain if so. (allRooms) Then re-assign timeslot!

Ed B :~)
Edgar L. Bolton, B.S. B.B.A.
Previous
Reply
Map
View

Click here to load this message in the networking platform