2017-01-25 74 views
0

我正在製作一個簡單的UDF,用於檢查給定的國家是否爲OECD的成員。我有兩個輸入:使用VBA for Excel在UDF中輸入的名稱無效

  1. 包含國家的名稱

  2. 包括含所有的OECD國家中列的第一個單元格中輸入Excel單元格。

功能經由一個環型的細胞Candidatecountries列的內容進行比較。如果候選人名稱與任何經合組織國家不匹配,最終該職能將其劃分爲非經合組織國家。

我的代碼是這樣的:

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名稱中包含空格或其他無效字符

使用Excel -The名稱衝突內置下劃線開始名稱或工作簿中另一個對象的名稱

爲什麼我收到此錯誤消息,該如何解決?

+2

你在你的範圍內重名。你要求變量'Candidate'和'Countries'作爲參數傳遞給你的函數,然後你在函數本身中聲明具有相同名字的變量。那些不能是相同的名字,這可能是你的問題的一部分。然後,當您嘗試將Dim Candidate As String並且String變量沒有.Value屬性時(儘管傳遞的參數可能作爲單元格引用傳遞),您也嘗試使用'Candidate.Value'。 – tigeravatar

+0

你應該考慮使用第二個參數'CountriesAs Range',將使你的** 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