【问题标题】:Dynamic target for intersect method in VBAVBA中相交方法的动态目标
【发布时间】:2016-02-16 22:46:18
【问题描述】:

背景: 我需要帮助调整我之前通过复制粘贴编写的代码。该函数的目标是在单击目标单元格时以指定格式添加新行。

这是通过以下代码实现的[仅摘录]:

Private Sub worksheet_selectionchange(ByVal target As Range)
If Not Intersect(target, Range("G6")) Is Nothing Then
  Rows("7:7").Select
  Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
  Range("B7:F7").Select
  With Selection.Font
    .ColorIndex = xlAutomatic
    .TintAndShade = 0
  End With

到目前为止,它也可以正常工作。但是现在我想再次将此功能添加到同一个选项卡以用于另一个单元格范围。我现在遇到的问题是,由于相关行是垂直堆叠的,所以每当我通过原始函数添加一行时,第二个例程中定义的范围现在不再起作用。

我的问题: 我可以动态定义 Intersect 方法的范围吗?我的想法会有点笨拙,比如让第二种方法引用一个变量而不是由第一个例程自动更改的固定单元格(MyRange)(例如 MyRange = MyRange + 1)。我该怎么做?或者还有其他方法可以实现我想做的吗?

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    您的想法是正确的 - 预先定义变量而不是在代码中硬编码值是可维护代码的构建块之一。有很多方法可以做到这一点,包括让 Excel 搜索关键字等。

    我对您的情况的建议是您查看 Excel 中的名称管理器,并定义一个新名称,该名称指的是您希望您的子用户监视的所有单元格。如果您这样做,Excel 将跟踪这些单元格,就像您只是在单元格中键入公式一样。即:如果您输入单元格 C5:“=A5+B5”,并且在 B 列的左侧插入一个新列,C5 现在将自动读取“=A5+C5”。这样,您的 VBA 代码不会改变,但您定义的 Name 中的值会改变。

    在不确切知道您的工作表是如何设置的情况下,以下是您如何实际执行此操作的示例:

        Private Sub worksheet_selectionchange(ByVal Target As Range)
    
        Dim MyRange As Range
        Dim CurrentRow As Integer
        Dim FormattedArea As Range 'This will hold the area of your row which you want formatted
        Const LeftColumn = 2 'this holds the left-most column of the area you want formatted...
        Const RightColumn = 6 'these hardcoded numbers will need to be changed if you want to format a different number of columns; if you have a dynamic way of determining them that would be best
    
        Set MyRange = Range("Possible_Areas") 'This makes MyRange = your defined, Excel-tracked name; you will need to go to the name manager in Excel and create it, listing all target cells you want included within it
        CurrentRow = Target.Row 'This will be used to find where to insert the new row, based on the current selection        
    
        If Not Intersect(Target, MyRange) Is Nothing Then
            Target.EntireRow.Insert 'Notice that I have removed your "selection" command - you can search this site for reasons on why ".Select" is problematic
            Set FormattedArea = Range(Cells(CurrentRow, LeftColumn), Cells(CurrentRow, RightColumn))
            With FormattedArea.Font
                .ColorIndex = xlAutomatic
                .TintAndShade = 0
            End With
        End If
    End Sub
    

    【讨论】:

    • 关于第 6 行代码的 cmets,如何动态定义要格式化的列数?
    • @Zeiram 这取决于这些列是什么——它们是否具有一致的标题名称?然后使用 Find 命令搜索这些名称。它们总是位于现在单元格 A1 右侧的 1 列和 5 列吗?然后标记单元格 A1 并向右工作。除了您可能想在这些位置之间和之前插入列之外,它们是否总是相同的?然后命名一个范围并使列 # 等于这些名称的列值 [就像我们为另一个命名范围所做的那样]。你还没有告诉我这些列真正代表什么,所以我无法直接回答。
    • @Zeiram 如果您在已经提出的问题之上还有一个新问题,您应该在网站上提出一个新问题;它使答案对于可能正在搜索与您相关的特定问题的个人用户更有价值。
    猜你喜欢
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 2013-04-04
    • 2016-10-07
    相关资源
    最近更新 更多