【问题标题】:Extending VB Code to Fill Excel Cells If Column Name Matches Data Validation如果列名匹配数据验证,则扩展 VB 代码以填充 Excel 单元格
【发布时间】:2013-03-13 11:29:05
【问题描述】:

我们目前在 Excel 工作簿中有一些 VB 代码,它允许选择多个数据验证(列表下拉列表)选项,然后对于从列表中选择的每个下拉项目,它会在行尾输出选项,每列一个选项。

即:从下拉列表中选择 Apples、Bananas 和 Cherries 将输出 Apples |香蕉 | Cherries(其中 | 是列分隔符)位于第一个单元格为空的行的末尾。

我们的代码是:-

Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo exitHandler

Dim rngDV As Range
Dim iCol As Integer

If Target.Count > 1 Then GoTo exitHandler

On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler
If rngDV Is Nothing Then GoTo exitHandler
If Intersect(Target, rngDV) Is Nothing Then
   'do nothing
Else
  Application.EnableEvents = False
   If Target.Column = 3 Then
    If Target.Value = "" Then GoTo exitHandler
    If Target.Validation.Value = True Then
     iCol = Cells(Target.Row, Columns.Count).End(xlToLeft).Column + 1
     Cells(Target.Row, iCol).Value = Target.Value
   Else
     MsgBox "Invalid entry"
     Target.Activate
    End If
  End If
End If

exitHandler:
  Application.EnableEvents = True

End Sub

然而,我们希望在此 VB 代码中进行修改,而不是使用选定的数据验证填充行尾的单元格。我们想填充列标题与从下拉列表中选择的选项匹配的列下的单元格。

即:在下拉列表中选择的苹果将填充该行上标有“苹果”的列下的单元格。在下拉列表中选择的樱桃将填充该行上标有“樱桃”的列下的单元格。理想情况下,通过填充,我们会为该单元格着色或在其中放置一个 X,而不是重复所选项目的名称。

如果有人能建议我们在上面的代码中需要修改什么,将不胜感激。

【问题讨论】:

  • 你能发一个示例文件吗?
  • 如何发布示例文件?我应该把它上传到 Dropbox 或类似网站并提供一个链接吗?
  • 是的 - Dropbox 很好。
  • 给你布雷特。谢谢参观。如果您查看“已排序”工作表上的代码,您将看到 VBA 代码。您将看到 C 列包含数据验证,我可以在其中选择多个选项,在此示例中,基于此标准,我希望自动填充/着色相应的列 D-M(尽管最终这里会有很多列)。按照目前的情况,它将每个选择的选项添加到下一个可用的空闲列 (AI),然后每列添加一个选项。 dl.dropbox.com/u/8388505/guest-posts.xlsx谢谢
  • #Update# 我现在已经删除了上面的链接文件(我认为它没有包含代码,因为我将它保存为 .xls)。

标签: excel vba


【解决方案1】:

我已按照您的要求修改了您的代码,它遍历列标题以找到正确的列,然后更改相应单元格的背景颜色。
更新:添加了一项检查以防止无限循环。

Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo exitHandler

Dim rngDV As Range
Dim iCol As Integer, iColumnHeaderRow As Integer
iColumnHeaderRow = 3 'change this if header row changes

If Target.Count > 1 Then GoTo exitHandler

On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler
If rngDV Is Nothing Then GoTo exitHandler
If Not Intersect(Target, rngDV) Is Nothing Then
    Application.EnableEvents = False
    If Target.Column = 3 Then
        If Target.Value = "" Then GoTo exitHandler
        If Target.Validation.Value = True Then
            'iterate through column headers to find the matching column
            iCol = (Target.Column + 1)
            Do Until Cells(iColumnHeaderRow, iCol).Value = Target.Value
                iCol = iCol + 1
                'if we've hit a blank cell in the header row, exit 
                '(also to prevent an infinite loop here)
                If Cells(iColumnHeaderRow, iCol).Value = "" Then GoTo exitHandler
            Loop

            'set fill color of appropriate cell
            With Cells(Target.Row, iCol).Interior
                .Pattern = xlSolid
                .PatternColorIndex = xlAutomatic
                .ThemeColor = xlThemeColorAccent6
                .TintAndShade = 0.599993896298105
                .PatternTintAndShade = 0
            End With
        Else
            MsgBox "Invalid entry"
            Target.Activate
        End If
    End If
End If

exitHandler:
    Application.EnableEvents = True
End Sub

【讨论】:

  • 感谢您的回答罗斯。这是完美的,并且正是我们需要它做的事情。尽管有两个答案都实现了我们想要的,但我将这个标记为正确答案,因为它是更完整的代码,需要更少的手动更改来实现。再次感谢!
  • @GeoffJackson 谢谢,我很高兴能帮上忙。如果验证的条目与列标题不匹配,我刚刚更新了代码以防止潜在的 SO。
  • 这不是抱怨,没办法。但在 excel 中处理代码时,请始终考虑使用单元格名称。这使您可以移动列而不用担心由于错误的列/行号而修复代码。
  • @Daniel 我同意,为了使其更具可扩展性,我会将列标题全部放在一个命名范围内,即“类别”,并将该命名范围用于验证和循环内。这种方式也可以让您使用 for 循环遍历有限列表,从而无需进行测试以防止 SO。然后要向系统添加类别,您只需插入一列并更新命名范围,无需调整代码。
【解决方案2】:

替换

Cells(Target.Row, iCol).Value = Target.Value

Cells(Target.Row, Range(Target.Value).Column).Value = "X"

注意:只有在您命名标题单元格时它才会起作用。例如,Range("Banana") 将引用您命名为“香蕉”的单元格。

要命名,请使用屏幕左上角的文本框。该文本框最初只包含单元格坐标,例如“A1”、“B2”等。单击您要命名的标题单元格,转到此文本框并输入“香蕉”或任何其他与您的下拉值匹配的名称。 用所有下拉值命名所有标题(缺少一个会导致错误)。

(你可以放弃 iCol 计算)

【讨论】:

  • 感谢您的回答丹尼尔,这确实是我想要的,非常感谢。纯粹基于另一个答案不需要我们制作相同名称的标题单元格这一事实,我会接受另一个答案是正确的,因为这对于这个问题的未来观众来说会更容易(不带走任何“正确性”) '虽然来自你的回答)。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多