简体   繁体   English

使用目标搜寻

[英]Using Goal Seek

I'm taking apart a very old spreadsheet I wrote and trying to put it back together using VBA. 我正在分解我编写的一个非常旧的电子表格,并尝试使用VBA将其放回原处。 So far I've this, which seems to work: 到目前为止,我有这个,它似乎可以工作:

Sub PipeData()

Dim FlowRate As Single
Dim Density As Single
Dim DynamicViscosity As Single
Dim PipeSize As Single
Dim Pi As Single
Dim ReynoldsNumber As Single
Dim Lamda As Single
Dim EquivalentRoughness As Single
Dim RelativeRoughness As Single
Dim Velocity As Single
Dim PressureDrop As Single

Density = 977.8
DynamicViscosity = 0.0004
PipeSize = 36.1
Pi = WorksheetFunction.Pi()
EquivalentRoughness = 0.046
RelativeRoughness = EquivalentRoughness / PipeSize

FlowRate = Cells(2, 7)


ReynoldsNumber = (4 * FlowRate) / (DynamicViscosity * Pi * (PipeSize / 1000))

If ReynoldsNumber < 2000 Then
    Lamda = 64 / ReynoldsNumber

Else
  Lamda = ((1 / (-1.8 * WorksheetFunction.Log((6.9 / ReynoldsNumber) + ((RelativeRoughness / 3.71) ^ 1.11)))) ^ 2)

End If

Velocity = ((4 * FlowRate) / (Pi * Density * ((PipeSize / 1000) ^ 2)))

PressureDrop = ((Lamda * Density) * (Velocity ^ 2)) / (2 * (PipeSize / 1000))

End Sub

Some of the constants listed here (for example density, pipe size, etc.) I eventually intend to read from a worksheet or automatically calculate but for now I'm proceeding one step at a time. 我最终打算从工作表中读取或自动计算一些此处列出的常数(例如密度,管道尺寸等),但现在我一次只进行一个步骤。

Now that I'm satisfied that this works, which I've checked by outputting the numbers generated, I want to use Goal Seek to find the flow rate value at a certain pre-defined flow rate. 现在,我已经满意了这一点,并通过输出生成的数字对其进行了检查,现在,我想使用“目标搜索”来找到某个预先定义的流速下的流速值。

So what I want to do is have VBA cycle through different flow rate values until the desired pressure drop value is reached. 所以我要做的是让VBA循环通过不同的流量值,直到达到所需的压降值。 I will tell VBA the desired pressure drop in a cell in the Excel sheet. 我将在Excel工作表中的一个单元格中告诉VBA所需的压降。 I want this calculation to exist entirely inside VBA without any worksheet formulas. 我希望此计算完全存在于VBA中,而不需要任何工作表公式。

So I've got, in very simplified terms, the following: 因此,我得到了以下简化的信息:

(1) A starting flow rate (I guess this should be defined in the VBA code otherwise Goal Seek won't have a starting point) (1)起始流速(我想这应该在VBA代码中定义,否则目标搜寻将没有起始点)

(2) Some calculations (2)一些计算

(3) A resulting pressure drop. (3)产生的压降。

(4) If the resulting pressure drop is not equal to a pre-defined value (located in cell G3) the flow rate value in (1) should be adjusted and the calculations run again. (4)如果最终的压降不等于预定义的值(位于单元格G3中),则应调整(1)中的流速值,然后重新进行计算。

(5) When the resulting pressure drop equals the pre-defined value tell me what the flow rate value used to calculate this is. (5)当最终的压降等于预定值时,请告诉我用于计算该值的流量值是多少。

Any ideas? 有任何想法吗?

OK, I took a crack at this..there may be a better way and this assumes a direct relationship (not inverse)..i moved some of your variables into constants and put the pressure calc in a function, and changed data types to double. 好的,我对此有所了解。也许有更好的方法,并且假设存在直接关系(而不是逆关系)。我将您的某些变量转换为常量,并将压力计算值放入函数中,并将数据类型更改为双。 It is a UDF with you can use in the worksheet. 它是一个UDF,可以在工作表中使用。

Const Density As Double = 977.8
Const DynamicViscosity As Double = 0.0004
Const PipeSize As Double = 36.1
Const Pi As Double = 3.14159265358979
Const EquivalentRoughness As Double = 0.046
Const RelativeRoughness As Double = EquivalentRoughness / PipeSize
Const Sig As Double = 0.0000000001  'this indicates how accurate you want your answer
Dim FlowRate As Double
Dim ReynoldsNumber As Double
Dim Lamda As Double
Dim Velocity As Double

Function PipeData(IdealPressureDrop As Long)
    FlowRate = 1000 + Sig
    Stepper = 100
    If PressureDrop(FlowRate) > IdealPressureDrop Then
        FlowRateGoal = GoalSeek(FlowRate, Stepper, -1, IdealPressureDrop)
    Else
        FlowRateGoal = GoalSeek(FlowRate, Stepper, 1, IdealPressureDrop)
    End If
    PipeData = FlowRateGoal
End Function

Function GoalSeek(FlowRate, Stepper, Direction, IdealPressureDrop)
calcagain:
    Select Case Direction
    Case 1
        Do While PressureDrop(FlowRate) < IdealPressureDrop
            oFR = FlowRate
            FlowRate = FlowRate + Stepper                
        Loop
    Case -1
        Do While PressureDrop(FlowRate) > IdealPressureDrop
            oFR = FlowRate
            FlowRate = FlowRate - Stepper                
        Loop
    End Select
    Stepper = Stepper / 10
    If Stepper < Sig Then GoTo getout
        FlowRate = oFR
    GoTo calcagain
getout:
    GoalSeek = FlowRate
End Function

Function PressureDrop(FlowRate)
    ReynoldsNumber = (4 * FlowRate) / (DynamicViscosity * Pi * (PipeSize / 1000))
    If ReynoldsNumber < 2000 Then
        Lamda = 64 / ReynoldsNumber
    Else
        Lamda = ((1 / (-1.8 * WorksheetFunction.Log((6.9 / ReynoldsNumber) + ((RelativeRoughness / 3.71) ^ 1.11)))) ^ 2)
    End If
    Velocity = ((4 * FlowRate) / (Pi * Density * ((PipeSize / 1000) ^ 2)))
    PressureDrop = ((Lamda * Density) * (Velocity ^ 2)) / (2 * (PipeSize / 1000))
End Function

This can now be referenced in the worksheet with 现在可以在工作表中使用

=PipeData(A3)

Where "A3" is your ideal pressure drop number 其中“ A3”是您理想的压降数值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM