【问题标题】:Non selected cells being affected when using Selection.SpecialCells(xlCellTypeVisible)'使用 Selection.SpecialCells(xlCellTypeVisible)' 时未选择的单元格受到影响
【发布时间】:2016-08-10 18:04:48
【问题描述】:

我创建了一个为当前选择添加前缀的宏。如您所见,它非常简单 - 它循环通过选择中的可见单元格。我添加了.SpecialCells(xlCellTypeVisible),因为它在使用过滤器时会影响意外的单元格。

Sub Prefix()

Dim rng As Range
Dim Prefix As String
Prefix = "P"

For Each rng In Selection.SpecialCells(xlCellTypeVisible)
    rng = Prefix & rng
Next rng

End Sub

举个例子,假设我的数据是Cells A1:A4这样填写的:

Title
1
2
1

当我执行以下操作时会出现问题:

  1. 在范围内添加Autofilter,并隐藏 A3 中的“2”
  2. 选择 A2(第一个“1”)
  3. 运行我的宏

问题在于,它不仅影响Cell A2(选定的单元格),而是开始将前缀应用于第一行(A1:Z1 等),直到我取消宏。如果我让它继续运行,它将继续对数千个单元执行此操作。

当我选择多个单元格时,或者如果我使用Selection 而不是Selection.SpecialCells(xlCellTypeVisible),或者如果我在没有过滤掉(隐藏)任何内容时将宏应用于一个单元格,则不会发生此问题。

有没有人知道为什么当我只选择一个单元格时选择默认为整个电子表格?
或者,任何人都可以建议一种使用 VBA 添加这样的前缀的方法吗?

我知道使用 excel 公式可以缓解这个问题,但这对我来说并不实用,而且也没有点击宏那么快。

【问题讨论】:

  • 很可能是因为您的子不知道选择是什么,所以它使用整个工作表。为您希望它工作的范围添加一个范围参数并将其传递给子。用该参数替换选择,它应该可以工作。
  • 请您解释一下添加范围参数的含义?我知道我可以运行 sub 来处理 Range("a2:a4").SpecialCells(xlCellTypeVisible) 或类似的东西,但我希望能够在选择中使用它,而不是每次都编辑宏。我可能会连续应用 10 个不同的选择,这些选择并不相邻,因此不值得每次都花时间编辑宏代码。
  • 如果您希望它像那样工作,它必须在工作表选择更改事件中。我很快就会发布一些东西
  • 当您说前缀时,您只是想将 p 添加到单元格中的值中吗?因为现在你的代码不应该工作,因为你没有在你的 for 循环中使用 Set for rng。
  • p 是一个例子。我实际上在做的是添加国家代码前缀,所以我使用输入框来决定代码应该是什么,具体取决于号码来自哪个国家。 Sub Prefix() 'Dim rng As Range 'Dim Prefix As String 'Prefix = InputBox("输入前缀,例如:+91", "Prefix") For Each rng In selection '.SpecialCells(xlCellTypeVisible) rng = VBA.replace(rng, "-", " ") rng = Prefix & rng Next rng End Sub

标签: vba excel selection


【解决方案1】:

您可以使用“Application.intersect”来确保获得您想要的结果:

For each rng in Application.Intersect(Selection,ActiveSheet.Cells.SpecialCells(xlCellTypeVisible))

【讨论】:

  • 还是要知道selection是什么
【解决方案2】:

如果您希望它在您手动选择一系列单元格时动态工作,并且您的意图只是将输入框中的国家代码添加到单元格的当前值,然后将下面发布的更改事件添加到代码中部分并将例程添加到工作簿中的代码模块。

不确定为什么要替换减号,但如果需要,可以将其添加到此代码中。

工作表代码:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Call AddPrefix(Target)
End Sub

添加一个模块并将这段代码放入其中。

Sub AddPrefix(rangeToPrefix)
    Dim cCell As Range
    Dim prefix As String
    prefix = InputBox("Enter your country code", "Set Country Code", +33)

    For Each cCell In rangeToPrefix.SpecialCells(xlCellTypeVisible)
        If Not IsEmpty(cCell) Then cCell.Value = prefix & cCell.Value
    Next cCell
End Sub

【讨论】:

  • 这是一个有趣的解决方案。这很难打开和关闭,并且在第二次使用时需要做一些工作。我也在努力使用它,而不是有时决定将更改应用于整个工作表(从而导致 excel 崩溃),看似随机,但大概我以某种方式滥用它。我认为另一种方法是使用我原来的方法,但使用If 检查selection.SpecialCells(xlCellTypeVisible) 是否产生错误,如果是,则改用selection
  • 我发布的代码应该只更改您用鼠标手动选择的单元格值(这会触发 selectionchange 事件),如果单元格为空,它会更改值。
猜你喜欢
  • 2021-08-20
  • 2023-02-25
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多