将整个范围转换为大写,而不循环遍历所有单元格
现在我正在使用下面的代码将小写字母列表从小写字母转换为大写字母:
Dim Tickers As String Dim n As Integer For n = 2 To Last Tickers = UCase(W.Cells(n, 1).Value) W.Cells(n, 1).Value = Tickers Next n
有没有一种方法可以将整个范围转换成一行? 就像是:
Range("A1:A20").convertouppercasesomehow
有没有一种方法可以将整个范围转换成一行?
是的,你可以转换没有循环。 尝试这个
Sub Sample() [A1:A20] = [INDEX(UPPER(A1:A20),)] End Sub
按照你的例子
W.Range("A1:A20") = [index(upper(A1:A20),)]
说明
有[A1:A20] = [INDEX(UPPER(A1:A20),)]
第1部分
如上所示, [A1:A20]
不过是写Range("A1:A20")
的简短方法
第2部分
[INDEX(UPPER(A1:A20),)]
Index
和Upper
是工作表函数。 所以你可以使用Application.Worksheetfunction.Index()
但是因为我们没有像Applicaiton.Worksheetfunction.UPPER()
那样的UPPER
,所以我们只能把它写成[cell] = [UPPER(cell)]
现在用这一行,我们正在指导VBA
返回一个数组,这是INDEX
进入的地方。 ( 正如我们所知, INDEX
函数有两种forms:数组forms和参考forms。 )通过不指定数组的行或列,我们只是让Excel知道我们想要整个数组。 ( 在VBA中提到的帮助 )所以基本上我们正在做的是将[A1:A20]
每个单元格转换为大写
你不能这样做,但你可以做一个给定的范围,如:
Sub Test() Dim Rng As Range Dim c As Range Set Rng = ActiveSheet.Range("A1:A20") For Each c In Rng c.Value = UCase(c.Value) Next c End Sub
这是另一个“单线黑客”:
Sub UCaseRange(rng As Range) rng = WorksheetFunction.Transpose(Split(UCase(Join( _ WorksheetFunction.Transpose(rng), vbBack)), vbBack)) End Sub
这假定,你的单元格都不包含vbBack字符(ASCII码8)。
关于Peter Albert提出的优雅的答案, WorksheetFunction的Transpose函数有一些老式的限制; 特别是可以翻转的65,535(最大无符号整数-1)元素的上限。 批量加载变体数组,处理“内存中”并随后将修改后的值返回到工作表可以克服该限制。
Sub test() With Worksheets("Sheet1") makeUpper .Range("A2:A1000000") End With End Sub Sub makeUpper(rng As Range) Dim v As Long, vUPRs As Variant With rng vUPRs = .Value2 For v = LBound(vUPRs, 1) To UBound(vUPRs, 1) vUPRs(v, 1) = UCase(vUPRs(v, 1)) Next v .Cells = vUPRs End With End Sub
这个过程非常快。 100K的数据通常需要不到半秒的时间,1M的单元可以在4-6秒内转换。
这是可以受益于Application.Selection属性中的单元格的子过程的types。 看到这个答案样板framwework来处理select内的单元格。