0

I want to create a little input box function where the user's input can only be months of the year (January, February, March etc), I figured it could be done via utilizing a variant variable (months). However, I am getting a type mismatch error , is what im trying to achieve achievable? thanks.

Sub test()

Dim NewName As Variant, Months As Variant
Months = Split("January,February,March,April,May,June,July,August,September,October,November,December")

Re_Enter_NewName:
NewName = InputBox("Please Write Month- Case Sensitive", "MONTH", vbOKCancel)

For Each Months In NewName ''Type Mismatch
If NewName = Months Then
Exit Sub

ElseIf NewName <> Months Then
 MsgBox "Please Enter a Month of the Year"
 GoTo Re_Enter_NewName:
Else
End If

Next Months

End Sub
0

2 Answers 2

1

I would use two functions:

One function to create the array with valid months - please check the code below: you have to use array not split. Alternatively you could read the valid month names from a worksheet or create the list automatically etc.

One generic function to check if a value is within an array

Option Explicit

Sub testGetMonthsName()

Dim MonthSelected As Variant, arrMonths As Variant
arrMonths = getMonthArray

Re_Enter_NewName:
MonthSelected = InputBox("Please Write Month- Case Sensitive", "MONTH")

If MonthSelected = vbNullString Then
    'cancel or empty
    Exit Sub

ElseIf isValueInArray(MonthSelected, arrMonths) Then
    'MonthSelected is valid
    Exit Sub
    
Else
    'MonthSelected is not valid
    MsgBox "Please Enter a Month of the Year"
    GoTo Re_Enter_NewName:
End If

End Sub


Private Function getMonthArray() As Variant
getMonthArray = Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
End Function

Private Function isValueInArray(value As Variant, arrValues As Variant) As Boolean
Dim i As Long
For i = LBound(arrValues) To UBound(arrValues)
    If arrValues(i) = value Then
        isValueInArray = True
        Exit For
    End If
Next
End Function

Based on comment from @ChristanBuse - a more advanced version:

Option Explicit

Sub test_getMonthFromUser()

Dim strMonth As String, cancel As Boolean

Do
    strMonth = getMonthNameFromUser(cancel)
    If cancel = True Then Exit Sub
    
    If isMonthNameValid(strMonth) = False Then
        If MsgBox("Please enter a valid month name", vbOKCancel + vbExclamation) = vbCancel Then
            Exit Do
        Else
            strMonth = vbNullString
        End If
    End If
Loop Until LenB(strMonth) > 0

If LenB(strMonth) > 0 Then
    MsgBox "Valid month selected: " & strMonth
End If

End Sub

Private Function getMonthNameFromUser(ByRef cancel As Boolean) As String

Dim strMonth As String
strMonth = InputBox("Please Write Month- Case Sensitive", "MONTH")

If StrPtr(strMonth) = 0 Then
    cancel = True
    Exit Function
End If

getMonthNameFromUser = strMonth

End Function


Private Function isMonthNameValid(strMonth As String) As Boolean
'will check according to systems language
'e.g. in German: Januar - in English: January
Dim i As Long
For i = 1 To 12
    If MonthName(i) = strMonth Then
        isMonthNameValid = True
        Exit For
    End If
Next
End Function

Sign up to request clarification or add additional context in comments.

4 Comments

I would add the Cancel check If StrPtr(MonthSelected)= 0 Then Exit Sub and leave the blank case as part of the re-enter logic. Better to use a Do... Loop Until... loop and remove the GoTo entirely. Cleaner. For the rest +1
Oh, and maybe use a Collection instead of an array of months then the isValueInArray would not be needed as you could check if the element exists by key
@CristianBuse: you are right - there is more to refactor (e.g. I would at least create the months-array/collection automatically) - but I am not sure whether a collection or array is "better" - I think it's more an individual preference.
@CristianBuse added a second, refactored version
0

You should also handle case when user cancels input box to prevent endless work

Sub test()
  Dim NewName As Variant, Months As Variant, mname, UserMonth
  UserMonth = ""
  'Months = Split("January,February,March,April,May,June,July,August,September,October,November,December")
  'Months is Variant/String array (1 element)
  'be sure to specify delimiter (comma)
  Months = Split( _
    "January,February,March,April,May,June,July,August,September,October,November,December", _
    ",")
    'Months is Variant/String array (12 elements)
Re_Enter_NewName:
  NewName = InputBox("Please Write Month- Case Sensitive", "MONTH", vbOKCancel)
  
  'For Each Months In NewName 'Type Mismatch: for each array in string
  For Each mname In Months
    If NewName = mname Then
      UserMonth = mname
    End If
  Next mname
  If UserMonth = "" Then
    MsgBox "Please Enter a Month of the Year"
     GoTo Re_Enter_NewName:
  End If
End Sub

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.