Home » excel » excel – Type mismatch when comparing two strings

excel – Type mismatch when comparing two strings

Posted by: admin May 14, 2020 Leave a comment

Questions:

I have the following code that is comparing a combobox on a userform(GUI) to a populated cell on sheet2 of my workbook and I am getting a “type mismatch” error. This was all working until another sub shifted some data into the cells being compared on sheet 2.

My issue lies with if Worksheets(sheet2).cells(1,i).value = LCase(GUI.superCB.Value) then

Worksheets(sheet2).cells(1,i).value Now shows up in the watch as a Variant/Integer which made me think that when the data was shifted it changed the “style” of that cell.

Private Sub NextButton_Click() ''' adds check boxes to frame

Dim i As Integer
'Dim superColm As Integer
For i = 5 To 12
    If Worksheets(Sheet2).Cells(1, i).Value = LCase(GUI.superCB.Value) Then 'problem line is right here
        superColm = i
        Exit For
    Else
    End If
Next i

NextButton.Visible = False
superCB.Visible = False

Run.Visible = True
Frame1.Visible = True



    Dim chk As Control
    Dim idx As Integer

    Dim lastrow As Integer
    lastrow = Worksheets(Sheet2).Cells(Rows.Count, superColm).End(xlUp).Row

    For idx = 1 To lastrow - 1
        Set chk = GUI.Frame1.Controls.add("Forms.CheckBox.1", idx, True)
        'set chk = gui.Frame1.Controls.Add(
        chk.Visible = True
        chk.Left = 5
        chk.Top = (idx - 1) * (chk.Height + 2)
        chk.Caption = Cells(idx + 1, superColm) & "   " & idx
    Next
    With Me.Frame1
        .ScrollBars = fmScrollBarsVertical
            If lastrow <= 10 Then
                .ScrollHeight = .InsideHeight * 1.5
            ElseIf lastrow <= 15 Then
                .ScrollHeight = .InsideHeight * 2.25
            ElseIf lastrow <= 20 Then
                .ScrollHeight = .InsideHeight * 3
            ElseIf lastrow <= 25 Then
                .ScrollHeight = .InsideHeight * 3.9
            ElseIf lastrow <= 30 Then
                .ScrollHeight = .InsideHeight * 4.75
            ElseIf lastrow <= 35 Then
                .ScrollHeight = .InsideHeight * 5.35
            Else
                .ScrollHeight = .InsideHeight * 6.25
            End If
        .ScrollWidth = .InsideWidth * 9
    End With
End Sub

If I have sheet 2 as the active sheet Cells(1,i).value will work however, I need to have sheet 2 hidden from the user in the end. With this working it makes me think that the cell style is not the issue.

I have tried going to Excel.Workbooks("Shawn_sch_v1.2.xlsm").worksheets(sheet2).cells(1,i).value and everything down to the base cells() hoping it was missing a sheet reference but nothing has helped.

How to&Answers:

A String can safely be compared against any other data type in VBA… except Error.

Comparing a Variant/Error against anything will throw a type mismatch error.

This code is implicitly accessing whatever ActiveSheet is:

chk.Caption = Cells(idx + 1, superColm) & "   " & idx

Cells should be qualified with the specific Worksheet object you mean to work with. If the active sheet contains a value that can’t be coerced into a String (e.g. #VALUE! or #REF!), that will throw a type mismatch error.

Worksheets(Sheet2).Cells(1, i).Value = ...

Here Sheet2 is an identifier. The Worksheets indexer wants either an integer value, or a string. If Sheet2 is the code name of a worksheet in ThisWorkbook, you don’t need to dereference it from Worksheets – just use it:

Sheet2.Cells(1, i).Value = ...

The Worksheet class doesn’t have a default property, so Debug.Print Worksheets(Sheet2) throws error 438 object doesn’t support this property or method – and a subsequent member call like .Cells(1, i), also throws a type mismatch error. If you don’t have a Sheet2 string variable holding a worksheet name, I suspect that’s the bug you’re having right now… which means everything above is just what’s waiting to bite you 🙂

If Sheet2 is a string variable that contains a valid sheet name, you can use the IsError function to verify whether a Variant is a Variant/Error:

If Not IsError(Sheet2.Cells(1, i).Value) Then
    ' value is safe to compare against a string
Else
    ' comparing the cell value to anything will throw error 13
End If

Lastly, I would advise against using Rows as a global variable, since it’s already a global-scope identifier ([_Global].Rows, implicitly referring to ActiveSheet). Now, renaming that variable with Find/Replace is going to be pretty hard to do without breaking your code: Rubberduck‘s “rename” refactoring could probably help with doing that safely (disclaimer: I manage that OSS VBIDE add-in project).

Answer:

This will be fixed with doing a check on the range object data type first.

Worksheets(Sheet2).Cells(1, i).Value is the range object. This can change data types every time the range is modified depending on how it is modified.

LCase(GUI.superCB.Value) This appears to be a form control. If the range is an integer, they cannot compare.

Try something like this:

Dim i As Integer
Dim iRange as String
'Dim superColm As Integer
`This is untested
For i = 5 To 12
iRange = Worksheets(sheet2).Cells(1, i).Text
If iRange = LCase(GUI.superCB.Value) Then 'problem line is right here
    superColm = i
    Exit For
Else
End If
Next i

The idea is to first be sure that the data types are the same.

You may need to use .Text or .Value2 instead of .Value for the range. If it is possible that the range object will be Empty or Nothing , then you also need to check for those too.

Edit: Changed .Value to .Text
Edit2: This answer is incorrect.