VBA Queueing Simulation Help Needed

evbanewB

New Member
Joined
Mar 7, 2012
Messages
1
Hello,

Thanks so much in advance for any help that you can provide me. I have been given code for a queueing simulation and I need to make it so that the simulation stops at the close time and the 'customers' that are currently in the system(nBusy) and in the queue(nInQueue) are reported. Currently, it is set up to not accept any new arrivals past the close time but will finish out the 'customers' in the queue. When I do make changes, I keep getting either a subscript out of range error or an overflow error. Any suggestions or tips would be so greatly appreciated! The code is below.

Code:
Option Explicit
Dim meanIATime As Single
Dim meanServeTime As Single
Dim nServers As Integer
Dim maxAllowedInQ As Integer
Dim closeTime As Single
Dim nInQueue As Integer
Dim nBusy As Integer
Dim clockTime As Single
Dim eventScheduled() As Boolean
Dim timeOfLastEvent As Single
Dim timeOfNextEvent() As Single
Dim nServed As Long
Dim nLost As Integer
Dim maxNInQueue As Integer
Dim maxTimeInQueue As Single
Dim timeOfArrival() As Single
Dim totalTimeInQueue As Single
Dim totalTimeBusy As Single
Dim sumOfQueueTimes As Single
Dim queueTimeArray() As Single
 
Sub Main()
Dim nextEventType As Integer
Dim finishedServer As Integer
Randomize
Call ClearOldResults
 
With wsReport
meanIATime = 1 / .Range("ArriveRate").Value
meanServeTime = .Range("MeanServeTime").Value
nServers = .Range("nServers").Value
maxAllowedInQ = .Range("MaxAllowedInQ").Value
closeTime = .Range("CloseTime").Value
End With
 
ReDim eventScheduled(nServers + 1)
ReDim timeOfNextEvent(nServers + 1)
 
Call Initialize
 
Do
 
Call FindNextEvent(nextEventType, finishedServer)
Call UpdateStatistics
If nextEventType = 1 Then
Call Arrival
Else
Call Departure(finishedServer)
End If
Loop Until Not eventScheduled(0) And nBusy = 0
 
Call Report
End Sub
 
Sub ClearOldResults()
With wsReport
.Range("Output_rng").ClearContents
With .Range("QDistAnchor")
Range(.Offset(1, 0), .Offset(0, 1).End(xlDown)).ClearContents
End With
End With
End Sub
 
Sub Initialize()
Dim i As Integer
clockTime = 0
nBusy = 0
nInQueue = 0
timeOfLastEvent = 0
nServed = 0
nLost = 0
sumOfQueueTimes = 0
maxTimeInQueue = 0
totalTimeInQueue = 0
maxNInQueue = 0
totalTimeBusy = 0
ReDim queueTimeArray(1)
queueTimeArray(0) = 0
eventScheduled(0) = True
timeOfNextEvent(0) = Exponential(meanIATime)
For i = 1 To nServers
eventScheduled(i) = False
Next
End Sub
 
Function Exponential(mean As Single) As Single
Exponential = -mean * Log(Rnd)
End Function
 
Sub FindNextEvent(nextEventType As Integer, finishedServer As Integer)
Dim i As Integer
Dim nextEventTime As Single
nextEventTime = 10 * closeTime
 
For i = 0 To nServers
If eventScheduled(i) Then
' If the current event is the most imminent so far, record it.
If timeOfNextEvent(i) < nextEventTime Then
nextEventTime = timeOfNextEvent(i)
If i = 0 Then
nextEventType = 1
Else
nextEventType = 2
finishedServer = i
End If
End If
End If
Next
clockTime = nextEventTime
End Sub
 
Sub UpdateStatistics()
Dim timeSinceLastEvent As Single, i As Integer
timeSinceLastEvent = clockTime - timeOfLastEvent
queueTimeArray(nInQueue) = queueTimeArray(nInQueue) + timeSinceLastEvent
totalTimeInQueue = totalTimeInQueue + nInQueue * timeSinceLastEvent
totalTimeBusy = totalTimeBusy + nBusy * timeSinceLastEvent
timeOfLastEvent = clockTime
End Sub
 
Sub Arrival()
Dim i As Integer
timeOfNextEvent(0) = clockTime + Exponential(meanIATime)
If timeOfNextEvent(0) > closeTime Then
eventScheduled(0) = False
End If
If nInQueue = maxAllowedInQ Then
nLost = nLost + 1
Exit Sub
End If
 
If nBusy = nServers Then
nInQueue = nInQueue + 1
If nInQueue > maxNInQueue Then
maxNInQueue = nInQueue
ReDim Preserve queueTimeArray(0 To maxNInQueue)
ReDim Preserve timeOfArrival(1 To maxNInQueue)
End If
timeOfArrival(nInQueue) = clockTime
Else
nBusy = nBusy + 1
 
For i = 1 To nServers
If Not eventScheduled(i) Then
eventScheduled(i) = True
timeOfNextEvent(i) = clockTime + Exponential(meanServeTime)
Exit For
End If
Next
End If
End Sub
 
Sub Departure(finishedServer As Integer)
Dim i As Integer
Dim timeInQueue As Single
nServed = nServed + 1
If nInQueue = 0 Then
nBusy = nBusy - 1
eventScheduled(finishedServer) = False
Else
nInQueue = nInQueue - 1
timeInQueue = clockTime - timeOfArrival(1)
If timeInQueue > maxTimeInQueue Then
maxTimeInQueue = timeInQueue
End If
sumOfQueueTimes = sumOfQueueTimes + timeInQueue
timeOfNextEvent(finishedServer) = clockTime + Exponential(meanServeTime)
For i = 1 To nInQueue
timeOfArrival(i) = timeOfArrival(i + 1)
Next
End If
End Sub
 
Sub Report()
 
 
Dim i As Integer
Dim avgTimeInQueue As Single
Dim avgNInQueue As Single
Dim avgNBusy As Single
Dim ser As Series
avgTimeInQueue = sumOfQueueTimes / nServed
avgNInQueue = totalTimeInQueue / clockTime
avgNBusy = totalTimeBusy / clockTime
 
For i = 0 To maxNInQueue
queueTimeArray(i) = queueTimeArray(i) / clockTime
Next
With wsReport
.Range("FinalTime").Value = clockTime
.Range("NServed").Value = nServed
.Range("AvgTimeInQ").Value = avgTimeInQueue
.Range("MaxTimeInQ").Value = maxTimeInQueue
.Range("AvgNInQ").Value = avgNInQueue
.Range("MaxNInQ").Value = maxNInQueue
.Range("AvgServerUtil").Value = avgNBusy / nServers
.Range("NLost").Value = nLost
.Range("PctLost").Formula = "=NLost/(NLost + NServed)"
 
 
With .Range("QDistAnchor")
For i = 0 To maxNInQueue
.Offset(i + 1, 0).Value = i
.Offset(i + 1, 1).Value = queueTimeArray(i)
Next
Range(.Offset(1, 0), .Offset(maxNInQueue, 0)).Name = "Report!NInQueue"
Range(.Offset(1, 1), .Offset(maxNInQueue, 1)).Name = "Report!PctOfTime"
End With
 
 
Set ser = .ChartObjects(1).Chart.SeriesCollection(1)
ser.Values = .Range("PctOfTime")
ser.XValues = .Range("nInQueue")
 
.Range("A2").Select
End With
End Sub
 
Sub ViewChangeInputs()
With wsReport
.Visible = True
.Activate
End With
Call ClearOldResults
End Sub
 
Last edited by a moderator:

Excel Facts

Who is Mr Spreadsheet?
Author John Walkenbach was Mr Spreadsheet until his retirement in June 2019.

Forum statistics

Threads
1,215,196
Messages
6,123,578
Members
449,108
Latest member
rache47

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top