我编写了一个自定义VBA函数,当我在VBA中调用它时它将起作用。 e.g。
Sub test()
Debug.Print calculate_acr_bands_data("recommended_acr", "22/11/2014", 2.67, "B23:C27", 50, 2.14, 1, 0.107, 3.89, "22/02/2021")
End Sub
输出......
0.01
但是,当我在excel工作簿中的单元格内调用完全相同的函数时。我收到错误"此公式中使用的值是错误的数据类型"。这没有任何意义,因为我刚刚证明该公式与VBA中的完全相同的输入一起工作。
如果您想查看源代码,我已将我的回购上传到我的GitHub帐户...
https://github.com/Joshua-W-Adams/vba-wall-loss-vs-time
感谢您的帮助。
更新
功能已发布在以下...
'Description: Calculate database of wall loss vs time information so relevant parameters can be returned
Public Function calculate_acr_bands_data(return_parameter As String, last_inspection_date As Date, last_inspection_date_wall_loss As Double, _
acr_bands_array_text As String, nominal_wall_thickness As Double, _
minimum_allowable_wall_thickness As Double, current_acr As Double, actual_cr As Double, current_rl As Double, current_end_of_life As Date) As Variant
'Create copy of data range so nominal wall thickness value is not overriden
Dim acr_bands_array As Range: Set acr_bands_array = ThisWorkbook.Worksheets("Wall_Loss_Vs_Time_Graph").Range(acr_bands_array_text)
Dim n As Integer: n = 0
Dim acr_bands_array_size As Integer: acr_bands_array_size = acr_bands_array.Rows.Count
Dim return_data_array() As BAND_ARRAY_CLASS
Dim current_band_position As Integer
Dim recommended_acr As Double
Dim recommended_rl As Double
Dim forecast_wall_loss As Double
Dim recommended_end_of_life As Date
'Update band array with fail FFS wall thickness of current cml
acr_bands_array(acr_bands_array.Rows.Count, 1) = nominal_wall_thickness - minimum_allowable_wall_thickness
'Determine current band that the last inspection date wall loss falls into
For n = 1 To acr_bands_array_size - 1
If last_inspection_date_wall_loss < acr_bands_array(n + 1, 1) Then
current_band_position = n
Exit For
End If
Next n
'Push first row to array (last inspection date details)
return_data_array = push_to_array(return_data_array, "Band Data Points", Format(last_inspection_date, "Short Date"), last_inspection_date_wall_loss, acr_bands_array(current_band_position, 2))
'Debug.Print return_data_array(0).graph_name
'Debug.Print return_data_array(0).date_value
'Debug.Print return_data_array(0).wall_loss
'Debug.Print return_data_array(0).acr
'Push all corrosion rate band data
If n <> 0 Then 'If a hole out is not detected
For n = current_band_position To acr_bands_array_size - 1
return_data_array = push_to_array(return_data_array, _
"Band Data Points", _
Format(DateAdd("d", (acr_bands_array(n + 1, 1) - return_data_array(UBound(return_data_array)).wall_loss) / acr_bands_array(n, 2) * 365, return_data_array(UBound(return_data_array)).date_value), "Short Date"), _
acr_bands_array(n + 1, 1), _
acr_bands_array(n, 2))
Next n
End If
'Push data for current wall loss as of today
For n = 1 To UBound(return_data_array) - 1
If Now() < return_data_array(n + 1).date_value Then
return_data_array = push_to_array(return_data_array, _
"Band Data Points", _
Format(Now(), "Short Date"), _
return_data_array(n).acr * DateDiff("d", return_data_array(n).date_value, Now()) / 365 + return_data_array(n).wall_loss, _
return_data_array(n).acr)
'Dim rsize As Integer
'rsize = UBound(return_data_array)
'Debug.Print return_data_array(rsize).graph_name
'Debug.Print return_data_array(rsize).date_value
'Debug.Print return_data_array(rsize).wall_loss
'Debug.Print return_data_array(rsize).acr
Exit For
End If
Next n
recommended_acr = (return_data_array(UBound(return_data_array) - 1).wall_loss - return_data_array(UBound(return_data_array)).wall_loss) _
/ (return_data_array(UBound(return_data_array) - 1).date_value - return_data_array(UBound(return_data_array)).date_value)
forecast_wall_loss = return_data_array(UBound(return_data_array)).wall_loss
recommended_end_of_life = return_data_array(UBound(return_data_array) - 1).date_value
recommended_rl = DateDiff("d", return_data_array(UBound(return_data_array) - 1).date_value, Now()) / 365
Debug.Print recommended_acr
Debug.Print forecast_wall_loss
Debug.Print recommended_end_of_life
Debug.Print recommended_rl
'Debug.Print recommended_rl
'Add additional graph data for reference
return_data_array = push_to_array(return_data_array, "Today", DateValue(Format(Now(), "Short Date")), 0, 0)
return_data_array = push_to_array(return_data_array, "Today", DateValue(Format(Now(), "Short Date")), nominal_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Recommended RL", DateValue(Format(recommended_end_of_life, "Short Date")), 0, 0)
return_data_array = push_to_array(return_data_array, "Recommended RL", DateValue(Format(recommended_end_of_life, "Short Date")), nominal_wall_thickness - minimum_allowable_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Recommended ACR", DateValue(Format(Now(), "Short Date")), forecast_wall_loss, recommended_acr)
return_data_array = push_to_array(return_data_array, "Recommended ACR", DateValue(Format(recommended_end_of_life, "Short Date")), nominal_wall_thickness - minimum_allowable_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Current RL", current_end_of_life, 0, 0)
return_data_array = push_to_array(return_data_array, "Current RL", current_end_of_life, nominal_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Current ACR", DateValue(Format(last_inspection_date, "Short Date")), last_inspection_date_wall_loss, current_acr)
return_data_array = push_to_array(return_data_array, "Current ACR", DateValue(Format(current_end_of_life, "Short Date")), nominal_wall_thickness, current_acr)
return_data_array = push_to_array(return_data_array, "Actual CR", DateValue(Format(last_inspection_date, "Short Date")), last_inspection_date_wall_loss, actual_cr)
return_data_array = push_to_array(return_data_array, "Actual CR", DateAdd("d", (nominal_wall_thickness - last_inspection_date_wall_loss) / actual_cr * 365, last_inspection_date), nominal_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Actual RL", DateAdd("d", (nominal_wall_thickness - last_inspection_date_wall_loss) / actual_cr * 365, last_inspection_date), 0, 0)
return_data_array = push_to_array(return_data_array, "Actual RL", DateAdd("d", (nominal_wall_thickness - last_inspection_date_wall_loss) / actual_cr * 365, last_inspection_date), nominal_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Fail FFS", DateValue(Format(last_inspection_date, "Short Date")), nominal_wall_thickness - minimum_allowable_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Fail FFS", IIf(recommended_end_of_life > current_end_of_life, recommended_end_of_life, current_end_of_life), nominal_wall_thickness - minimum_allowable_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Nominal Wt", last_inspection_date, nominal_wall_thickness, 0)
return_data_array = push_to_array(return_data_array, "Nominal Wt", IIf(recommended_end_of_life > current_end_of_life, recommended_end_of_life, current_end_of_life), nominal_wall_thickness, 0)
'Return requested parameter to user
If return_parameter = "database" Then
calculate_acr_bands_data = return_data_array
ElseIf return_parameter = "recommended_acr" Then
calculate_acr_bands_data = Round(recommended_acr, 2)
ElseIf return_parameter = "forecast_wall_loss" Then
calculate_acr_bands_data = Round(forecast_wall_loss, 2)
ElseIf return_parameter = "recommended_rl" Then
calculate_acr_bands_data = Round(recommended_rl, 2)
Else
calculate_acr_bands_data = Null
End If
End Function
'Description: Pass array and values to push
Function push_to_array(bands_array As Variant, graph_name As String, date_value As Date, wall_loss As Double, acr As Double) As Variant
Dim size As Integer: size = UBound(bands_array) + 1
ReDim Preserve bands_array(size)
Set bands_array(size) = New BAND_ARRAY_CLASS
With bands_array(size)
.graph_name = graph_name
.wall_loss = wall_loss
.date_value = date_value
.acr = acr
End With
push_to_array = bands_array
End Function
答案 0 :(得分:1)
您的代码不能用作UDF,因为UDF无法为除调用UDF之外的任何单元格赋值(并且通过设置函数的返回值来指定其值)。
所以,因为你的行
acr_bands_array(acr_bands_array.Rows.Count, 1) = nominal_wall_thickness - minimum_allowable_wall_thickness
正在尝试修改Excel工作表的状态,它会崩溃并且应该向调用该函数的单元格返回#VALUE!
错误。
我不确定为什么会出现"A value used in this formula is of the wrong data type"
错误 - UDF返回任何类型的错误消息只是非常,这只是错误值。