在工作表名称中包含字符串和单元格值

时间:2016-12-22 16:10:26

标签: excel vba excel-vba

我有一个简单的工作簿,上面有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的语法以便能够修复它。

如果我遗漏了网站名称,它就能完美运作。

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

2 个答案:

答案 0 :(得分:5)

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

ActiveSheet.NameString"Amazon"字面量也是如此。我假设$B$27上的单元格ActiveSheet包含数值; +运算符是添加运算符,VBA抛出类型不匹配,因为它不知道如何添加带有数字的字符串,因为您可以在立即窗格中轻松复制(Ctrl + G):

?"foo" + 42
'type mismatch

使用字符串连接运算符+替换&运算符可修复症状,并且"有效":

?"foo" & 42
'foo42

但是,您需要考虑真正正在进行什么,并修复问题,而不仅仅是症状:如果使用字符串连接运算符,VBA会隐式将所有操作数转换为字符串。您可以使用CStr函数明确转换:

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

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

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

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

Range.[_Default] in the VBE Object Browser

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

ActiveSheet.Range("B27") = 42

与此代码一样:

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

隐含地没有默认成员&#34;重定向&#34;对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问题,使用Range对象限定所有Worksheet次调用即可为您节省大量问题。

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

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

在这一点上,使用&+运算符并不重要,因为+运算符可以很好地连接字符串...所有操作数都是字符串 - 除了一致性和可读性之外,在连接字符串时,您肯定希望使用&运算符。

答案 1 :(得分:0)

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

我可以替换&#39; +&#39;用&#39;&amp;&#39;或者使用cstr(ActiveSheet.Range(&#34; B27&#34;))方法。