I've recently learnt about the Model-View-Presenter architectural pattern and I wanted to give it a go with a simple VBA project.
The aim is to retrieve a person's name from a UserForm.
The userform looks like this:
A user should select a team, which updates the name field > Select a name belonging to that team > Hit OK.
The control names are:
- TeamSelect
- NameSelect
- OkButton
- CloseButton
I'm particularly interested in feedback on my implementation of MVP (or lack of!)
... So here is the code:
GetName Sub - Standard Module: Macros
Public Sub GetName()
With New NamePresenter
.Present
End With
End Sub
Model - Class Module: NameModel
Private Type TNameView
Team As String
Name As String
End Type
Private this As TNameView
Public Property Get Team() As String
Team = this.Team
End Property
Public Property Let Team(ByVal value As String)
this.Team = value
End Property
Public Property Get Name() As String
Name = this.Name
End Property
Public Property Let Name(ByVal value As String)
this.Name = value
End Property
Public Property Get IsValid() As Boolean
IsValid = (this.Name <> vbNullString) And (this.Team <> vbNullString)
End Property
View - UserForm Module: NameView
Public Event UpdateNames(ByVal Team As String)
Private Type TNameView
Model As NameModel
Data As NameData
IsCancelled As Boolean
End Type
Private this As TNameView
Public Property Set Model(ByVal Model As NameModel)
Set this.Model = Model
End Property
Public Property Set Data(ByVal Data As NameData)
Set this.Data = Data
End Property
Public Property Get IsCancelled() As Boolean
IsCancelled = this.IsCancelled
End Property
Private Sub TeamSelect_Change()
this.Model.Team = TeamSelect.value
RaiseEvent UpdateNames(TeamSelect.value)
End Sub
Private Sub NameSelect_Change()
this.Model.Name = NameSelect.value
End Sub
Private Sub OkButton_Click()
If this.Model.IsValid Then
Me.Hide
Else
MsgBox "Something is missing!"
End If
End Sub
Private Sub CloseButton_Click()
this.IsCancelled = True
Me.Hide
End Sub
Private Sub UserForm_Activate()
PositionForm
TeamSelect.List = this.Data.Teams
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Cancel = True
CloseButton_Click
End Sub
Private Sub PositionForm()
With Me
.StartUpPosition = 0
.Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
.Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
End With
End Sub
Presenter - Class Module: NamePresenter
Private WithEvents View As NameView
Private Model As NameModel
Private Data As NameData
Public Sub Present()
Set View = New NameView
Set Model = New NameModel
Set Data = New NameData
With View
Set .Model = Model
Set .Data = Data
.Show vbModal
If .IsCancelled Then Exit Sub
MsgBox Model.Team & " / " & Model.Name
End With
End Sub
Private Sub View_UpdateNames(ByVal Team As String)
View.NameSelect.List = Data.Names(Team)
End Sub
Data - Class Module: NameData
Public Property Get Teams() As Variant
Teams = Array("Team1", "Team2", "Team3")
End Property
Public Function Names(ByVal Team As String) As Variant
Select Case Team
Case "Team1"
Names = Array("Name1", "Name2", "Name3")
Case "Team2"
Names = Array("Name4", "Name5", "Name6")
Case "Team3"
Names = Array("Name7", "Name8", "Name9")
End Select
End Function
Note: I've ommitted Option Explicit
only in this post to keep the code-section as short as possible