我了解VBA无法在以下代码中动态引用变量名称,例如b
和i
,并解释它以获取b1
的值为描述here。
但我想知道是否有更优雅的方式来完成我在下面做的事情?
基本上,我希望获得7列的所有组合。
Sub combination()
Dim w(1 To 7) As Integer
Dim b(1 To 7) As Integer
'get values
For i = 1 To 7
w(i) = Cells(6, i + 1).Value
Next i
newline = 8
total = 0
For b1 = 0 To 1
For b2 = 0 To 1
For b3 = 0 To 1
For b4 = 0 To 1
For b5 = 0 To 1
For b6 = 0 To 1
For b7 = 0 To 1
b(1) = b1
b(2) = b2
b(3) = b3
b(4) = b4
b(5) = b5
b(6) = b6
b(7) = b7
For i = 1 To 7
total = total + b(i) * w(i)
Next i
Cells(newline, 1).Value = total
For i = 1 To 7
Cells(newline, i + 1).Value = b(i)
Next i
total = 0
newline = newline + 1
Next b7
Next b6
Next b5
Next b4
Next b3
Next b2
Next b1
End Sub
答案 0 :(得分:2)
如果问题是:“如何使用动态变量变量名称”,那么大多数情况下的答案是请使用数组。这不仅适用于VBA,还适用于具有“变量名称”功能的语言,例如PHP。所以使用数组绝对是正确的方法。
通过具体的例子,可以有一种更灵活的方式。您的b1
,b2
,...,b7
是二进制数字,数组b(1 to 7)
则是7个单二进制数字的数组,它们一起代表一个十进制数字值从0到127(2 ^ 7 - 1)。所以你可以有一个返回这样一个数组的函数,这个函数可以更灵活,因为它可以返回7个数字的可变长度的数组。
参见示例:
Function getBinArray(ByVal vDecimal As Double, ByVal digits As Integer) As Variant
p = 1
Dim bin() As Integer
ReDim bin(1 To digits)
Do While p < digits + 1
'remainder = vdecimal Mod (2 ^ p)
remainder = vDecimal - Int(vDecimal / (2 ^ p)) * (2 ^ p)
If remainder <> 0 Then
bin(p) = 1
vDecimal = vDecimal - (2 ^ (p - 1))
Else
bin(p) = 0
End If
p = p + 1
Loop
getBinArray = bin
End Function
Sub combination()
Dim w As Variant
Dim b As Variant
lCount = 7 'count of values to compute subtotals for
With ActiveSheet
'get values
w = .Range(.Cells(6, 2), .Cells(6, 2 + lCount - 1)).Value
newline = 8
.Range(.Rows(8), .Rows(.Rows.Count)).Clear
Total = 0
For vDecimal = 0 To 2 ^ lCount - 1
b = getBinArray(vDecimal, lCount)
For i = 1 To lCount
Total = Total + b(i) * w(1, i)
Next i
.Cells(newline, 1).Value = Total
.Range(.Cells(newline, 2), .Cells(newline, 2 + lCount - 1)).Value = b
Total = 0
newline = newline + 1
Next vDecimal
End With
End Sub
我的b()
数组按以下顺序包含二进制数字b(1)
=数字2 ^ 0,b(2)
=数字2 ^ 1,... b(n)
=数字2 ^(N-1)。