【问题标题】:Include string and cell value in sheet name在工作表名称中包含字符串和单元格值
【发布时间】:2016-12-22 16:10:26
【问题描述】:

我有一个简单的工作簿,其中包含 3 个不同网站的工作表,我可以从这些网站购买东西。我希望在编辑工作表时更新选项卡名称。工作表名称将是网站名称 + 所有项目的总和(单元格 C27)

这是我拥有的宏:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("B27")) Is Nothing Then
        ActiveSheet.Name = "Amazon " + ActiveSheet.Range("B27")
    End If
End Sub

我收到运行时错误“13”: 类型不匹配

我知道这是因为我将 2 种不同类型的字符串和值组合在一起,但我不太熟悉 VBA 的语法,无法修复它。

如果我省略网站名称,它会完美运行。

什么是最简单的解决方法?

【问题讨论】:

  • & 不是 +,B27 范围内是什么?我相信长度和一些特殊字符是有限制的,也可以尝试在范围之后使用 .value,因为您尝试将范围和字符串结合起来
  • 您也可以尝试将“+”替换为“&”,因为不确定 Excel 是否允许前者。
  • "Amazon " + cstr(ActiveSheet.Range("B27")) 用于类型不匹配。否则,如果单元格包含错误值,则放置 CSTR,无论+& 是什么,您仍然会得到类型不匹配。长度也应该
  • 这两种解决方案都有效!谢谢大家!
  • 您绝对应该在这里和一般情况下使用与号方法。虽然两者都适用于这种情况,但 & 表示连接,而 + 表示加法。

标签: vba excel


【解决方案1】:
ActiveSheet.Name = "Amazon " + ActiveSheet.Range("B27")

ActiveSheet.NameString"Amazon" 文字也是如此。我假设ActiveSheet 上的单元格$B$27 包含一个数值; + 运算符是 addition 运算符,VBA 抛出 type mismatch 因为它不知道如何 add 带有编号,因为您可以在 立即窗格 (Ctrl+G) 中轻松重现:

?"foo" + 42
'type mismatch

+ 运算符替换为字符串连接 运算符& 修复了症状,并且“有效”:

?"foo" & 42
'foo42

但是您需要考虑真正发生了什么,并解决问题,而不仅仅是症状:当您使用string concatenation 运算符,VBA 将所有操作数隐式转换为字符串。您可以使用 CStr 函数明确转换:

?"foo" & CStr(42)
'foo42, this time without implicit conversions

ActiveSheet.Range("B27") 是一个对象 - 一个Range 对象引用:

?TypeName(ActiveSheet.Range("B27"))
Range

这里还有另一个隐式操作:它不是您要转换为字符串(隐式或显式)的对象引用,而是其默认成员的值。如果您在对象浏览器 (F2) 中查看Range 对象,您会注意到它有一个隐藏的_Default 属性:

该默认属性显然是以获取/设置Range.Value的方式实现的;这就是这段代码编译的原因:

ActiveSheet.Range("B27") = 42

这段代码也是如此:

Dim foo As Long
foo = ActiveSheet.Range("B27")

如果没有 默认成员 隐式“重定向”对 Value 的调用,这些将是非法的,因为您无法在不使用 Set 关键字的情况下分配对象引用,并且您也不能将对象引用分配给值。

请注意此处Range("B27") 之间的区别:

If Not Intersect(Target, Range("B27")) Is Nothing Then

对比这里:

ActiveSheet.Name = "Amazon " + ActiveSheet.Range("B27")

前者是Range对象,后者是它的Value。另请注意,Range("B27") 隐含地引用了ActiveSheet,因此:

Range("B27")

和这个完全一样:

ActiveSheet.Range("B27")

没有理由不明确地用ActiveSheet 来限定它。事实上,只要查看 标记中的任意 100 个 Stack Overflow 问题,使用 Worksheet 对象限定所有 Range 调用,将会为您节省很多问题。

因此,编写处理程序的 显式 方式如下 - 请注意,有效的工作表名称必须为 32 个字符或更少,因此如果连接的字符串长于那。而且由于两个工作表不能具有相同的名称,如果截断的字符串导致工作簿中已经存在工作表名称,则需要执行 something

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, ActiveSheet.Range("B27")) Is Nothing Then
        On Error Resume Next
        ActiveSheet.Name = Left$("Amazon " & CStr(ActiveSheet.Range("B27").Value), 32)
        On Error GoTo 0
        If Err.Number <> 0 Then MsgBox "Could not rename worksheet '" & ActiveSheet.Name & "'."
    End If
End Sub

此时无论您使用&amp; 还是+ 运算符都无关紧要,因为+ 运算符非常适合连接字符串...当所有操作数都是 em> 字符串 - 除了一致性和可读性,您肯定希望在连接字符串时更喜欢使用 &amp; 运算符。

【讨论】:

    【解决方案2】:

    cmets 中列出的两种解决方案都有效!

    我可以将 '+' 替换为 '&' 或使用 cstr(ActiveSheet.Range("B27")) 方法。

    【讨论】:

    • 您绝对应该在这里和一般情况下使用与号方法。尽管两者都适用于这种情况,但&amp; 用于连接,而+ 用于添加。
    猜你喜欢
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 2020-09-18
    • 2022-07-20
    • 1970-01-01
    • 2013-05-29
    相关资源
    最近更新 更多