2017-02-20 4 views
6

Я создал excel UDF, который принимает вход массива. Я хочу, чтобы он разрешал четное количество элементов в массиве. Вот код: (это только коротко, поэтому я выложу все это и таким образом вы можете иметь некоторый контекст)Как заставить аргумент в 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 

В настоящее время я возвращаю окно сообщения, которое выглядит как собственные один в Excel, которая появляется, когда вы вводите SUBSTITUTE() с третий аргумент отсутствует. Однако, когда вы делаете это с помощью SUBSTITUTE() или любой аналогичной функции, Excel запрещает вам вводить формулу, вместо этого она нажимает на нее, чтобы вы могли исправить неисправную функцию. Мне бы это понравилось, так как в противном случае моя функция может быть вставлена ​​в разбитое состояние (нечетное число аргументов) в несколько ячеек, что означает, что окно сообщения появляется несколько раз при пересчете!

Как я могу исправить код, чтобы, если обнаружены неправильные аргументы (нечетное количество элементов в массиве), пользователь автоматически возвращается на этап редактирования формы?

+1

Не будет ли с помощью этой функции более интуитивным, если вы прошли по списку оригиналов и второй список замен? Тогда ваша функция может проверить, что оба параметра ParamArrays имеют одинаковый размер; усекая вторую, если она была больше первой и добавила вторую с соответствующим значением из оригинала, если она была короче первой. – Jeeped

+0

@ Jeeped Nice думал. Я пытался подражать классической формуле 'SUBSTITUTE (..., oldText, newText)', т. Е. С переменными аргументами, а не с двумя массивами аргументов, на самом деле был тем, что я думал. Кроме того, я не считаю, что у вас может быть 2 ParamArrays, так как они неопределенные длины, так как вы можете определить, где один закончен, а следующий начался?Но ваша общая идея была такой, какой я считал, когда у меня есть нечетное число аргументов, я просто дублирую последний аргумент в массиве, так что он вообще игнорируется в формуле - это один из способов справиться с ошибками, просто не один я после – Greedo

+0

Да, я не должен был использовать hte term *** paramarray ***. Это были бы простые массивы типа '= SUBSTITUTEMULTI (A1, {" a "," b "," c "}, {" x "," y "," z "})'. – Jeeped

ответ

2

Это не очень хорошее решение. Как правило, использование SendKeys не рекомендуется, и это решение работает только если вы отключили свой MoveAfterReturn собственность (то есть бесконтрольно на изображении ниже)

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

Или просто 'SendKeys '{up}" 'rirst. Является ли аргумент «истина» необходимым, я удалил его, и все работает отлично (видимо), для чего он нужен? – Greedo

+0

@ Greedo 'True' заставляет Excel ждать нажатия клавиши, прежде чем возвращать управление макросу. Если вы не ждете, вы можете получить неожиданные результаты. Например, если вы использовали 'ActiveCell' в более позднем коде, и вы не ждали, что' SendKeys' переведет вас в другую ячейку, вы получите ссылку на неправильную ячейку. * Заметьте, использование 'ActiveCell' не рекомендуется * – CallumDA

+0

' SendKeys "Up" 'будет работать тоже - хорошее предложение! (Для тех, кто с вниз MoveAfterReturn) – CallumDA

3

функцию, возвращающую ошибку, когда неправильное количество вводятся аргументы.

Возвращение должно быть вариантом, а не строкой.

Замените ваш msgbox на SUBSTITUTEMULTI=CVErr(xlErrValue).

Список ошибок:

  • xlErrDiv0 для #DIV/0 ошибки
  • xlErrNA для #N/A ошибки
  • xlErrName для #NAME? ошибки
  • xlErrNull для #NULL ошибки
  • xlErrNum для #NUM ошибка
  • xlErrRef для #REF ошибки
  • xlErrValue для #VALUE ошибки

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

+0

Придется обновить - забыл добавить 'CVErr' для возврата. Возвращает число без него. –

+0

nice concept :) –

+2

На самом деле это не то, о чем просит ОП. * Возврат * значение ошибки отличается. Например, 'SUM (1/0)' возвращает значение ошибки, но 'SUM (#)' не будет завершено. Последнее поведение - это то, что происходит после OP. – CallumDA

Смежные вопросы