简体   繁体   English

Excel VBA 宏帮助 - 必填单元格

[英]Excel VBA Macro Help - Mandatory Cells

New user, was referred to your helpful website by a friendly team member.新用户,被友好的团队成员推荐到您有用的网站。

Problem: Trying to force a user in excel to fill in a cell in a column (column O) before filling in a cell in columns IL.问题:试图强制 Excel 中的用户在填充 IL 列中的单元格之前填充列(O 列)中的单元格。 The problem lies in that not every cell in the columns needs to be filled in. I've found a VBA code that has somewhat helped but the problem is the pop up will still occur if column O is filled before there is text in just one of the cells in column IL (and therefore the error occurs unless all 4 cells in the row are filled in).问题在于并非列中的每个单元格都需要填写。我发现了一个 VBA 代码,它有点帮助,但问题是如果在只有一个文本之前填充了 O 列,仍然会出现弹出窗口IL 列中的单元格的数量(因此除非填充了该行中的所有 4 个单元格,否则会发生错误)。 As mentioned, the goal is (for example) to get O264 to be filled in first before any of the cells in column I,J,K or L264 are filled in.如前所述,目标是(例如)在填充 I、J、K 或 L264 列中的任何单元格之前先填充 O264。

Further exacerbating this issue is there are multiple rows I need this applied to, believe this is where the range fits in. However, playing with the range line in excel does not work in the way I've tried.进一步加剧这个问题的是,我需要将它应用于多行,相信这是范围适合的地方。但是,在 excel 中使用范围线并不能按照我尝试的方式工作。

Code below:代码如下:

Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("I:L")) Is Nothing Then
If Target.Cells.Count > 1 Or IsEmpty(Target) Then Exit Sub
If Target.Offset(, -1).Value = "" Then
MsgBox "You must first enter feedback in column ""O"""
Target.Value = ""
Target.Offset(, -1).Select
End If
End If
End Sub

This could be a case where you might need to aid the user a little more.在这种情况下,您可能需要更多地帮助用户。 You could do that by hiding the dependent cells, by locking them, by greying them out, etc. My feeling is that displaying a message box whenever a user enters data in the wrong order is a little too reactive.您可以通过隐藏从属单元格、锁定它们、将它们变灰等来实现这一点。我的感觉是,每当用户以错误的顺序输入数据时显示一个消息框有点过于被动。

In the example below, the target cells are locked and greyed until something is entered in column 'O'.在下面的示例中,目标单元格被锁定并呈灰色,直到在“O”列中输入内容。 You'd also need to create a list of target rows if you have more than one.如果您有多个目标行,您还需要创建一个目标行列表。

In your code behind the appropriate sheet, the skeleton code below should get you started.在相应工作表后面的代码中,下面的骨架代码应该可以帮助您入门。 I've included a couple of helper functions to make the code a little clearer for you:我已经包含了几个辅助函数,让你的代码更清晰一点:

Option Explicit

Private Const SHEET_PASSWORD As String = "xyz" 'whatever password you choose.
Private Const TARGET_ROWS As String = "2,4,6" 'your target rows, separated by commas.
Private Const TARGET_COLUMN As String = "O"
Private Const DEPENDENT_COLUMNS As String = "I:L"

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rng As Range, cell As Range

    Set rng = Intersect(Target, Me.Columns(TARGET_COLUMN))
    'Exit routine if we're not in the target column.
    If rng Is Nothing Then Exit Sub

    'Process the target column cells.
    For Each cell In rng.Cells
        If IsTargetRow(cell.Row) Then
            SetDependentStates cell
        End If
    Next
End Sub

Private Sub SetDependentStates(cell As Range)
    Dim DependentRange As Range

    'Define the Dependent range based on passed cell row.
    Set DependentRange = Intersect( _
        cell.EntireRow, _
        Me.Range(DEPENDENT_COLUMNS) _
    )

    'Lock/unlock and paint Dependent rows, based on
    'contents of passed cell.
    Application.EnableEvents = False 'prevent capture of change event.
    Me.Unprotect SHEET_PASSWORD
    With DependentRange.Cells
        If Len(cell.Value) = 0 Then
            .ClearContents
            .Locked = True
            With .Interior
                .Pattern = xlSolid
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorDark1
                .TintAndShade = -0.249977111117893
                .PatternTintAndShade = 0
            End With
        Else
            .Locked = False
            With .Interior
                .Pattern = xlNone
                .TintAndShade = 0
                .PatternTintAndShade = 0
            End With
        End If
    End With
    Me.Protect SHEET_PASSWORD
    Me.EnableSelection = xlUnlockedCells
    Application.EnableEvents = True
End Sub

Private Function IsTargetRow(rowNum As Long) As Boolean
    Dim v As Variant

    'Tests if the pass row number is in the target row list.
    For Each v In Split(TARGET_ROWS, ",")
        If CLng(v) = rowNum Then
            IsTargetRow = True
            Exit Function
        End If
    Next
End Function

Public Sub InitialiseDependentStates()
    Dim v As Variant
    Dim cell As Range

    'Define your unlocked cells.
    'This is a simple example, adjust as you wish.
    With Me
        .Unprotect SHEET_PASSWORD
        .Cells.Locked = False
        .Protect SHEET_PASSWORD
        .EnableSelection = xlUnlockedCells
    End With

    For Each v In Split(TARGET_ROWS, ",")
        Set cell = Me.Range(TARGET_COLUMN & v)
        SetDependentStates cell
    Next
End Sub

You'll likely want to initialise the dependent states when the workbook is opened.您可能希望在打开工作簿时初始化依赖状态。 Do this in the code behind the Workbook:在 Workbook 后面的代码中执行此操作:

Private Sub Workbook_Open()
    Sheet1.InitialiseDependentStates 'use whichever sheet you're using.
End Sub

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

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