2017-02-20 6 views
6

Ich habe eine Excel-UDF erstellt, die eine Array-Eingabe akzeptiert. Ich möchte nur eine gerade Anzahl von Elementen im Array zulassen. Hier ist der Code: (es ist nur kurz, so werde ich es post alle und auf diese Weise Sie etwas Kontext haben kann)Erzwingen eines Arguments in einer Excel-UDF

Function SUBSTITUTEMULTI(inputString As String, ParamArray criteria() As Variant) as String 

Dim subWhat As String 
Dim forWhat As String 
Dim x As Single 


If UBound(criteria()) Mod 2 = 0 Then 
'check whether an even number of arguments is input 
MsgBox "You've entered too few arguments for this function", vbExclamation 

Else 
    x = 0 
    For Each element In criteria 
     If x = 0 Then 
      subWhat = element 
     Else 
      forWhat = element 
      inputString = WorksheetFunction.Substitute(inputString, subWhat, forWhat) 
     End If 
     x = 1 - x 
    Next element 
SUBSTITUTEMULTI = inputString 
End If 
End Function 

Aktuell kehre ich ein Meldungsfeld, das wie Excel eigene sucht man das erscheint, wenn Sie SUBSTITUTE() eingeben mit das dritte Argument fehlt. Wenn Sie dies jedoch mit SUBSTITUTE() oder einer ähnlichen Funktion tun, verhindert Excel, dass Sie die Formel eingeben, stattdessen klickt es Sie zurück, damit Sie die fehlerhafte Funktion beheben können. Ich möchte das, da sonst meine Funktion in ihren gebrochenen Zustand (ungerade Anzahl von Argumenten) in mehrere Zellen eingefügt werden kann, was bedeutet, dass das Meldungsfeld bei der Neuberechnung mehrmals erscheint!

Wie kann ich den Code reparieren, so dass der Benutzer automatisch zum Bearbeitungsformel zurückkehrt, wenn falsche Argumente gefunden werden (eine ungerade Anzahl von Elementen im Array)?

+1

Wäre diese Funktion nicht verwendet werden intuitiver, wenn Sie auf einer Liste von Originalen und einer zweiten übergeben Liste der Ersetzungen? Dann könnte Ihre Funktion überprüfen, dass die beiden ParamArrays die gleiche Größe hatten; die zweite abschneiden, wenn sie größer als die erste war, und die zweite mit dem übereinstimmenden Wert aus dem Original anhängen, wenn sie kürzer als die erste war. – Jeeped

+0

@Jeeped Netter Gedanke. Ich habe versucht, die klassische 'SUBSTITUTE (..., oldText, newText)' -Formel zu emulieren, d. H. Mit alternierenden Argumenten anstelle von zwei Arrays von Argumenten war das, was ich _wanted_ wollte. Ich glaube auch nicht, dass du 2 ParamArrays haben kannst, da sie eine unbestimmte Länge haben. Wie könntest du also bestimmen, wo man fertig ist und die nächste angefangen hat?Aber Ihre allgemeine Idee war eine, die ich in Betracht gezogen habe, wenn ich eine ungerade Anzahl von Argumenten habe, ich kopiere einfach das letzte Argument im Array, so dass es in der Formel insgesamt ignoriert wird - das ist eine Möglichkeit, mit den Fehlern umzugehen, nur nicht die Ich bin nach – Greedo

+0

Ja, ich hätte nicht den Begriff *** paramarray *** verwenden sollen. Sie wären einfache Arrays wie '= SUBSTITUTEMULTI (A1, {" a "," b "," c "}, {" x "," y "," z "})'. – Jeeped

Antwort

2

Dies ist keine besonders gute Lösung. Im Allgemeinen ist die Verwendung von SendKeys wird abgeraten und diese Lösung funktioniert nur, wenn Sie Ihre MoveAfterReturn Eigenschaft (dh nicht markiert im Bild unten) deaktiviert haben

enter image description here

Function test(rng As Range) 
    'check condition 
    If rng.Count <> 2 Then 
     MsgBox "Incorrect..." 
     SendKeys "{F2}", True 
     Exit Function 
    End If 

    'code here to be run if parameters are valid 
    test = "Success" 
End Function 
+0

Oder einfach 'SendKeys '{up}" 'rirst. Ist das 'True'-Argument notwendig, habe ich es entfernt und alles funktioniert (scheinbar) noch gut, wofür ist es da? – Greedo

+0

@Greedo 'True' zwingt Excel, auf das Drücken der Taste zu warten, bevor die Steuerung an das Makro zurückgegeben wird. Wenn Sie nicht warten, erhalten Sie möglicherweise unerwartete Ergebnisse. Wenn Sie zum Beispiel 'ActiveCell' im späteren Code verwenden und Sie nicht auf' SendKeys' gewartet haben, um Sie in eine andere Zelle zu verschieben, erhalten Sie einen Verweis auf die falsche Zelle. * Hinweis, die Verwendung von 'ActiveCell' wird nicht empfohlen * – CallumDA

+0

' SendKeys "Up" 'würde auch funktionieren - guter Vorschlag! (Für diejenigen mit einem Down MoveAfterReturn) – CallumDA

3

Haben Sie die Funktion einen Fehler zurück, wenn eine falsche Anzahl von Argumente werden eingegeben.

Die Rückgabe muss eine Variant statt String sein.

Ersetzen Sie Ihre msgbox durch SUBSTITUTEMULTI=CVErr(xlErrValue).

Eine Liste von Fehlern:

  • xlErrDiv0 für einen #DIV/0 Fehler
  • xlErrNA für einen #N/A Fehler
  • xlErrName für einen #NAME? Fehler
  • xlErrNull für einen #NULL Fehler
  • xlErrNum für eineFehler
  • xlErrRef für einen #REF Fehler
  • xlErrValue für einen #VALUE Fehler

(http://www.cpearson.com/excel/writingfunctionsinvba.aspx)

+0

Hatte zu aktualisieren - vergessen, 'CVErr' hinzuzufügen, um zurückzukehren. Gibt nur die Nummer ohne es zurück. –

+0

nettes Konzept :) –

+2

Das ist nicht wirklich was OP verlangt. * Returning * ein Fehlerwert ist anders. Zum Beispiel gibt 'SUM (1/0)' 'einen Fehlerwert zurück, aber' SUM (#) 'wird nicht vervollständigt. Das letztere Verhalten ist, was OP ist danach. – CallumDA

Verwandte Themen