Несоответствие типов при сравнении двух строк - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть следующий код, который сравнивает комбинированный список в пользовательской форме (GUI) с заполненной ячейкой на листе 2 моей рабочей книги, и я получаю ошибку «несоответствие типов».Это все работало до тех пор, пока другой сабвуфер не переместил некоторые данные в ячейки, сравниваемые на листе 2.

Моя проблема связана с if Worksheets(sheet2).cells(1,i).value = LCase(GUI.superCB.Value) then

Worksheets(sheet2).cells(1,i).value Теперь отображается в часах как вариант/ Целое число, которое заставило меня думать, что когда данные были сдвинуты, это изменило «стиль» этой ячейки.

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

Если у меня есть лист 2 в качестве активного листа, то, однако, Cells(1,i).value будет работать, мне нужнов конце есть лист 2, скрытый от пользователя.Эта работа заставляет меня думать, что стиль ячейки не имеет значения.

Я пытался перейти на Excel.Workbooks("Shawn_sch_v1.2.xlsm").worksheets(sheet2).cells(1,i).value и все, вплоть до базовых ячеек (), надеясь, что отсутствует ссылка на лист, но ничего не помогло.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

A String можно безопасно сравнить с любым другим типом данных в VBA ... , за исключением Error.

Сравнение Variant/Error с чем-либо выдаст несоответствие типов ошибка.

Этот код неявно обращается к тому, что ActiveSheet есть:

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

Cells должен быть квалифицирован с конкретным объектом Worksheet, который вы имеете в видуработать с.Если активный лист содержит значение, которое не может быть приведено к String (например, #VALUE! или #REF!), это приведет к ошибке несоответствия типов .

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

Здесь Sheet2 - это идентификатор .Индексатору Worksheets требуется либо целочисленное значение, либо строка.Если Sheet2 является кодовым именем рабочего листа в ThisWorkbook, вам не нужно извлекать его из Worksheets - просто используйте его:

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

Класс Worksheet не делаетимеет свойство по умолчанию , поэтому Debug.Print Worksheets(Sheet2) выдает ошибку 438 объект не поддерживает это свойство или метод - и последующий вызов члена, такой как .Cells(1, i), также выдает несоответствие типов ошибка.Если у вас нет строковой переменной Sheet2, содержащей имя листа, я подозреваю, что это ошибка, с которой вы столкнулись прямо сейчас ... что означает, что все вышеперечисленное - это то, что вас ждет:)

Если Sheet2 является строковой переменной, которая содержит действительное имя листа, вы можете использовать функцию IsError, чтобы проверить, является ли Variant 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

Наконец, я бы посоветовал не использовать Rows в качестве глобальной переменной, поскольку это уже идентификатор глобальной области ([_Global].Rows, косвенно ссылающийся на ActiveSheet).Теперь переименовать эту переменную с помощью Find / Replace будет довольно сложно, не нарушая ваш код: рефакторинг Rubberduck «переименование», вероятно, может помочь сделать это безопасно (отказ от ответственности: я управляю этим OSS VBIDEпроект надстройки).

0 голосов
/ 11 декабря 2018

Это будет исправлено, если сначала проверить тип данных объекта диапазона.

Worksheets(Sheet2).Cells(1, i).Value - это объект диапазона.Это может изменять типы данных каждый раз, когда диапазон изменяется в зависимости от того, как он изменяется.

LCase(GUI.superCB.Value) Похоже, это элемент управления формы.Если диапазон является целым числом, они не могут сравниваться.

Попробуйте что-то вроде этого:

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

Идея состоит в том, чтобы сначала убедиться, что типы данных совпадают.

Возможно, вам придется использовать .Text или .Value2 вместо .Value для диапазона.Если возможно, что объект диапазона будет Empty или Nothing, то вам также необходимо проверить их тоже.

Редактировать: Изменено .Value на .Text Редактировать2: Этот ответ неверен.

...