11

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

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
4

5 回答 5

39

有没有一种方法可以在一行中转换整个范围?

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

Sub Sample()
    [A1:A20] = [INDEX(UPPER(A1:A20),)]
End Sub

或者,使用可变范围,试试这个:

Sub Sample()
    Dim rng As Range
    Set rng = Range("A1:A20")
    rng = Evaluate("index(upper(" & rng.Address & "),)")
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(),但由于我们没有UPPERlike的等价物Application.Worksheetfunction.UPPER(),我们只能把它写成[cell] = [UPPER(cell)]

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

于 2013-11-14T19:13:53.770 回答
4

您不能像这样在一行中执行此操作,但您可以在给定范围内执行此操作,例如:

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

这是相当简单和直观的。

于 2013-11-14T18:59:05.023 回答
2

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

Function UcaseRangeAsArray(TargetRng As Range) As Variant()
Dim Arr()    
Arr = Evaluate("INDEX(UPPER(" & TargetRng.Address(External:=True) & "),)")    
UcaseRangeAsArray = Arr
Erase Arr
End Function
于 2018-01-07T17:33:26.160 回答
1

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

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

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

于 2013-11-15T09:17:23.537 回答
0

关于Peter Albert提出的优雅答案,WorksheetFunctionTranspose函数有一些老式的限制;具体来说,可以翻转的元素上限为 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属性中处理单元格中受益的子过程类型。有关在选择中处理单元格的样板框架,请参阅此答案。

于 2016-02-17T03:47:04.653 回答