【问题标题】:Type mismatch when comparing two strings比较两个字符串时类型不匹配
【发布时间】:2018-12-11 20:29:38
【问题描述】:

我有以下代码将用户窗体 (GUI) 上的组合框与工作簿 sheet2 上的填充单元格进行比较,我收到“类型不匹配”错误。这一切都在起作用,直到另一个子将一些数据转移到工作表 2 上正在比较的单元格中。

我的问题在于if Worksheets(sheet2).cells(1,i).value = LCase(GUI.superCB.Value) then

Worksheets(sheet2).cells(1,i).value 现在在手表中显示为 Variant/Integer,这让我觉得当数据移动时,它改变了该单元格的“样式”。

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 以及所有内容到基本单元格(),希望它缺少工作表参考,但没有任何帮助。

【问题讨论】:

  • 工作表中是否有错误?
  • 据我所知或已引起我的注意。你能推荐我应该寻找的任何东西吗?
  • 如果没有声明变量,变量类型可能会根据数据的处理方式而改变。看起来像是将范围值与表单控件值进行比较。
  • 您是否建议像下面这样声明? Dim i As Integer Dim superColm As Integer Dim sheetName As String sheetName = Worksheets(Sheet2).Cells(1, i).Value For i = 5 To 12 If sheetName = LCase(GUI.superCB.Value) Then superColm = i Exit For Else End If Next i

标签: excel vba type-mismatch


【解决方案1】:

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 索引器需要整数值或字符串。如果Sheet2ThisWorkbook 中工作表的代号,则无需从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 插件项目)。

【讨论】:

  • 问题是 Worksheets 被使用。我通常改用Sheets。我没有发现这种差异。
  • @DavidS Worksheets/Sheets 没有区别。唯一的区别是Sheets 可以为您提供Chart 对象,这是另一种问题 - 如果您正在寻找Worksheet,您应该使用Worksheets。问题是 Worksheet 对象正在作为参数传递...以检索 相同的工作表 - 首先甚至不需要集合查找,假设 Sheet2Worksheet 而不是 String
  • Mathieu 感谢您抽出宝贵时间给我们写这篇文章。我想我能听懂你说的大部分内容。可悲的是,我认为我的问题是我以某种方式将我的iRange= 移到了设置变量的位置上方。我还同时将 .value 更改为 .text ,所以这也可能有所帮助。如果它回来,我会记住错误检查。谢谢大家!
  • @MathieuGuindon 你对rows 有什么建议? lastrow = Sheet2.Cells(Rows.Count, superColm).End(xlUp).Row
  • @Gman 您确实意识到 iRange= 在您的原始问题中无处可寻(iRange 错误与您的类型不匹配无关),并且 VBA 始终无缝地执行隐式类型转换- 没有整数/字符串比较会引发类型不匹配; Empty 很高兴地转换为空字符串以进行比较,并且工作表单元格永远不会是 Nothing。无论如何,请注意隐含的ActiveSheet 引用。 Rows.Count 是一个,是的,lastRow 将是一个更好的名称,用于表示“最后一行”的东西。
【解决方案2】:

这将通过首先检查范围对象数据类型来解决。

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 作为范围。如果范围对象可能是 EmptyNothing ,那么您还需要检查这些。

编辑:将 .Value 更改为 .Text Edit2:这个答案不正确。

【讨论】:

  • David S 我试了一下,我在iRange= worksheets(sheet2).cells(1,i).value 上遇到了同样的错误(运行时 13 类型不匹配)我们接下来可以尝试什么? cells(1,i) 仍然在手表中显示类型变体/整数。
  • GUI.superCB.value 在手表中显示 Type-variant/String。
  • 出错时引用的单元格中的实际值是多少? @Gman
  • @Gman 看到马修的回答。我们都错过了,但他明白了。
  • @Gman 并不是我很关心 +15,但为什么要在承认不正确的答案上打勾?
猜你喜欢
  • 1970-01-01
  • 2013-05-13
  • 2015-07-31
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2022-03-30
  • 1970-01-01
相关资源
最近更新 更多