VENSIM SIMUL8 timing issue using DLL

Use this forum to post Vensim related questions.
Post Reply
joe
Junior Member
Posts: 3
Joined: Thu May 28, 2009 7:04 pm

VENSIM SIMUL8 timing issue using DLL

Post by joe »

Hi,

I am using VENSIM to generate patient demand along with other more SD things and then using SIMUL8 to treat the patients.

I am using Excel to achieve this as I am not (hopefully) trying anything too complicated. What I thought of doing was using VENSIM's game function, the game generates the demand I then run Simul8 and determine the number of patients treated.

Below is the code that I thought would work but I have obviously missed something:

result = vensim_get_val("Available for treatment", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 10) = stime$
Worksheets("Sheet1").Cells(4, 2) = stime$
End If
Call Trial
num$ = Worksheets("Sheet1").Cells(4, 6)
comstr$ = "SIMULATE>SETVAL|TREATED= " + num$
result = vensim_command(comstr$)
If result = 0 Then Exit Sub
result = vensim_get_val("Treated", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 11) = stime$
End If

The "Call Trial" line relates to the Simul8 run. The "Worksheets("Sheet1").Cells(4, 6)" is where the output from Simul8 is located.

VENSIM doesn't wait for the value to be returned before going to the next line consequently the number of people treated isn't updated.

Any advice or guidance would be appreciated

Many thanks

Joe
Administrator
Super Administrator
Posts: 4841
Joined: Wed Mar 05, 2003 3:10 am

Post by Administrator »

Is the code stepping over the "Call Trial" line?

And how are you calling Simul8 (it would be handy to see the routine where you call Simul8)?

Tony.
joe
Junior Member
Posts: 3
Joined: Thu May 28, 2009 7:04 pm

Post by joe »

Hi Tony,

This is the code used to run the Simul8 trial:

Private Sub Trial()
MYSIMUL8.ResetSim (0)
MYSIMUL8.TrialSim 50, False
End Sub

Simul8 runs ok and it posts the number of people treated back but as I mentioned before whilst this code is running VENSIM has already gone through the rest of the code.

Are there any techniques to freeze VENSIM until the Simul8 trial is complete. Then restart at the next line?

VENSIM and SIMUL8 are already open before the above code is run. I thought about trying to put in some kind of delay after the simul8 line is reached but this didn't have an effect.

Below is the entire routine if needed:

Private Sub game()
Dim timeval As Single
result = vensim_be_quiet(2)
result = vensim_command("SPECIAL>LOADMODEL|C:\Documents and Settings\Joe\Desktop\Composite\simplemodel.vpm")
Worksheets("Sheet1").Activate
result = vensim_command("SIMULATE>RUNNAME|test")
If result = 0 Then Exit Sub
num$ = Worksheets("Sheet1").Cells(15, 9)
comstr$ = "SIMULATE>SETVAL|INTERVENTION= " + num$
result = vensim_command(comstr$)
If result = 0 Then Exit Sub
num$ = Worksheets("Sheet1").Cells(8, 9)
result = vensim_command("GAME>GAMEINTERVAL|" + num$)
If result = 0 Then Exit Sub
result = vensim_command("MENU>GAME")
If result = 0 Then Exit Sub
result = vensim_get_val("Time", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 9) = stime$
End If
result = vensim_get_val("Available for treatment", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 10) = stime$
Worksheets("Sheet1").Cells(4, 2) = stime$
End If
Call Trial
num$ = Worksheets("Sheet1").Cells(4, 6)
comstr$ = "SIMULATE>SETVAL|TREATED= " + num$
result = vensim_command(comstr$)
If result = 0 Then Exit Sub
result = vensim_get_val("Treated", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 11) = stime$
End If

End Sub
Administrator
Super Administrator
Posts: 4841
Joined: Wed Mar 05, 2003 3:10 am

Post by Administrator »

The problem here is not with Vensim. You need to make the function call to Simul8 and wait for it to finish.

What is the "false" in the line below? Only asking in case it is a wait flag.

MYSIMUL8.TrialSim 50, False


Another solution would be to set some cell to -1 before calling Simul8. Now run the Simul8 code and make sure it overwrites the -1 with 1, and have a loop in your code above that monitors the cell contents and exits the loop when it finds a 1.

For example, the following monitors a cell, and sleeps for 100 milliseconds before checking the contents again. If Simul8 can set the cell to anything other than -1, the loop will end.

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)


Worksheets("Sheet1").Cells(100, 100) = -1
Call Trial

while ( Worksheets("Sheet1").Cells(100, 100) = -1 )
Sleep(100)
wend
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

I can't follow your code - you need to do the following

MENU>GAME

then in a loop

get value from vensim
call some other function to do some computation
use SIMULATE>SETVAL
GAME>GAMEON
check to see if finished

I do not see a GAMEON command anywhere. You also need to make sure the variable you set is a gaming variable and not a constant.
joe
Junior Member
Posts: 3
Joined: Thu May 28, 2009 7:04 pm

Post by joe »

The variable I am trying to change is a gaming variable. I use MENU>GAME in a previous piece of code see below:

Private Sub game()
Dim timeval As Single
result = vensim_be_quiet(2)
result = vensim_command("SPECIAL>LOADMODEL|C:\Documents and Settings\Joe\Desktop\Composite\simplemodel.vpm")
Worksheets("Sheet1").Activate
result = vensim_command("SIMULATE>RUNNAME|test")
If result = 0 Then Exit Sub
num$ = Worksheets("Sheet1").Cells(15, 9)
comstr$ = "SIMULATE>SETVAL|INTERVENTION= " + num$
result = vensim_command(comstr$)
If result = 0 Then Exit Sub
result = vensim_command("GAME>GAMEINTERVAL|1")
If result = 0 Then Exit Sub
result = vensim_command("MENU>GAME")
If result = 0 Then Exit Sub
result = vensim_get_val("Time", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 9) = stime$
End If
result = vensim_get_val("Available for treatment", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 10) = stime$
End If
MYSIMUL8.TrialSim 50, False
num$ = Worksheets("Sheet1").Cells(4, 6)
comstr$ = "SIMULATE>SETVAL|TREATED = " + num$
result = vensim_command(comstr$)
result = vensim_get_val("Treated", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(21, 11) = stime$
End If
End Sub

Then I use the following code:

Private Sub Continue()
Dim timeval As Single
Dim i As Single
i = Worksheets("Sheet1").Cells(9, 9)
result = vensim_command("GAME>GAMEON")
'result = vensim_command("GAME>BACKUP") to back up
num$ = Worksheets("Sheet1").Cells(10, 9)
comstr$ = "SIMULATE>SETVAL|TREATED = " + num$
result = vensim_command(comstr$)
If result = 0 Then Exit Sub
result = vensim_get_val("time", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(i, 9) = stime$
End If
result = vensim_get_val("Available for treatment", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(i, 10) = stime$
Worksheets("Sheet1").Cells(4, 2) = stime$
End If
result = vensim_get_val("Treated", timeval)
If result = 1 Then
stime$ = timeval
Worksheets("Sheet1").Cells(i, 11) = stime$
End If
i = i + 1
Worksheets("Sheet1").Cells(9, 9) = i
End Sub

Sorry for the amount of code.

Thanks

Joe
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

the continue sub looks OK except that you need to have SIMULATE>SETVAL before GAME>GAMEON, not after. so you must have a loop somewhere that looks like


do
call simul8 code
call continue subroutine
end do

As Tony suggests - make sure the simul8 code finishes before returning to call the continue subroutine.
Post Reply