2016-02-12 12 views
5

Ich habe eine UDF erstellt, die auf einem einzigen Blatt funktioniert. Das Problem tritt bei mehreren Blättern auf. Wenn ich die Formel auf mehreren Blättern habe und wenn ich sie auf ein Blatt (neu) lade, ändert sich auch die Ausgabe in ALLE anderen Blätter.VBA UDF ändert Werte auf ALLEN Blättern. Wie kann man auf eins beschränken?

Warum passiert das? Ich verwende kein ActiveWorksheet oder Active Cell oder ähnliches.

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

Er lädt die Formel neu, was bedeutet, dass sie neu berechnet wird? Oder es wird neu berechnet und verwendet dieselben Informationen für alle Blätter, anstatt die Daten auf dem Blatt zu verwenden, in dem sich die Formel befindet? (...Ist das sinnvoll?). Es könnte etwas mit [Volatilität] zu tun haben (http://www.mrexcel.com/forum/excel-questions/271165-udf-volatile-vs-not.html) – BruceWayne

+0

1) Wenn ich die Formel in einem Blatt laden manuell 2) Es verwendet den gleichen Wert für alle anderen Blätter - ja – sandboxj

+0

Versuchen Sie auch, eine Arbeitsblattvariable hinzuzufügen ('Dim ws als Worksheet',' Set ws = Sheets (security.parent.name) ', dann fügen Sie einfach' ws hinzu . 'vor allen Verwendungen von' Cells() '. Das wird sicherstellen, dass die Daten vom Blatt kommen,' security' ist on. – BruceWayne

Antwort

6

Es gibt keine übergeordnete Arbeitsblatt für jede der drei Mal angegeben Sie die Range.Cells property so die Mutter Arbeitsblatt verwenden wird dem ActiveSheet property Verzug geraten. Dies kann mit einer With ... End With statement behoben werden, die einen Arbeitsblattverweis auf einen der Bereichsparameter 'Range.Parent property bietet.

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 

Im With ... End With, die alle die Cells sind Referenzen als .Cells zu zeigen, dass das übergeordnete Arbeitsblatt derjenige in der mit Bezug genommen wird, ... End With.

Sie müssen die ISERROR- oder VBA-Werte des Arbeitsblatts IsError function nicht unbedingt mit True vergleichen. Es weiß bereits, ob es wahr oder falsch ist.

Es wurde darauf hingewiesen (danke BruceWayne), dass Sie zwei nicht deklarierte Variablen, col_num und col_num2 hatten. Dies kann vermieden werden, indem Sie Option Explicit¹ oben im Codeblatt im Deklarationsbereich hinzufügen.


¹ Einstellung Variablendeklaration erforderlich innerhalb der Werkzeuge des VBE ► Optionen ► Editor Eigenschaftenseite der Option Explicit Anweisung an den Anfang jedes neu erstellten Code Blatt gelegt wird. Dies vermeidet alberne Codierungsfehler wie Rechtschreibfehler und beeinflusst Sie, den richtigen Variablentyp in der Variablendeklaration zu verwenden. Variablen, die ohne Deklaration direkt erstellt werden, sind alle vom Typ Variante/Objekt. Verwenden Option Explicit ist weithin als "Best Practice".

+1

Also war ich auf etwas, als ich vorschlug, das Blatt explizit zu machen? Yay! Schön zu wissen, dass ich ' m auf dem richtigen Weg in UDFs (ich lerne sie immer noch). Schöne Erklärung! (FYI es gibt einige nicht deklarierte Variablen, 'col_num' und' col_num2'). Ich würde auch empfehlen, 'Option Explicit' jederzeit in VBA hinzuzufügen – BruceWayne

+1

Ja, das scheint das Problem zu sein, so gut ich es zu diesem Zeitpunkt sagen kann, das OP kann bestätigen. Ein paar Tage, jedes Mal, wenn ich sehe, dass 'Zellen' und nicht' .Cells' Alarmglocken in meinem Kopf abgehen. – Jeeped

+1

... und danke, dass du die nicht deklarierten Vars notiert hast; Ich habe meine Antwort geändert, um das widerzuspiegeln. – Jeeped