简体   繁体   English

随机选择单元格清除内容 - Excel VBA

[英]Randomly Selecting Cells for Clearing Contents - Excel VBA

I currently have rows of merged cells.我目前有几行合并的单元格。 I need a way to randomly select 50% of these cells to clear the contents of through VBA.我需要一种方法来随机 select 50% 的这些单元格来清除通过 VBA 的内容。

This is what I have so far:这是我到目前为止所拥有的:

Sub DelFifty()
Dim rng As Range
Dim i As Long, x As Long, y As Long

Set rng = Range("B1:M36")

On Error GoTo ErrHandler

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

For i = 1 To Int(rng.Cells.Count * 0.5)
retry:
    x = WorksheetFunction.RandBetween(1, rng.Rows.Count)
    y = WorksheetFunction.RandBetween(1, rng.Columns.Count)
    If rng.Cells(x, y) <> "" Then
        rng.Cells(x, y).ClearContents
    Else
        GoTo retry
    End If
Next i

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

ErrHandler:
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

End Sub

Here is my code:这是我的代码:

Sub SubClearMergedCells()

    'Declarations
    Dim WksWorksheet01 As Worksheet
    Dim RngRange01 As Range
    Dim RngTarget As Range
    Dim BlnAlreadyCleared() As Boolean
    Dim LngCounter01 As Long
    Dim LngCellsToBeCleared As Long
    Dim DatTimer As Date
    Dim DblMaximumTime As Double

    'Setting variables.
    Set WksWorksheet01 = Sheets(ActiveSheet.Name)       'put here the sheet where your range is placed
    Set RngRange01 = WksWorksheet01.Range("B5:E11")     'put here the address of the range
    LngCellsToBeCleared = 4                             'put here the number of cells you want to be cleared
    DblMaximumTime = 10                                 'put here the maximum time (in seconds) you want to wait before the code is terminated
    DblMaximumTime = DblMaximumTime / 24 / 3600
    DatTimer = Now + DblMaximumTime

    'Reallocating BlnAlreadyCleared to cover the entire RngRange01.
    ReDim BlnAlreadyCleared(1 To RngRange01.Rows.Count)

    'Repeating until LngCellsToBeCleared is reached.
    Do Until LngCounter01 >= LngCellsToBeCleared

        'Seeding the Rnd function (not strictly necessary, it just "improves the quality" of the random result).
        Randomize

        'Setting RngTarget as a random cell within RngRange01.
        Set RngTarget = RngRange01.Cells(Round(Rnd * (RngRange01.Rows.Count - 1), 0) + 1, 1)

        'Checking if the maximum time has beed reached.
        If Now > DatTimer Then
            MsgBox "The subroutine is taking too much to complete its task. It will be terminated.", , "Maximum time reached"
            Exit Sub
        End If

        'Checking if the range has been already cleared.
        If BlnAlreadyCleared(RngTarget.Row - RngRange01.Row + 1) = False Then

            'Clearing contents of RngTarget merged cell.
            WksWorksheet01.Range(RngTarget, RngTarget.Offset(0, RngRange01.Columns.Count)).ClearContents

            'Setting BlnAlreadyCleared to mark the proper row as cleared.
            BlnAlreadyCleared(RngTarget.Row - RngRange01.Row + 1) = True

            'Setting LngCounter01 for the next cell to be cleared.
            LngCounter01 = LngCounter01 + 1

        End If

    Loop

End Sub

I guessed your cells are merged by rows.我猜你的单元格是按行合并的。 You could not clear their contents because you were addressing only one of them.您无法清除它们的内容,因为您只针对其中之一。 To address them all, i've used the Worksheet.Range method combined with the Range.Offset method and Range.Columns.Count method.为了解决所有这些问题,我将 Worksheet.Range 方法与 Range.Offset 方法和 Range.Columns.Count 方法结合使用。 The rest of the code is on principle quite similar to your own (i've just used an array variable to mark the cells i've already cleared instead of looking to their contents).代码的 rest 原则上与您自己的非常相似(我只是使用数组变量来标记我已经清除的单元格,而不是查看它们的内容)。 A possible problem to these kind of approaches can be time.这些方法的一个可能问题是时间。 A greater list with an high percentage of data to be cleared could take a lot.要清除的数据比例较高的更大列表可能需要很多时间。 Since the range we've used is small, there should be no problem.由于我们使用的范围很小,所以应该没有问题。 Anyway i've added a timer to make sure that the subroutine doesn't go on forever trying to randomly picking the not yet picked cells.无论如何,我已经添加了一个计时器,以确保子程序不会永远尝试随机选择尚未选择的单元格。

EDIT: here is the same code edited according to the further instructions:编辑:这是根据进一步说明编辑的相同代码:

Sub SubClearMergedCellsByValue()

    'Declarations
    Dim WksWorksheet01 As Worksheet
    Dim RngRange01 As Range
    Dim RngTarget As Range
    Dim LngCellsToBeCleared As Long
    Dim DatTimer As Date
    Dim DblMaximumTime As Double

    'Setting variables.
    Set WksWorksheet01 = Sheets(ActiveSheet.Name)       'put here the sheet where your range is placed
    Set RngRange01 = WksWorksheet01.Range("B5:E11")     'put here the address of the range
    LngCellsToBeCleared = 4                             'put here the number of cells you want to be cleared
    DblMaximumTime = 10                                 'put here the maximum time (in seconds) you want to wait before the code is terminated
    DblMaximumTime = DblMaximumTime / 24 / 3600
    DatTimer = Now + DblMaximumTime

    'Reallocating BlnAlreadyCleared to cover the entire RngRange01.
    ReDim BlnAlreadyCleared(1 To RngRange01.Rows.Count)

    'Repeating until LngCellsToBeCleared is reached.
    Do Until Excel.WorksheetFunction.CountBlank(RngRange01.Columns(1)) >= LngCellsToBeCleared

        'Seeding the Rnd function (not strictly necessary, it just "improves the quality" of the random result).
        Randomize

        'Setting RngTarget as a random cell within RngRange01.
        Set RngTarget = RngRange01.Cells(Round(Rnd * (RngRange01.Rows.Count - 1), 0) + 1, 1)

        'Checking if the maximum time has beed reached.
        If Now > DatTimer Then
            MsgBox "The subroutine is taking too much to complete its task. It will be terminated.", , "Maximum time reached"
            Exit Sub
        End If

        'Checking if the range has been already cleared.
        If RngTarget.Value <> "" Then

            'Clearing contents of RngTarget merged cell.
            WksWorksheet01.Range(RngTarget, RngTarget.Offset(0, RngRange01.Columns.Count)).ClearContents

        End If

    Loop

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM