2017-04-24 7 views
1

VBA内から呼び出したときに動作するカスタムVBA関数を記述しました。例えばカスタム関数はVBAで動作しますが、Excelセルで呼び出されたときには動作しません

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 

しかし、私は私のエクセルブックのセル内から正確に同じ関数を呼び出すとき。 「この数式で使用されている値が間違ったデータ型です」というエラーが表示されます。 VBAの中から正確に同じ入力を使って式を証明しただけなので意味がありません。あなたがソースコードを表示したい場合、私は私のGitHubのアカウントに私のレポをアップロードした

enter image description here

...助けを

https://github.com/Joshua-W-Adams/vba-wall-loss-vs-time

感謝。

UPDATE

機能は、UDFがそれ以外の任意のセルに値を割り当てることはできませんので、あなたのコードはUDFとして動作しません

'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 
+1

私の推測では、テストで文字列として渡す日付は、実際には日付型です。 –

+0

あなたのコードを質問に投稿すると、あなたの問題の原因を見ることができます。 (コードなしで、私たちは推測することができます) – YowE3K

+0

calculate_acr_bands_data関数のシグネチャを投稿できますか? – AlwaysData

答えて

1

...下記掲載されています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は、エラーメッセージの任意の並べ替え、単にエラー値を返すことが非常珍しいです。

+0

ありがとう、ワークシート上の配列の参照と変更とは対照的に、上記のコードを変更してデータを格納および変更する仮想配列を作成することで、これを確認しました。この問題を解決するためのヒントとしては、関数にブレークポイントを追加するというヒントがありました。エラーの原因となるコード行を分離することができました.Excelセルから関数を呼び出すときにはどうしたらよいか分かりませんでした。あなたの助けに感謝します。 – Josh

関連する問題