在矩阵中查找随机零的位置

在矩阵中查找随机零的位置

假设我在 Excel 中有一个矩阵,即区间 A1:E5 中的数组。每个单元格都有 0 或 1。如何在该数组中找到随机零的位置?

我看到使用 Excel 函数乘积和,我就能找到某个值对应的行和列。问题是,只有当我要查找的值是唯一的时,此过程才会起作用。

下面是我想要的一个例子:

考虑一下我的数据

A C
1 0 1 0 1 1
2 0 0 0 1 1
3 1 1 1 1 1
4 1 1 1 1 0
5 0 1 1 1 1

我想要一个可以从集合中随机选择一个输出的函数{(1,A),(1,C),(2,A),(2,B),(2,C),(4,E),(5,A)}

我所说的函数是指 Excel 单元格中的表达式。

有人知道怎么做吗?

答案1

上面/下面概述的宏似乎是最简单的方法。如果您不能使用宏,那么这里有一个繁琐的方法。

此处,G 列至 K 列代表 A 列至 E 列中值为 0 的单元格。

G2细胞公式:

    =IF(A2=0,ADDRESS(ROW(),COLUMN()-6),"")

将其拖到横向和纵向。接下来,旋转数据(使用非传统的旋转方法),单击任意绿色列。然后按 ALT-D 再按 P。这将打开“旋转向导”。

选择“多个合并范围”,然后单击“下一步”。

在此处输入图片描述

然后点击“为我创建单页字段”并按“下一步”。对于您的数据范围,请在绿色列左侧添加一个空白列。在本例中,范围是 F1:k6。点击“下一步”。

在此处输入图片描述

最后,选择要放置此数据透视表的位置,例如单元格 M3。将“值”字段放在“行”区域中。

在此处输入图片描述

最后一步,创建一个公式来从数据透视区域中选择一个随机值。单元格 P1 公式:

    =INDEX($M$5:$M$11,RANDBETWEEN(1,COUNTA($M$5:$M$11)),1)

在此处输入图片描述

由于这是一个随机公式,因此它会在工作表中每次单击时发生变化。是的,这是一项繁琐的任务,如果您有很多列,情况会更糟。

注意:除了使用数据透视表,您还可以使用公式从绿色列中提取唯一值,但如果列很多,公式可能会很长。只需查找从多列中提取不同值即可。

答案2

尝试以下用户定义函数:

Public Function RanZero(rng As Range)
    Application.Volatile
    Dim r As Range, temp As String
    Dim arr, N As Long
    Dim wf As WorksheetFunction
    Set wf = Application.WorksheetFunction
    
    For Each r In rng
        If r.Value = 0 Then
            temp = temp & "," & r.Address(0, 0)
        End If
    Next r
    
    temp = Mid(temp, 2)
    arr = Split(temp, ",")
    N = wf.RandBetween(LBound(arr), UBound(arr))
    RanZero = arr(N)
End Function

它收集全部矩阵中的单元格具有零值并返回一个随机样本。

在此处输入图片描述

用户定义函数 (UDF) 非常容易安装并使用:

  1. ALT-F11 打开 VBE 窗口
  2. ALT-I ALT-M 打开新模块
  3. 粘贴内容并关闭 VBE 窗口

如果您保存工作簿,UDF 将随之保存。如果您使用的是 2003 之后的 Excel 版本,则必须将文件保存为 .xlsm 而不是 .xlsx

消除UDF:

  1. 调出如上所示的 VBE 窗口
  2. 清除代码
  3. 关闭 VBE 窗口

使用Excel 中的 UDF:

=我的函数(A1)

要了解有关宏的更多信息,请参阅:

http://www.mvps.org/dmcritchie/excel/getstarted.htm

http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx

有关 UDF 的详细信息,请参阅:

http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx

必须启用宏才能使其工作!

答案3

如果您拥有最新版本的 Excel 365(带有LET())并且所有列都至少包含一个 0,那么您可以使用以下单元格公式来选择一个包含 0 的随机单元格:

=LET(col,RANDBETWEEN(1,COLUMNS(A1:E10)),rows,FILTER(ROW(INDEX(A1:E10,0,col)),INDEX(A1:E10,0,col)=0),ADDRESS(INDEX(rows,RANDBETWEEN(1,COUNT(rows))),COLUMN(A1)+col-1))

在此处输入图片描述

怎么运行的:

  • col,RANDBETWEEN(1,COLUMNS(A1:E10))从范围中随机选择一个列并将其存储在变量中col
  • rows,FILTER(ROW(INDEX(A1:E10,0,col)),INDEX(A1:E10,0,col)=0)计算选定列中为 0 的行号并存储在rows
  • ADDRESS(INDEX(rows,RANDBETWEEN(1,COUNT(rows))),COLUMN(A1)+col-1))生成单元格引用

相关内容