将整个范围转换为大写,而不循环遍历所有单元格

时间:2013-11-14 18:50:35

标签: excel excel-vba range uppercase vba

现在我正在使用以下代码将股票代码列表从小写字母转换为大写字母:

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

5 个答案:

答案 0 :(得分:30)

  

我可以用一种方法将整个范围转换成一行吗?

是的,您可以在不循环的情况下进行转换。试试这个

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),)]

IndexUpper是工作表函数。因此,您可以使用Application.Worksheetfunction.Index(),但由于我们没有像UPPER这样的Application.Worksheetfunction.UPPER(),因此我们只能将其写为[cell] = [UPPER(cell)]

现在有了这一行,我们正在指示VBA返回一个数组,这就是INDEX发挥作用的地方。 (我们知道,INDEX函数有两种形式:数组形式和引用形式。)通过不指定数组的行或列,我们只是让Excel知道我们想要整个数组。 (在VBA帮助中提及)所以基本上我们正在做的是将[A1:A20]中的每个单元格转换为大写

答案 1 :(得分:3)

你不能在这样的一行中做到这一点,但你可以在给定的范围内这样做:

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

这是相当简单和直观的。

答案 2 :(得分:1)

这是另一个“单线黑客”:

Sub UCaseRange(rng As Range)
    rng = WorksheetFunction.Transpose(Split(UCase(Join( _
        WorksheetFunction.Transpose(rng), vbBack)), vbBack))
End Sub

这假设您的单元格都不包含vbBack字符(ASCII代码8)。

答案 3 :(得分:1)

我从各种来源收集的信息:

Function UcaseRangeAsArray(TargetRng As Range) As Variant()
Dim Arr()    
Arr = Evaluate("INDEX(UPPER(" & TargetRng.Address(External:=True) & "),)")    
UcaseRangeAsArray = Arr
Erase Arr
End Function

答案 4 :(得分:0)

关于Peter Albert提出的优雅答案,WorksheetFunction Transpose函数有一些旧的限制;特别是有一个可以翻转的65,535(最大无符号整数-1)元素的上限。批量加载变体数组,处理“内存中”&#39;然后将修改后的值返回到工作表可以克服该限制。

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属性中的单元格处理中受益的子过程的类型。请参阅this answer了解样板框framwework以处理选择中的单元格。