这是一个非常基本的问题,我确信它已被回答,但我似乎无法在其他地方找到它。我有一部分vba代码适用于单个单元格。但是我想将它扩展为适用于一系列单元格(所有单元格都在同一列中)。
基本上它的目标寻找循环改变了“b”列中的值,直到“w”列中的值与“x”列中的值匹配(在99%以内)。
什么有效:
Sub Goalseeker()
Do Until Range("w32").Value / Range("x32").Value > 0.99
Range("b32").Value = Range("b32").Value - 1
Loop
End Sub
我想将其扩展为第32行到第107行。 我尝试过的: 编辑:我根据收到的评论进行了调整,并在工作之前做了一些调整。如果有人对这个过程感兴趣:
Option Explicit
Sub Goalseeker()
Dim i As Integer
Dim targetcell As Double
Dim outputcell As Double
Dim variablecell As Range
For i = 32 To 107
targetcell = Cells(i, "x")
outputcell = Cells(i, "w")
Set variablecell = Range("B" & i)
Do Until outputcell / targetcell > 0.99
variablecell = variablecell - 1
targetcell = Cells(i, "x")
outputcell = Cells(i, "w")
Loop
Next
End Sub
我不得不调整的是
Do Until outputcell / targetcell > 0.99
variablecell = variablecell - 1
targetcell = Cells(i, "x")
outputcell = Cells(i, "w")
Loop
重新定义(我道歉,如果这是错误的术语)targetcell和outputcell是必要的,以防止无限循环。
谢谢大家。我将努力为相对引用而不是绝对引用此函数。
答案 0 :(得分:0)
这里几乎没有问题。将For i循环更改为格式For i = x to y
而非For i = x to i = y
您可以将targetcell
和outputcell
称为double
,但variablecell
必须是range
。如果它是range
则需要Set
您应该声明所有变量,如下所示。
最后,您可能希望放入一个捕捉以摆脱无限循环(如果目标永远不会达到0.99以上?)
Sub Goalseeker()
Dim i As Integer
Dim targetcell As Double
Dim outputcell As Double
Dim variablecell As Range
For i = 32 To 107
targetcell = Cells(i, "x")
outputcell = Cells(i, "w")
Set variablecell = Range("B" & i)
Do Until outputcell / targetcell > 0.99
variablecell = variablecell - 1
Loop
Next
End Sub
答案 1 :(得分:0)
考虑以下示例表:
使用以下代码在" B"中找到正确的值。列(如图所示),以便最小化结果(下一列)和目标(两列以上)之间的误差。
Option Explicit
Public Sub GoalSeekMyValues()
' Call GoalSeek with inputvalues "B2:B16", having the result
' at column offset 1, and the goal in column offset 2.
' Note that Range("B2").Resize(15, 1) = Range("B2:B16"),
' But I prefer the top cell and row count of this syntax.
GoalSeek Range("B2").Resize(15, 1), 1, 2
End Sub
Public Sub GoalSeek(ByVal variables As Range, ByVal result_offset As Long, ByVal goal_offset As Long)
Dim n As Long, i As Long, pct_error As Double, last_error As Double
'x is the input value (variable)
'y is the result
'g is the goal for y
Dim x As Double, y As Double, g As Double
' Read the number of rows in the input values
n = variables.Rows.Count
Dim r As Range
' Loop through the rows
For i = 1 To n
'Set a range reference at the i-th input cell
Set r = variables.Cells(i, 1)
' Read the value, the result and the goal
x = r.Value
y = r.Offset(0, result_offset).Value
g = r.Offset(0, goal_offset).Value
pct_error = Abs(y / g - 1)
Do
'Set the next value
r.Value = x - 1
' Read the result (assume goal doesn't change)
y = r.Offset(0, result_offset).Value
' Keep last error, and calculate new one
last_error = pct_error
pct_error = Abs(y / g - 1)
' If new error is more than last then exit the loop
' and keep the previous value (with less error).
If pct_error > last_error Then
' Keep last value
r.Value = x
Exit Do
End If
' read the input value
x = r.Value
' Assume inputs must be positive so end the loop
' on zero on negative numbers
Loop Until x <= 0
Next i
End Sub
您的代码有很多失败点。
您使用绝对引用(如读取第12个单元格和第4个单元格),这不是非常可重复使用的编程风格。我总是尝试使用相对引用。我从左上角引用的单元格(在本例中为B2
)开始,并使用以下方法从那里向下移动:
Range("B2").Cells(5,1)
- 参考B2
的第5行和第1列。Range("B2").Resize(15, 1)
- 展开范围以包含15行和1列。Range("B2).Cells(i,1).Offset(0, 3)
- 从i
- 行使用列偏移量3(表示表格中的第4列)。我建议使用一种常见的目标寻求方法(如二分),或者更好的是,使用内置的目标搜索功能
示例:
Range("B2").Cells(i,2).GoalSeek Goal:=Range("B2").Cells(i,3).Value, ChangingCell:=Range("B2").Cells(i,1)