Initializing help system before first use

VBA

VBA typically serves for embedding a Mosel model into an Excel spreadsheet. In this section we shall only show the parts relevant to the Mosel functions, assuming that the execution of a model is trigged by the action of clicking on some object such as the buttons shown in Figure Excel spreadsheet embedding VBA macros.

MoselUG/moselugvb.png

Figure 17.1: Excel spreadsheet embedding VBA macros

Compiling and executing a model in VBA

As with the other programming languages, to execute a Mosel model in VBA we need to perform the standard compile/load/run sequence as shown in the following example (contained in the file ugvb.bas). We use a slightly modified version burglar5.mos of the burglar problem where we have redirected the output printing to the file burglar_out.txt.

Private Sub burglar_Click()
  Dim model
  Dim ret As Long
  Dim result As Long
  Dim outfile As String, moselfile As String

'Initialize Mosel
  ret = XPRMinit
  If ret Then
    MsgBox "Initialization error (" & ret & ")"
    Exit Sub
  End If

'Compile burglar5.mos
  XPRMsetdefworkdir GetFullPath()
  moselfile = GetFullPath() & "\" & "burglar5"
  outfile = GetFullPath() & "\" & "burglar_out.txt"
  ret = XPRMcompmod(vbNullString, moselfile & ".mos", vbNullString, _
        "Burglar problem")
  If ret <> 0 Then
    MsgBox "Compile error (" & ret & ")"
    Exit Sub
  End If

'Load burglar5.bim
  model = XPRMloadmod(moselfile & ".bim", vbNullString)
  If model = 0 Then
    MsgBox "Error loading model"
    Exit Sub
  End If

'Run the model
  ret = XPRMrunmod(model, result, "OUTFILE=""" & Replace(outfile, "\", _
        "\\") & """")
  If ret <> 0 Then
    MsgBox "Execution error (" & ret & ")"
    GoTo done
  Else
    ShowFile outfile
  End If
  MsgBox vbNewLine & "model Burglar returned: " & result

done:
  XPRMfree
End Sub

'Auxiliary routines
Private Sub ShowFile(fn As String)
  Dim vs As String
  vs = CreateObject("Scripting.FileSystemObject").OpenTextFile(fn).ReadAll
  MsgBox vs
End Sub

Private Function GetFullPath() As String
  Dim path As String
  path = ThisWorkbook.path
  If Right(path, 1) = "\" Then path = Left(path, Len(path) - 1)
  GetFullPath = path
End Function

This implementation redirects the output into a log file vbout.txt the contents of which is displayed after a successful model run.

Parameters

When executing a Mosel model in VBA, it is possible to pass new values for its parameters into the model. The following program (also contained in the file ugvb.frm) extract shows how we may run model `Prime' from Section Working with sets to obtain all prime numbers up to 500 (instead of the default value 100 set for the parameter LIMIT in the model). We use a slightly modified version prime4.mos of the model where we have redirected the output printing to a file denoted by the parameter OUTFILE.

Private Sub prime_Click()
  Dim model
  Dim ret As Long
  Dim result As Long
  Dim outfile As String, moselfile As String

'Initialize Mosel
  ret = XPRMinit
  If ret Then
    MsgBox "Initialization error (" & ret & ")"
    Exit Sub
  End If

'Compile prime4.mos
  XPRMsetdefworkdir GetFullPath()
  moselfile = GetFullPath() & "\" & "prime4"
  outfile = GetFullPath() & "\" & "vbout.txt"
  ret = XPRMcompmod(vbNullString, moselfile & ".mos", vbNullString, _
        "Prime numbers")
  If ret <> 0 Then
    MsgBox "Compile error (" & ret & ")"
    Exit Sub
  End If

'Load prime4.bim
  model = XPRMloadmod("prime4.bim", vbNullString)
  If model = 0 Then
    MsgBox "Error loading model"
    Exit Sub
  End If

'Run model with new parameter settings
  ret = XPRMrunmod(model, result, "LIMIT=500,OUTFILE=""" & Replace(outfile, _
        "\", "\\") & """")

  If ret <> 0 Then
    MsgBox "Execution error (" & ret & ")"
    GoTo done
  Else
    ShowFile outfile
  End If
  MsgBox vbNewLine & "model Prime returned: " & result

done:
  XPRMfree
End Sub

Redirecting the Mosel output

In the previous example we have hardcorded the redirection of the output directly in the model. With Mosel's VBA interface the user may also redirect all output produced by Mosel to files directly from the host application, that is, redirect the output stream.

To redirect all output of a model to the file myout.txt add the following function call before the execution of the Mosel model:

' Redirect all output to the file "myout.txt"
 XPRMsetdefstream 0, XPRM_F_OUTPUT, "myout.txt"

Similarly, any possible error messages produced by Mosel can be recovered by replacing in the line above XPRM_F_OUTPUT by XPRM_F_ERROR. This will redirect the error stream to the file myout.txt.

The following VBA program extract (file ugcb.bas) shows how to use a callback in VBA to receive all output from a Mosel model (standard output and errors). The output will be displayed in the spreadsheet from where the model run was started.

Private ROWNUM As Long
Public Sub example()
  Dim ret As Long
  Dim result As Long
  Dim module

  ClearColumn

' Initialize Mosel. Must be called first
  ret = XPRMinit
  If ret <> 0 Then
    PrintLn ("Failed to initialize Mosel")
    Exit Sub
  End If

' Redirect the output and error streams to the callback
  ret = XPRMsetdefstream(0, XPRM_F_OUTPUT, XPRM_IO_CB(AddressOf OutputCB))
  ret = XPRMsetdefstream(0, XPRM_F_ERROR, XPRM_IO_CB(AddressOf OutputCB))

  PrintLn "Starting model..."

' Run the model
  ret = XPRMexecmod("", GetFullPath() & "\" & "burglar10.mos", _
                    "FULLPATH='" & GetFullPath() & "'", result, module)
  If ret <> 0 Then
    PrintLn ("Failed to execute model")
    GoTo done
  Else
    PrintLn "Finished model"
  End If

  done:
    XPRMfree
End Sub

#If VBA7 Then
Private Sub OutputCB(ByVal model As LongPtr, ByVal ref As LongPtr, _
                    ByVal msg As String, ByVal size As Long)
  ' Output to the spreadsheet
  Call PrintLn(msg)
End Sub
#Else
Private Sub OutputCB(ByVal model As Long, ByVal ref As Long, _
                    ByVal msg As String, ByVal size As Long)
  ' Output to the spreadsheet
  Call PrintLn(msg)
End Sub
#End If

Public Sub PrintLn(ByVal msg As String)
  ' Strip any trailing newlines first
  If Right(msg, Len(vbLf)) = vbLf Then msg = Left(msg, Len(msg) - Len(vbLf))
  If Right(msg, Len(vbCr)) = vbCr Then msg = Left(msg, Len(msg) - Len(vbCr))
  Worksheets("Run Model").Cells(ROWNUM, 2) = Trim(msg)
  ROWNUM = ROWNUM + 1
End Sub

Sub ClearColumn()
  Worksheets("Run Model").Columns(2).ClearContents
  ROWNUM = 1
End Sub

Function GetFullPath() As String
  Dim path As String
  path = ThisWorkbook.path
  If Right(path, 1) = "\" Then path = Left(path, Len(path) - 1)
  GetFullPath = path
End Function

© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.