2016-02-12 5 views
5

私は、1枚のシート上で動作するUDFを作成しました。この問題は、複数のシートで発生します。数式が複数のシートにある場合、1つのシートにロードすると、他のすべてのシートの出力も変わります。VBA UDFはすべてのシートの値を変更します。どのように1に制限する?

どうしてですか?私はActiveWorksシートやアクティブセルなどを使用していません。

Function customreturn(security As Range, datacheck As Range) As Variant 

    Dim row_num As Integer 
    Dim row_num2 As Integer 
    Dim price1 As Double 
    Dim price2 As Double 
    Dim perfo As Double 
    Dim blank_end As Boolean 

    row_num = security.Row 
    col_num = security.Column 
    row_num2 = row_num + 1 
    col_num2 = datacheck.Column 

    If WorksheetFunction.IsError(datacheck.Value) = True Then 
     customreturn = "No data" 
    Else 
     price1 = Cells(row_num, col_num).Value 

     Do While WorksheetFunction.IsError(Cells(row_num2, col_num2).Value) = True 
      row_num2 = row_num2 + 1 
     Loop 

     price2 = Cells(row_num2, col_num).Value 

     perfo = price1/price2 - 1 

     customreturn = perfo 
    End If 
End Function 
+2

これは再計算された数式をリロードしますか?または、数式が入っているシート上のデータを使用する代わりに、すべてのシートで同じ情報を再計算して使用しますか? (...それは理にかなっていますか?)。それは[ボラティリティ](http://www.mrexcel.com/forum/excel-questions/271165-udf-volatile-vs-not.html) – BruceWayne

+0

と関係があるかもしれません。1)数式を1枚のシートに読み込むと手動で 2)それは他のすべてのシートで同じ値を使用します - はい – sandboxj

+0

また、ワークシート変数( 'Dim ws as Worksheet'、' Set ws = Sheets(security.parent.name) ')を追加してから、' ws '' Cells() 'のすべての使用の前に' '.''を実行すると、' 'security''がオンになっているシートからデータが得られていることが確認されます – BruceWayne

答えて

6

あなたはとても親ワークシートがActiveSheet propertyにデフォルト設定されRange.Cells propertyを使用する3回のいずれかに指定した親のワークシートがありません。これは、範囲パラメータ 'Range.Parent propertyの1つに対するワークシート参照を提供するWith ... End With statementで修正できます。

付き内
Function customreturn(security As Range, datacheck As Range) As Variant 
    Dim row_num As Long, row_num2 As Long, col_num As Long, col_num2 As Long 
    Dim price1 As Double, price2 As Double, perfo As Double 
    Dim blank_end As Boolean 

    row_num = security.Row 
    col_num = security.Column 
    row_num2 = row_num + 1 
    col_num2 = datacheck.Column 

    With security.Parent 
     If IsError(datacheck) Then 
      customreturn = "No data" 
     Else 
      price1 = .Cells(row_num, col_num).Value 

      Do While IsError(.Cells(row_num2, col_num2)) 
       row_num2 = row_num2 + 1 
      Loop 

      price2 = .Cells(row_num2, col_num).Value 

      perfo = price1/price2 - 1 

      customreturn = perfo 
     End If 
    End With 
End Function 

...端と、Cellsの全ては親のワークシートは1がで...エンドで呼ばれていることを示すために.Cellsとして言及されています。

ワークシートのISERRORまたはVBAのIsError functionTrueと明示的に比較する必要はありません。です。それは既にそれが真か偽かを知っています。

2つの宣言されていない変数col_numとcol_num2がありました(ありがとうBruceWayne)。これは、宣言領域の各コードシートの先頭にOption Explicitを追加することで回避できます。


は、オプション►エディタのプロパティページが新規に作成された各コードシートの上部にOption Explicit文を入れます►は、VBEのツールの中に変数の宣言を必要とする設定を¹しました。これは、スペルミスのような間違ったコードミスを避けるだけでなく、変数宣言で正しい変数型を使用するように影響します。宣言なしでオンザフライで作成された変数は、すべてバリアント/オブジェクトタイプです。 Option Explicitを使用することは、「ベストプラクティス」と広く考えられています。

+1

シートを明示することを提案するときに何かに出ましたか? (私はまだそれらを学んでいる)UDFの正しいパスにmを置いておいてください(これはまだ分かっていませんが、いくつかの宣言されていない変数 'col_num'と' col_num2'があります)。 。 – BruceWayne

+1

はい、これは私がこの時点で知る限り最善の問題であると思われ、OPが確認できます。私が 'Cells'を見るたびに、' Cells'という警鐘が私の頭の中で消えてしまうのです。 – Jeeped

+1

...宣言されていないヴァールに注目してくれてありがとう。私はそれを反映するために私の答えを修正しました。 – Jeeped

関連する問題