在工作表名称中包含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
属性:
该默认属性显然是以这样的方式实现的:它获取/设置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”))方法。