【问题标题】:Subtract sets after filtering in VBA在VBA中过滤后减去集合
【发布时间】:2015-08-20 21:40:28
【问题描述】:

我想从彼此中减去 2 个范围(组)。被减数(要减去的范围)包含减数(要减去的范围),这会创建一个正余数范围。请注意,被减数(基数)由过滤后的单元格组成,它们不一定相互连接。在介绍性示例之后,请参阅下面的更多内容。

例如假设被减数如下:

x1  x2  x3
A   A   A
A   A   B
A   A   C

减数如下,其中-代表什么,只是用来说明定位:

x1  x2  x3
-   -   A
-   -   -
-   -   C

那么余数应该如下:

x1  x2  x3
A   A   -
A   A   B
A   A   -

值得一提的是,由于在进行减法之前使用了过滤器,因此行被隐藏行分隔,请参阅以下可以在 Excel/VBA 中使用的示例:

X1  X2  X3
12  13  B
12  15  C
12  15  D
12  15  E
12  15  F
13  15  G
13  15  H
13  13  I
13  15  J
13  15  K
13  15  L
13  15  M
13  13  N
13  15  O
13  15  P
13  15  Q
13  15  R
13  14  S

首先我过滤第二列以仅显示“13”。这产生:

X1  X2  X3
12  13  B
13  13  I
13  13  N

那么假设我想从上面显示的范围中减去Cells(2,3)BCells(14,3)N,或者以与之前相同的方式说明:

X1  X2  X3
-   -   B
-   -   -
-   -   N

那么结果应该是:

X1  X2  X3
12  13  -
13  13  I
13  13  -

实现这个的代码(未完成):

Sub TestingStuff()

Dim y As Integer
Dim x1 As Range, x2 As Range, xs As Range

Dim ws As Worksheet: Set ws = ActiveWorkbook.ActiveSheet

ws.AutoFilterMode = False
Dim rng As Range: Set rng = ws.UsedRange
rng.AutoFilter
rng.AutoFilter Field:=2, Criteria1:="13"

Dim myR As Range: Set myR = ws.UsedRange

Set x1 = myR.Offset(1, 0).Resize(myR.Rows.count - 1).SpecialCells(xlCellTypeVisible)
Set x2 = Union(ws.Cells(2, 3), ws.Cells(14, 3))
' Set xs = SubtractRanges(x1, x2)

End Sub

将两个范围相减的代码SubtractRanges(x1, x2) 可能必须从头开始创建。我尝试了另一个来源,但不幸的是它不适用于隐藏行。 [参考见Subtracting ranges in VBA (Excel)

我愿意接受任何关于如何实现这一目标的建议。我自己的一个想法是在过滤到临时表后复制可见单元格,在那里进行减法,然后将剩余部分复制回来。然而,这个解决方案的问题是,在任何过滤之前原始完整样本的行序列都会丢失(除了地址可以以某种方式保存),而且将东西复制到临时表中以便稍后删除它们总是有点不方便.你怎么看?

简短的目标:

1) 对原始完整样本应用过滤器以创建某个子样本 2)从子样本中减去一个范围,得到余数范围 3)停用过滤器以再次获得完整样本,使用原始顺序,但同时减去相应的范围(步骤2)

为什么不直接从完整样本中删除 (2) 中的范围?问题是这样做我不会得到正确的余数范围,这是我以后工作所需要的。想象一下,我有一整套 10,000 个单位、100 个单位的子集和要从子集中减去的 40 个单位的子集,这反过来又会导致 60 个单位的剩余范围。如果我从 10,000 个单位中减去 40 个单位,那将导致 9,960 个单位,这不是正确的余数范围。我希望这会使方法更加清晰。

【问题讨论】:

  • 抱歉读了三遍我无法理解你想要做什么“然后假设我想减去 Cells(2,3) 是 B 和 Cells(14,3) 这是剩余正方形中的N”对我来说毫无意义:(。首先你能解释一下你要实现什么吗?
  • 不清楚输出...告诉更多。
  • 我添加了一个示例来更好地说明我的意思,并且我还相应地更改了最终的预期输出
  • 我删除了减去范围的代码,因为它在我的情况下不起作用并且不再需要保留它。引用仍在线程中,但如果有任何 1 想查找它。
  • 这听起来像你想要的,给定两个范围 A 和 B,一个函数返回 A 中不存在于 B 中的可见单元格。如果这不是你所要求的,那么你需要更清楚地解释自己。

标签: excel filter set subtraction vba


【解决方案1】:

使用数组来存储数据块:
子TestingStuff()

Dim y As Integer
Dim x1 As Range, x2 As Range, xs As Range

Dim ws As Worksheet: Set ws = ActiveWorkbook.ActiveSheet

ws.AutoFilterMode = False
Dim rng As Range: Set rng = Range("A1").CurrentRegion

rng.AutoFilter Field:=2, Criteria1:="13"

Dim arr() As Variant
ReDim arr(0 To 2, 0 To rng.Rows.Count)

Set x2 = Union(ws.Cells(2, 3), ws.Cells(14, 3))

j = 0

'Build array
For i = 1 To rng.Rows.Count
    If rng.Rows(i).Hidden = False Then
        arr(0, j) = rng(i, 1)
        arr(1, j) = rng(i, 2)
        arr(2, j) = rng(i, 3)
        For Each cell In x2
            If cell.Row = i Then
                arr(cell.Column - 1, j) = ""
            End If
        Next cell

        j = j + 1
    End If
Next i
ReDim Preserve arr(0 To 2, 0 To j)

Range("E25").CurrentRegion.Clear
Set xs = Range("E25:G" & 25 + j)
xs = Application.Transpose(arr)
'Do whatever you wish with the array
'such as print to another range etc, transpose it etc
'If you wanted it lined up with the original table, you
'wouldnt need to buid an array necessarily - I dont know where you want the output...

结束子

【讨论】:

  • 感谢您的回答。我认为循环遍历可见单元可能比循环和测试条件if not hidden... 更快。此外,您没有应用我要求的方法,即简单的减法或创建子集的反向。问题是在删除后我想停用过滤器并且仍然具有与原始样本相同的顺序。使用您的方法,我将所有内容都放在一个数组中,但不是我想要的位置。我需要做更多的测试。此外,您的解决方案也不完整,因为它仅适用于我展示的小示例。
  • 好的,我想和大多数人一样,我不清楚确切的要求...您想修改范围并在工作表上显示它吗?然后删除过滤器,它会返回完整的可见表并删除?
  • 是的,我相信你现在明白我的意思了。循环的行数必须是动态的;它并不总是等于 3,就像上面的最小示例一样。
猜你喜欢
  • 2012-10-09
  • 1970-01-01
  • 2016-01-18
  • 1970-01-01
  • 2022-01-23
  • 2018-11-08
  • 1970-01-01
  • 2019-11-28
  • 1970-01-01
相关资源
最近更新 更多