Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Help with adding functionality to existing code
Message
 
To
All
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Title:
Help with adding functionality to existing code
Miscellaneous
Thread ID:
00619646
Message ID:
00619646
Views:
49
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
				IF llSlotFound
					EXIT
				endif
			ENDFOR 
			IF llSlotFound
				EXIT
			endif
		ENDFOR
		llSlotFound=.f. 
		lnProcCtr=lnProcCtr+1
	ENDSCAN
ENDIF
Next
Reply
Map
View

Click here to load this message in the networking platform