2017-02-20 25 views
6

Stworzyłem excel UDF, który akceptuje wejście tablicy. Chcę, aby zezwalała tylko na parzystą liczbę elementów w tablicy. Oto kod: (to tylko krótkie, więc będę to wszystko i w ten sposób można mieć pewien kontekst post)Jak wymusić argument w programie 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 

Obecnie powrotu okno komunikatu, który wygląda jak własny jednego programu Excel, który pojawia się, kiedy wchodzi SUBSTITUTE() z brak trzeciego argumentu. Jednak gdy zrobisz to za pomocą SUBSTITUTE() lub dowolnej podobnej funkcji, program Excel uniemożliwi Ci wprowadzenie formuły, zamiast tego kliknie z powrotem do niej, aby naprawić wadliwą funkcję. Chciałbym to, ponieważ w przeciwnym razie moja funkcja może być wklejona w stanie złamania (nieparzysta liczba argumentów) do kilku komórek, co oznacza, że ​​pole komunikatu pojawia się kilka razy podczas przeliczania!

Jak mogę naprawić kod, aby po wykryciu niepoprawnych argumentów (nieparzystej liczby elementów w tablicy) użytkownik automatycznie powrócił do etapu formuły edycji?

+1

Would not korzystania z tej funkcji jest bardziej intuicyjne, jeśli przeszedł wzdłuż liście oryginałów i sekundy lista podstawień? Wtedy twoja funkcja może sprawdzić, czy dwa ParamArrays były tego samego rozmiaru; obcięcie drugiego, jeśli był większy od pierwszego i dodanie drugiego z pasującą wartością z oryginału, jeśli był krótszy niż pierwszy. – Jeeped

+0

@Jeeped Nice thought. Próbowałem naśladować klasyczną formułę 'SUBSTITUTE (..., oldText, newText)', tj. Mając naprzemienne argumenty zamiast dwóch tablic argumentów, faktycznie było to, co chciałam. Nie wierzę też, że możesz mieć 2 ParamArrays, ponieważ mają one nieokreśloną długość, więc jak możesz określić, gdzie skończyłeś, a następny zaczął?Ale twój ogólny pomysł był taki, który rozważałem, gdy mam nieparzystą liczbę argumentów, po prostu duplikuję ostatni argument w tablicy, tak że jest on całkowicie ignorowany w formule - jest to jeden ze sposobów radzenia sobie z błędami, a nie z Jeden jestem po – Greedo

+0

Tak, nie powinienem był używać terminu *** *** Paramarray ***. Będą to proste tablice typu '= SUBSTITUTEMULTI (A1, {" a "," b "," c "}, {" x "," y "," z "})'. – Jeeped

Odpowiedz

2

To nie jest szczególnie dobre rozwiązanie. Generalnie stosowanie SendKeys jest zniechęcony i to rozwiązanie działa tylko wtedy, gdy wyłączona aĹ MoveAfterReturn (tj zaznaczone na zdjęciu poniżej)

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

Lub po prostu 'SendKeys" {up} "' rirst. Czy argument "Prawda" jest konieczny, usunąłem go i wszystko nadal działa dobrze (podobno), po co to jest? – Greedo

+0

@Greedo 'True' wymusza na programie Excel oczekiwanie na naciśnięcie klawisza przed zwróceniem sterowania do makra. Jeśli nie zaczekasz, możesz uzyskać nieoczekiwane rezultaty. Na przykład, jeśli używałeś 'ActiveCell' w późniejszym kodzie i nie czekałeś aż' SendKeys' przeniesie cię do innej komórki, skończyłoby się odniesieniem do niewłaściwej komórki. * Uwaga, użycie 'ActiveCell' nie jest zalecane * – CallumDA

+0

' SendKeys "Up" 'też by działało - dobra sugestia! (Dla tych, którzy mają w dół MoveAfterReturn) – CallumDA

3

posiada funkcji zwróci błąd, gdy nieprawidłowy numer argumenty są wprowadzane.

Powrót musi być wariantem, a nie łańcuchem.

Zamień swój msgbox na SUBSTITUTEMULTI=CVErr(xlErrValue).

listę błędów:

  • xlErrDiv0 dla #DIV/0 błędu
  • xlErrNA dla #N/A błędu
  • xlErrName dla #NAME? błędu
  • xlErrNull dla #NULL błędu
  • xlErrNum dotyczący #NUM błąd
  • xlErrRef dla #REF błędu
  • xlErrValue dla #VALUE błędu

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

+0

Musiałem zaktualizować - zapomniałem dodać 'CVErr' do powrotu. Zwraca tylko liczbę bez tego. –

+0

fajna koncepcja :) –

+2

To nie jest to, o co prosze OP. * Wracając * wartość błędu jest inna. Na przykład 'SUMA (1/0)' zwraca wartość błędu, ale 'SUMA (#)' nie zostanie zakończona. To drugie zachowanie jest po OP. – CallumDA