如何使用 VBA 在 Excel 的 5 列中获取 "yes" 和 "No" 的排列?
How to use VBA to get permutations of "yes" and "No" across 5 columns in Excel?
我需要在五列中列出 Yes/No 的所有排列。例如,{是,是,是,是,是},{是,是,是,是,否},{是,是,是,否,否},{是,是,否,否,否} , ETC...
see this screenshot
问题是我只想到了那几个,我认为总数是 120...是否有一些 VBA 代码可以 运行 获得所有排列?
我不会给你一个 VBA 解决方案,而是一个你可以实现的算法:只要把每个“否”想象成数字 0,把每个“是”想象成数字 1。你创建二进制系统中的所有数字,从“00000”到“11111”(因此从 0 到 31)。
那么,您需要做的是:
You take every number from 0 to 31, and for every number:
You convert it into binary format.
In that binary format, replace every 0 by a "No" and every 1 by a "Yes".
Find a way to fill your Excel sheet with the corresponding results.
祝你好运
这应该将所有组合打印到相应的 rows/columns。用户需要 select header 正下方的左上角单元格。
Dim i As Long, ii As Long, iii As Long, iiii As Long, iiiii As Long
Dim j As Long, jj As Long
Dim str As String
Dim rng As Range
Dim arr(1) As String
arr(0) = "yes"
arr(1) = "no"
Dim arr_rows() As String
Dim arr_columns() As String
' five nested loops (each for a column)
' the idea is to have all possibilities (yes or no) covered
' each row is taken care of by adding vbNewLine
For i = LBound(arr) To UBound(arr)
For ii = LBound(arr) To UBound(arr)
For iii = LBound(arr) To UBound(arr)
For iiii = LBound(arr) To UBound(arr)
For iiiii = LBound(arr) To UBound(arr)
str = str & arr(i) & "," & arr(ii) & "," & arr(iii) & "," & arr(iiii) & "," & arr(iiiii) & vbNewLine
Next iiiii
Next iiii
Next iii
Next ii
Next i
' splitting the string created in the loop by new line character
' (i.e. obtaining an array with an element for each row)
' for each row splitting by a comma
' (i.e. obtaining another array with an element for each column)
arr_rows = Split(str, vbNewLine)
Set rng = Selection
For j = LBound(arr_rows) To UBound(arr_rows)
arr_columns = Split(arr_rows(j), ",")
For jj = LBound(arr_columns) To UBound(arr_columns)
rng.Offset(j, jj) = arr_columns(jj)
Next jj
Next j
您不需要 VBA 来执行此操作。以下工作表公式可帮助您实现目标。
Select 单元格 B2
并粘贴此公式:
=CHOOSE(1+MID(LEFT("00000",5-LEN(DEC2BIN(32-ROW()+1)))&DEC2BIN(32-ROW()+1),COLUMN()-1,1),"No","Yes")
现在将该公式复制到此范围:B2:F33
就是这样。
当然,之后,您可能希望复制结果并粘贴为值,以便在单元格中包含硬值而不是公式。
下面是如何在 VBA 中执行此操作,如果您更喜欢编码解决方案:
Option Explicit
Sub DisplayYesNoPerms()
Dim rows&, cols&
cols = 5
rows = 2 ^ cols
[b2].Resize(rows, cols) = YesNoPerms(rows, cols)
End Sub
Function YesNoPerms(rows&, cols&)
Dim i&, j&, t$, v
ReDim v(0 To rows - 1, 1 To cols)
For i = 0 To rows - 1
t = Format(DecToBin(i), String(cols, "0"))
For j = 1 To cols
v(i, j) = IIf(Mid(t, j, 1), "No", "Yes")
Next
Next
YesNoPerms = v
End Function
Function DecToBin$(ByVal n&)
Do
DecToBin = n Mod 2 & DecToBin
n = n \ 2
Loop While n
End Function
我需要在五列中列出 Yes/No 的所有排列。例如,{是,是,是,是,是},{是,是,是,是,否},{是,是,是,否,否},{是,是,否,否,否} , ETC... see this screenshot
问题是我只想到了那几个,我认为总数是 120...是否有一些 VBA 代码可以 运行 获得所有排列?
我不会给你一个 VBA 解决方案,而是一个你可以实现的算法:只要把每个“否”想象成数字 0,把每个“是”想象成数字 1。你创建二进制系统中的所有数字,从“00000”到“11111”(因此从 0 到 31)。
那么,您需要做的是:
You take every number from 0 to 31, and for every number:
You convert it into binary format.
In that binary format, replace every 0 by a "No" and every 1 by a "Yes".
Find a way to fill your Excel sheet with the corresponding results.
祝你好运
这应该将所有组合打印到相应的 rows/columns。用户需要 select header 正下方的左上角单元格。
Dim i As Long, ii As Long, iii As Long, iiii As Long, iiiii As Long
Dim j As Long, jj As Long
Dim str As String
Dim rng As Range
Dim arr(1) As String
arr(0) = "yes"
arr(1) = "no"
Dim arr_rows() As String
Dim arr_columns() As String
' five nested loops (each for a column)
' the idea is to have all possibilities (yes or no) covered
' each row is taken care of by adding vbNewLine
For i = LBound(arr) To UBound(arr)
For ii = LBound(arr) To UBound(arr)
For iii = LBound(arr) To UBound(arr)
For iiii = LBound(arr) To UBound(arr)
For iiiii = LBound(arr) To UBound(arr)
str = str & arr(i) & "," & arr(ii) & "," & arr(iii) & "," & arr(iiii) & "," & arr(iiiii) & vbNewLine
Next iiiii
Next iiii
Next iii
Next ii
Next i
' splitting the string created in the loop by new line character
' (i.e. obtaining an array with an element for each row)
' for each row splitting by a comma
' (i.e. obtaining another array with an element for each column)
arr_rows = Split(str, vbNewLine)
Set rng = Selection
For j = LBound(arr_rows) To UBound(arr_rows)
arr_columns = Split(arr_rows(j), ",")
For jj = LBound(arr_columns) To UBound(arr_columns)
rng.Offset(j, jj) = arr_columns(jj)
Next jj
Next j
您不需要 VBA 来执行此操作。以下工作表公式可帮助您实现目标。
Select 单元格 B2
并粘贴此公式:
=CHOOSE(1+MID(LEFT("00000",5-LEN(DEC2BIN(32-ROW()+1)))&DEC2BIN(32-ROW()+1),COLUMN()-1,1),"No","Yes")
现在将该公式复制到此范围:B2:F33
就是这样。
当然,之后,您可能希望复制结果并粘贴为值,以便在单元格中包含硬值而不是公式。
下面是如何在 VBA 中执行此操作,如果您更喜欢编码解决方案:
Option Explicit
Sub DisplayYesNoPerms()
Dim rows&, cols&
cols = 5
rows = 2 ^ cols
[b2].Resize(rows, cols) = YesNoPerms(rows, cols)
End Sub
Function YesNoPerms(rows&, cols&)
Dim i&, j&, t$, v
ReDim v(0 To rows - 1, 1 To cols)
For i = 0 To rows - 1
t = Format(DecToBin(i), String(cols, "0"))
For j = 1 To cols
v(i, j) = IIf(Mid(t, j, 1), "No", "Yes")
Next
Next
YesNoPerms = v
End Function
Function DecToBin$(ByVal n&)
Do
DecToBin = n Mod 2 & DecToBin
n = n \ 2
Loop While n
End Function