【问题标题】:Combination with no repeat in Excel including reducing rowsExcel中不重复的组合,包括减少行数
【发布时间】:2022-10-13 04:43:55
【问题描述】:

我的数据集看起来像这样

AAAA
BBBB
CCCC
DDDD
EEEE
FFFF

我想删除第一行和第二行,然后我想删除第一行和第三行,然后是第一行和第四行,依此类推。 接下来,第二和第三行,第二和第四行等等。

CCCC   BBBB   BBBB
DDDD   DDDD   CCCC
EEEE   EEEE   EEEE
FFFF   FFFF   FFFF

有谁知道如何在 Excel 中实现它?

【问题讨论】:

  • 只是为了了解所涉及的组合数量,根据您的示例,您的数据集是否固定为六个项目,还是可能更多?如果有,还要多少?
  • 它固定在六个项目

标签: excel vba excel-formula combinations stochastic


【解决方案1】:

更适合VBA,但鉴于您的数据集仅限于六个项目,这也可以通过Office 365 公式实现:

=LET(ζ,A1:A6,ξ,SEQUENCE(5556,,1111),λ,FILTER(ξ,MMULT(N(ISNUMBER(FIND(SEQUENCE(,6),ξ))),SEQUENCE(6,,,0))=4),TRANSPOSE(INDEX(ζ,UNIQUE(MAKEARRAY(ROWS(λ),4,LAMBDA(α,β,SMALL(0+MID(INDEX(λ,α),SEQUENCE(,4),1),β)))))))

【讨论】:

  • 谢谢!你能解释一下你的想法吗?
  • SEQUENCE(5556,,1111) 生成一个从 1111 到 6666 的整数数组。然后将该数组减少,使其包含来自 1-6 整数集中的四个项目的 15 个唯一组合。然后使用这个简化的数组来索引范围A1:A6
【解决方案2】:

请测试下一个代码。它将处理您显示的范围,位于"A1:A" & x 并从“C2”开始返回:

Sub RemoveIncrementedRows()
  Dim arr, arrRes, i As Long, k As Long, c As Long, lastR As Long
  
  'the range to be processed should be in "A1:A"
  lastR = Range("A" & rows.count).End(xlUp).row
  arr = Range("A2:A" & lastR).Value2 'place the range in an array for faster iteration
  ReDim arrRes(1 To UBound(arr) - 1, 1 To UBound(arr) - 1) 'ReDim the result array
  For k = 1 To UBound(arrRes)
    For i = 1 To UBound(arr)
           If i <> k Then
               c = c + 1
               arrRes(c, k) = arr(i, 1)
          End If
    Next i
    c = 0 'reinitialize the variable to keep the result array rows
  Next k
  'drop the result array content at once (in "C2")
  Range("C2").Resize(UBound(arrRes), UBound(arrRes, 2)).Value2 = arrRes
End Sub

它能够处理位于“A:A”中的更多值,计算最后一行。

我想“AAAA”、“BBBB”等只是类似的例子,你会使用不同的字符串。否则,也可以自动构建包含该字符串的数组...

【讨论】:

  • 我赞成它,但后来注意到它一次只删除一行而不是 2 行,所以可能需要一个 mod?
  • @Tom Sharpe 是的,但是要处理的范围开始了从第二排,所以第一行也被删除了...... :) 尝试根据要求检查结果。我观察到它可以以那种(简单的)方式被移除。
  • OP 确实继续说 ...[delete] 第二行和第三行,第二行和第四行等等...所以我猜它们确实是指@Jos Woolley 建议的所有 15 种组合,其中一些确实包括第一行.
  • @Tom Sharpe 他准确地说删除第一行和第二行,然后我要删除第一行和第三行,然后是第一行和第四行,依此类推.因此,所有情况下都删除了 first 。你可以看到在他/她的例子中(前三个处理结果),其中上述逻辑/理解看起来得到确认(我认为......)。我还认为 OP 应该测试代码并确认(或确认)代码做了他/她希望的(我理解)......
  • 是的,OP 需要表达意见——我没有更多要补充的了。
【解决方案3】:

我已经玩了一段时间了,想知道我是否可以从字面上理解 OP 的指令,并从全套 90 行中排除第一行和第二行、第一行和第三行等以留下 60 行,然后将数组重塑为15套四套:

=LET(n,6,r,4,C,COMBIN(n,r),range,A2:A7,
rows,SEQUENCE(n*C,1,0),
pairs,SEQUENCE(n*n,1,0),
filterPairs,FILTER(pairs,MOD(pairs,n)>QUOTIENT(pairs,n)),
filter,INDEX(filterPairs,QUOTIENT(rows,n)+1),
filterRows,FILTER(rows,(MOD(rows,n)<>QUOTIENT(filter,n))*(MOD(rows,n)<>MOD(filter,n))),
select,MOD(filterRows,n)+1,
WRAPCOLS(INDEX(range,select),r))

【讨论】: