【问题标题】:Excel VBA - How do I select a range corresponding to values in previous cells?Excel VBA - 如何选择与先前单元格中的值对应的范围?
【发布时间】:2012-11-15 19:42:19
【问题描述】:

我有一组非常大的数据,其中包括 NAS 中飞机的开始和停止时间。我想创建一个宏来在 excel 中对这些数据进行可视化表示,如下所示:

(注意:此图片使用假数据)

如您所见,我已经手动完成了前 7 行,但是有几个数据文件,每个文件多达 2500 多行,这使得这个过程很乏味。我尝试创建一个宏,但我很困惑如何搜索和选择要突出显示的适当范围。

这是我目前所拥有的:

Sub autofill()

    Dim rng As Range
    Dim row As Range
    Dim cell As Range

    'set the range of the whole search area
    Set rng = Range("A2:HJ121")

    For Each row In rng.Rows
        Dim callsign As Variant
        Set callsign = cell("contents", "A" & row)
        Dim valstart As Variant
        Set valstart = cell("contents", "E" & row)
        Dim valstop As Variant
        Set valstop = cell("contents", "F" & row)

        'now select the range beginning from the column whose header matches the
        'time in valstart and ends at the time which matches the time in valstop

        Selection.Merge
        Selection.Style = "Highlight"
        Selection.Value = callsign
    Next row

End Sub

选择我需要的行的最简单方法是什么?

我不是专业的程序员;如果我的代码展示了草率的技术或违反了一些神圣的编程原则,请提前道歉。 :P

谢谢!

【问题讨论】:

    标签: search excel selection vba


    【解决方案1】:

    这是我在 VBA 上的尝试。

    Option Explicit
    
    Public Sub fillSchedule()
        Dim startCol As Long
        Dim endCol As Long
        Dim i As Long
        Dim j As Long
    
        Dim ws As Excel.Worksheet
        Dim entryTime As Single
        Dim exitTime As Single
        Dim formatRange As Excel.Range
    
        Set ws = ActiveSheet
    
        startCol = ws.Range("H:H").Column
        endCol = ws.Range("HJ:HJ").Column
    
        Call clearFormats
    
        For i = 2 To ws.Cells(1, 1).End(xlDown).Row
            entryTime = ws.Cells(i, 5).Value
            exitTime = ws.Cells(i, 6).Value
            Set formatRange = Nothing
    
            For j = startCol To endCol
                If (ws.Cells(1, j).Value > exitTime) Then
                    Exit For
                End If
    
                If ((entryTime < ws.Cells(1, j).Value) And (ws.Cells(1, j).Value < exitTime)) Then
                    If (formatRange Is Nothing) Then
                        Set formatRange = ws.Cells(i, j)
                    Else
                        Set formatRange = formatRange.Resize(, formatRange.Columns.Count + 1)
                    End If
                End If
            Next j
    
            If (Not formatRange Is Nothing) Then
                Call formatTheRange(formatRange, ws.Cells(i, "A").Value)
            End If
        Next i
    End Sub
    
    Private Sub clearFormats()
        With ActiveSheet.Range("H2:HJ121")
            .clearFormats
            .ClearContents
        End With
    
    End Sub
    Private Sub formatTheRange(ByRef r As Excel.Range, ByRef callsign As String)
    
        r.HorizontalAlignment = xlCenter
        r.Merge
    
        r.Value = callsign
    
        ' Apply color
        With r.Interior
            .Pattern = xlSolid
            .PatternColorIndex = xlAutomatic
            .ThemeColor = xlThemeColorLight2
            .TintAndShade = 0.799981688894314
            .PatternTintAndShade = 0
        End With
    
        ' Apply borders
        With r.Borders(xlEdgeLeft)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With r.Borders(xlEdgeTop)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With r.Borders(xlEdgeBottom)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
        With r.Borders(xlEdgeRight)
            .LineStyle = xlContinuous
            .ColorIndex = 0
            .TintAndShade = 0
            .Weight = xlThin
        End With
    End Sub
    

    【讨论】:

    • 非常感谢!这非常接近完美。唯一的问题是它在我的所有工作表上的某个时间点都遇到了运行时错误,尽管时间不同。它处理了一些工作表大约一半,其他只处理前 10 行。 Run-time error '91': Object variable or With block variable not set,指向行r.HorizontalAlignment = xlCenter。此外,它没有选择它应该选择的第一个单元格,但我认为如果我稍微看一下代码,这应该很容易修复:)
    • 很高兴为您提供帮助! :) 另外,我知道出了什么问题。当代码为此行返回 false 时:“If ((entryTime
    • 伟大的思想都一样!我自己更改了确切的代码,还做了一个小改动,将所有列移到左侧(因为我更喜欢在单元格的开头概念化时间的开始而不是结束:P)。我做的唯一另一件事是将您的样式代码更改为简单的formatRange.Style = "Highlight" :P 顺便说一句,我会对此表示赞同,但我不能——没有足够的代表! :( 还需要 10 个...
    • 我很高兴你能成功 :) 是的,伟大的思想都一样,哈哈。不用担心投票。我很高兴能提供帮助!
    【解决方案2】:

    条件格式解决方案怎么样?

    突出显示从 H2 到(右下角最后一个单元格)的所有单元格。

    使用这个公式:

    =IF(AND((H$1>$E2),(H$1<$F2)),TRUE)
    

    然后应用填充。如果您愿意放弃填充范围内的边框和名称,它会为您工作:)。

    此外,您可能希望从 G2 冻结窗格,这样您就可以一直滚动到 HJ 列并仍然看到 Callsign 列。

    希望对你有帮助

    【讨论】:

    • 不幸的是,我确实需要名称和边框:\——但感谢关于我以前没有使用过的冻结窗格的提示,即使我无法让它工作——冻结 3 个需要的列(呼号、入口、出口)加上第一行。对我来说更简单的解决方案是隐藏 B、C、D 和 G 列并在 H2 处拆分。
    • 很惊讶您无法让冻结窗格工作。如果您单击 D2(单独单击 D2,然后单击 View->Freeze Panes->Freeze Panes),我认为它应该可以工作。
    猜你喜欢
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多