代码没有产生正确的值 - 循环中的公式根据0到360的增量找到最小值

时间:2014-10-24 13:58:00

标签: loops excel-vba vba excel

我已经搜索了线程,看看是否有任何特定的问题,但是,我没有找到任何与我需要的相匹配的东西。我有一个公式,实际上有几个公式,它们随着圆周的角位置而变化。到目前为止,我一直在使用excel并以1度的增量创建角度范围,并简单地使用每个单元格的公式来计算值。但是,该文件已经非常大,而且由于许多公式随角度变化,因此学习如何执行此操作会很有用。

在所有情况下,我都是从0度到360度循环,想要找到最大值或最小值。到目前为止我使用的代码如下(在这个阶段为我可怕的笨重和糟糕的编程道歉 - 我对此很新): -

Function C_1c_Long(Radius, rm)

Dim phi As Double
Dim C_1c As Integer
Dim Angle As Integer
Dim pi As Double
Dim C_1cphi As Integer

Angle = 0
pi = Application.WorksheetFunction.pi

Do

C_1cphi = (2 * Radius + rm * Sin(phi)) / (2 * (Radius + rm * Sin(phi)))
Angle = Angle + 1
phi = Application.WorksheetFunction.Radians(Angle)

Loop Until C_1c < C_1cphi

C_1c = C_1cphi

C_1c_Long = C_1c

End Function

提前致谢 - 我知道这可能非常简单,但在谈到VBA时我很害怕!

1 个答案:

答案 0 :(得分:0)

让我们从可以帮助您编写任何VBA程序的技术问题开始:

1)在测试它作为循环条件之前,你没有将C_1c设置为等于任何东西。 VBA自动将其设置为0,这可能是您想要的,也可能不是。{初始化变量总是一个好主意,这样无论谁在阅读你的代码(就像你从现在开始的6个月后)都会知道你在想什么。

2)您已将C_1cC_1cphi声明为Integer,但之后您尝试将浮点数存储到其中。这可能会导致您失去所需的精度。

3)您尚未提供Radiusrm的类型。在这种情况下,很明显你想要数字。并且,它们没有必要是整数,所以我将它们都声明为Double。另外你知道你将返回一个数字(正确的知道,Integer,但基于(2)它也应该是一个双数),所以我也会声明它。这变成了

Function C_1c_Long(Radius as Double, rm as Double) as Double

如果您将来希望在编写代码时有一个不知道变量类型的函数,只需将其声明为Variant即可。这是再一次,所以你很清楚谁会在你以后读到你的代码。

现在回答如何解决最大化功能问题的问题。

简短的回答是扔掉你的代码。因为这是一个连续的问题(你怎么知道最大值不是65.45502269421度?)只搜索整数并不是一个好主意。所以这里有两个问题的替代解决方案

1)如果您了解微积分,那么这是直截了当的,您可以手动计算它,并适当地编写解决方案(我假设,没有编写错误检查代码,Radius > rm):< / p>

Function C_1c_Long(Radius As Double, rm As Double) As Double
    C_1c_Long = (2 * Radius - rm) / (2 * Radius - 2 * rm)
End Function

2)如果您不知道微积分,那么您可以应用Excel附带的求解器来执行此操作,方法是将公式放在一个单元格中,将角度置于另一个单元格中,并告诉求解器通过更改来最大化公式角度。

3)为了完整起见,这里是如何调整算法以找到整数度的最大值。声明一个变量来保持最大值。然后,循环遍历所有的整数,并将该值与当前最大值进行比较。并且,在这种情况下,我们可以将最大值初始化为第一个计算值,或者将某个数字初始化为可能值范围之外的数字。

Function C_1c_Long(Radius As Double, rm As Double) As Double

Dim phi As Double
Dim Angle As Double
Dim C_1cphi As Double
Dim max As Double

phi = Application.WorksheetFunction.Radians(0#)
max = (2 * Radius + rm * Sin(phi)) / (2 * (Radius + rm * Sin(phi)))

For Angle = 1 To 360
    phi = Application.WorksheetFunction.Radians(0#)
    C_1cphi = (2 * Radius + rm * Sin(phi)) / (2 * (Radius + rm * Sin(phi)))
    If C_1cphi > max Then
        max = C_1cphi
    End If
Next Angle

C_1c_Long = C_1cphi

End Function