2017-01-25 3 views
0

Я делаю простой UDF, который проверяет, является ли данная страна членом ОЭСР. У меня есть два входа:Недопустимое имя, введенное в UDF с VBA для Excel

  1. Excel ячейки, содержащей название страны

  2. ввода, содержащий первую ячейку столбца, содержащего все страны ОЭСР.

Функция сравнивает содержимое ячейки Candidate и колонны из countries через петлю. Если имя кандидата не совпадает ни с одной из стран ОЭСР, в конечном итоге эта функция классифицирует ее как страну, не являющуюся членом ОЭСР.

Мой код выглядит так:

Function OECD(Candidate, Countries) 
    Dim Candidate As String 
    Dim Countries As String 
    OECDCountry = Countries 'Variable that changes at every iteration, I compare the name of the candidate to this 
    For i = 1 To 34  
     If Candidate.Value = OECDCountry Then 
      OECD = 2     
     Else: OECDCountry = Countries.Offset(i, 0) 
    Next i 

'If the column next to the candidate name, where I am running this function, is still empty, record the country as non-OECD 

    If Candidate.Offset(0, 1) <> 2 Then OECD = 1     
End Function 

Однако, когда я пытаюсь использовать эту функцию, я получаю следующее сообщение об ошибке при выборе второй вход:

Имя, которое вы ввели не действует. Причины для этого могут включать в себя:

-The имя не начинается с буквы или подчеркивания

-The имя содержит пробел или другие недопустимые символы

-The имя конфликтует с Excel встроенный имя или название другого объекта в рабочей книге

Почему я получаю это сообщение об ошибке и как его исправить?

+2

у вас есть повторяющиеся имена в вашей области. Вы запрашиваете переменные «Кандидат» и «Страны», которые должны быть переданы вашей функции в качестве аргументов, а затем вы объявляете переменные с одинаковыми именами в самой функции. Они не могут быть идентичными именами, что, вероятно, является причиной вашей проблемы. Затем вы также пытаетесь использовать 'Candidate.Value', когда вы пытались преобразовать переменные« Dim Candidate As String »и String, не имеют свойства .Value (хотя переданный аргумент мог бы быть, если он был передан как ссылка на ячейку). – tigeravatar

+0

, вы должны рассмотреть возможность использования второго параметра «Страны как диапазон», сделает ваш код ** UDF ** намного проще –

+1

И вы должны объявить 'OECDCountry'' 'String'. И вам нужно будет объявить ваш UDF как «volatile», так что изменение в столбце, в котором перечислены все страны, позволит вам повторно закрепить UDF. И считаете ли вы, что с помощью 'VLOOKUP' делать все, не используя UDF? – YowE3K

ответ

0

Ну, я должен сказать, что я считаю, что страны ОЭСР являются примером статических данных, поскольку они не меняются очень часто. Я бы сохранил данные на листе где-то, а затем по первому запросу прочитал его в кеш, используя Scripting.Dictionary, а затем можно использовать метод Exists. Вот мое решение

Option Explicit 

Private mdicRunTimeCacheOECDCountries As Scripting.Dictionary 

Sub DevTimeSetup_RunOnce() 

    ' ___   _____ _   ___  _    ___   ___ 
    '| \ _____ _|_ _(_)_ __ ___/ __| ___| |_ _ _ _ __ | _ \_ _ _ _/_ \ _ _ __ ___ 
    '| |)/-_) V/| | | | ' \/ -_)__ \/ -_) _| || | '_ \ | /|| | ' \ (_) | ' \/ _/ -_) 
    '|___/\___|\_/ |_| |_|_|_|_\___|___/\___|\__|\_,_| .__/_|_|_\\_,_|_||_\___/|_||_\__\___| 
    '             |_| |___|           http://www.network-science.de/ascii/ 
    '* just some code to set up a sheet with some data as OP supplied none 
    '* so that anyone can play with this problem 
    Dim rngOECD As Excel.Range 
    Set rngOECD = Sheet1.Range(Sheet1.Cells(1, 1), Sheet1.Cells(7, 1)) 
    rngOECD.Value2 = [{"USA";"UK";"Germany";"France";"Italy";"Japan";"Canada"}] 'not full OECD, just G7 
    rngOECD.Name = "OECDCountries" 

End Sub 


Private Function GetRunTimeCacheOECDCountries() As Scripting.Dictionary 
    If mdicRunTimeCacheOECDCountries Is Nothing Then 
     Set mdicRunTimeCacheOECDCountries = New Scripting.Dictionary 

     Dim rngOECD As Excel.Range 
     Set rngOECD = Sheet1.Range("OECDCountries") 

     Dim rngLoop As Excel.Range 
     For Each rngLoop In rngOECD 
      mdicRunTimeCacheOECDCountries.Add rngLoop.Value2, 0 
     Next 

    End If 
    Set GetRunTimeCacheOECDCountries = mdicRunTimeCacheOECDCountries 
End Function 



Public Function OECD(Candidate) As Long 
    OECD = VBA.IIf(GetRunTimeCacheOECDCountries.Exists(Candidate), 1, 0) 
End Function 

и вызовите из листа с формулой ячейки, как этот

=OECD("UK")

+0

Благодарим вас за ответ. Это было сложнее, чем я ожидал, но теперь я думаю, что понял – Patapunfate

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