一次选择所有单元格超过限制值

时间:2012-01-11 22:21:38

标签: excel excel-vba vba

我只能选择包含数字的区域中的单元格: Region.SpecialCells(xlCellTypeConstants , xlNumbers)

但我不知道如何只选择数字以上的单元格。例如,那些高于1.0

我有一张带有数字的大表,我想把所有数字都限制在1以上,并将它们设置为1.我很乐意这样做,而不必在每个单元格上循环。

谢谢!

3 个答案:

答案 0 :(得分:4)

下面这个方法避免了逐个单元循环 - 虽然它比你的范围循环代码长得多,但我可以分享你在可能的情况下避免逐个单元格范围循环的偏好

我已从A fast method for determining the unlocked cell range更新了我的代码,以提供非单元格循环方法

  1. 代码检查SpecialCells(xlCellTypeConstants , xlNumbers) 存在于要更新的​​工作表上(错误处理应始终如此 与SpecialCells
  2. 一起使用
  3. 如果存在这些单元格,则会创建工作表,并且如果主工作表上的值,则会将公式插入到步骤1的范围内以创建故意错误(1/0)是> 1
  4. SpecialCells(xlCellTypeFormulas, xlErrors)返回工作表中一系列单元格,其值大于1(进入rng3
  5. rng3

    rng3.Value2=1的所有区域都设置为1
    Sub QuickUpdate()
    Dim ws1 As Worksheet
    Dim ws2 As Worksheet
    Dim rng1 As Range
    Dim rng2 As Range
    Dim rng3 As Range
    Dim lCalc As Long
    
    Set ws1 = ActiveSheet
    
    On Error Resume Next
    Set rng1 = ws1.Cells.SpecialCells(xlConstants, xlNumbers)
    On Error GoTo 0
    'exit if there are no contants with numbers
    If rng1 Is Nothing Then Exit Sub
    
    'disable screenupdating, event code and warning messages.
    'set calculation to manual
    With Application
        .ScreenUpdating = False
        .EnableEvents = False
        .DisplayAlerts = False
        lCalc = .Calculation
        .Calculation = xlCalculationManual
    End With
    
    ws1.Copy After:=Sheets(Sheets.Count)
    Set ws2 = ActiveSheet
    'test for cells constants > 1
    ws2.Cells.SpecialCells(xlConstants, xlNumbers).FormulaR1C1 = "=IF('" & ws1.Name & "'!RC>1,1/0,'" & ws1.Name & "'!RC)"
    On Error Resume Next
    Set rng2 = ws2.Cells.SpecialCells(xlCellTypeFormulas, xlErrors)
    On Error GoTo 0
    
    If Not rng2 Is Nothing Then
        Set rng3 = ws1.Range(rng2.Address)
     rng3.Value2 = 1    
               Else
        MsgBox "No constants < 1"
    End If
    ws2.Delete
    
    'cleanup user interface and settings
    With Application
        .ScreenUpdating = True
        .EnableEvents = True
        .DisplayAlerts = True
        lCalc = .Calculation
    End With
    
    'inform the user of the unlocked cell range
    If Not rng3 Is Nothing Then
        MsgBox "Cells updated in Sheet " & vbNewLine & ws1.Name & vbNewLine & " are " & vbNewLine & rng3.Address(0, 0)
    Else
        MsgBox "No cells updated in " & ws1.Name
    End If
    End Sub
    

答案 1 :(得分:2)

循环中有什么危害?我刚刚在39900个单元格上测试了这段代码,它以2秒的速度运行。

Sub Sample()
    Dim Rng As Range, aCell As Range

    Set Rng = Cells.SpecialCells(xlCellTypeConstants, xlNumbers)

    For Each aCell In Rng
        If aCell.Value > 1 Then aCell.Value = 1
    Next aCell
End Sub

我唯一关心的是使用SpecialCells,因为它们不可预测,因此我很少使用它们。

另请查看此知识库文章:http://support.microsoft.com/?kbid=832293

答案 2 :(得分:2)

我说,忘了SpecialCells。只需将需要测试的所有单元格加载到Variant数组中。然后遍历该数组并进行封顶。这非常有效,与在片材中循环细胞相反。最后,将其写回工作表。

50,000个单元格包含0到2之间的随机值,此代码在我的古董笔记本电脑上运行0.2秒。

额外的好处是,这是非常清晰易读的代码,您可以完全控制将要操作的范围。

Dim r As Range
Dim v As Variant
Set r = Sheet1.UsedRange
' Or customise it:
'Set r = Sheet1.Range("A1:HZ234") ' or whatever.
v = r ' Load cells to a Variant array

Dim i As Long, j As Long
For i = LBound(v, 1) To UBound(v, 1)
    For j = LBound(v, 2) To UBound(v, 2)
        If IsNumeric(v(i, j)) And v(i, j) > 1 Then
            v(i, j) = 1 ' Cap value to 1.
        End If
    Next j
Next i

r = v ' Write Variant array back to sheet.