在工作表名称中包含string和单元格值

我有一个简单的工作簿,我可以从3个不同的网站买东西。 我想在编辑工作表时让标签名称更新。 工作表名称将是网站名称+所有项目的总数(单元格C27)

这就是我所拥有的macros观:

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”:types不匹配

我知道这是因为我将2个不同types的string和值组合在一起,但是我不太熟悉VBA的语法来修复它。

如果我遗漏了网站名称,它完美的作品。

什么是最简单的修复?

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

ActiveSheet.Name是一个String"Amazon"字面也是如此。 我假设ActiveSheet上的单元$B$27包含一个数值; +运算符是加法运算符,VBA会抛出一个types不匹配,因为它不知道如何使用数字添加string,因为您可以在即时窗格 (Ctrl + G)中轻松地进行复制:

 ?"foo" + 42 'type mismatch 

string连接运算符replace+运算符&修复症状和“工作”:

 ?"foo" & 42 'foo42 

但是,您需要考虑实际发生的情况,并解决问题 ,而不仅仅是症状 :当您使用string连接运算符时,VBA隐式地将所有操作数转换为string。 您可以使用CStr函数显式地进行该转换:

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

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

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

还有另一个隐式操作在这里进行:它不是将对象引用转换为string(隐式或显式),而是其默认成员的值。 如果你看对象浏览器 (F2)中的Range对象,你会发现它有一个隐藏的_Default属性:

范围。[_默认]在VBE对象浏览器中

该默认属性显然是以这样的方式实现的:它获取/设置Range.Value ; 这就是为什么这个代码编译:

 ActiveSheet.Range("B27") = 42 

正如这个代码:

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

如果没有默认成员隐式地将调用redirect到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在任何地方限定它。 实际上,只要查看vba标签中的任何随机100堆栈溢出问题,使用Worksheet对象来限定所有Range调用将为您节省大量的问题。

因此,编写处理程序的明确方法如下所示 – 请注意,有效的工作表名称必须是32个字符或更less,所以如果连接的string比这更长,则需要截断名称。 由于两个工作表不能具有相同的名称,因此如果截断的string导致工作簿中已有工作表名称,则需要执行一些操作

 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 

在这一点上,无论使用&还是+运算符都没有关系,因为+运算符完全正确地连接string……当所有的操作数都是string时 – 除了一致性和可读性之外,您一定会更喜欢连接string时使用&运算符。

评论中列出的两种解决scheme都是可行

我可以用'&'replace'+',或者使用cstr(ActiveSheet.Range(“B27”))方法。