Excel VBA自定义函数FindGrade运行返回空白问题求助
排查Excel VBA自定义函数返回空白的问题
Hey there, let's break down why your FindGrade function keeps returning blank and fix those issues one by one.
核心错误梳理
I spotted several critical mistakes in your code that are causing the blank result:
- Parameter name typo: You used
chkeventin theIfcondition, but your function's parameter is namedEventtype. This means none of your grade rules (A/B/C/D) were ever being assigned, so all subsequent checks failed. - Misused Dictionary: You created a
Scripting.Dictionarybut didn't populate it with values fromchkcell—and worse, you tried calling.exists()on a string variablex(which doesn't have that method). The Dictionary was completely wasted here. - Incorrect string manipulation:
Resultis a String type, but you tried using.Add()(a method for collections). Strings need direct assignment likeResult = "A". - Uninitialized variables:
chkfoundandchkfoundDwere never set to an initial value (VBA defaults toEmpty), so checkingIf chkfound = 0was unreliable. - Redundant/confused logic: The later
chkfoundDchecks duplicated code and had inconsistent order, leading to missed matches.
Fixed Full Code
Here's the corrected version with all issues addressed, plus improved efficiency:
Function FindGrade(chkcell As String, Eventtype As String) As String Dim A As String, B As String, C As String Dim D1 As String, D2 As String, D3 As String Dim Result As String Dim chkfound As Integer, chkfoundD As Integer Dim cellValues As Object ' Dictionary to store chkcell values for fast lookup Dim x As Variant ' Initialize variables to avoid Empty value issues chkfound = 0 chkfoundD = 0 Result = "" ' Fix parameter name and assign rules for "Books" event If Eventtype = "Books" Then A = "7" B = "2,11" C = "5" D1 = "4" D2 = "8,10,12" D3 = "6" End If ' Populate Dictionary with trimmed values from chkcell (handles accidental spaces) Set cellValues = CreateObject("Scripting.Dictionary") cellValues.CompareMode = vbTextCompare For Each x In Split(chkcell, ",") x = Trim(x) If Not cellValues.Exists(x) Then cellValues.Add x, x End If Next x ' Match rules in priority order ' Rule A: Check if 7 exists If cellValues.Exists(A) Then Result = "A" chkfound = 1 End If ' Rule B: Check if BOTH 2 and 11 exist (per your description) If chkfound = 0 Then Dim bParts As Variant bParts = Split(B, ",") Dim allBMatch As Boolean allBMatch = True For Each x In bParts If Not cellValues.Exists(Trim(x)) Then allBMatch = False Exit For End If Next x If allBMatch Then Result = "B" chkfound = 1 End If End If ' Rule C: Check if 5 exists If chkfound = 0 And cellValues.Exists(C) Then Result = "C" chkfound = 1 End If ' Match D-series rules If chkfound = 0 Then If cellValues.Exists(D1) Then Result = "D1" chkfoundD = 1 ElseIf cellValues.Exists(D3) Then Result = "D3" chkfoundD = 1 ElseIf cellValues.Exists(D2) Then Result = "D2" chkfoundD = 1 Else ' Fallback if no D rules match Result = "1" End If End If ' Return the final result FindGrade = Result End Function
Key Improvements Explained
- Fixed parameter typo: Now the "Books" event correctly loads all grade rules.
- Proper Dictionary usage: We store all values from
chkcellin the Dictionary, making existence checks fast and clean (no nested loops needed). - Correct string assignment:
Resultis set directly with grade values instead of using invalid.Add()calls. - Accurate B rule logic: Now it properly checks if all values in B's rule exist (2 and 11, in your example) instead of just one.
- Initialized variables:
chkfoundandchkfoundDstart at 0, so condition checks work as expected. - Simplified logic: Rules are checked in priority order, and we stop at the first match to avoid unnecessary work.
Test It Out
For your example where H1 is "10,1,7,8", calling =FindGrade(H1,"Books") will return A (since 7 is present). Other test cases:
- H1 =
"2,11,3"→ returnsB - H1 =
"5,9"→ returnsC - H1 =
"8,1"→ returnsD2 - H1 =
"3,9"→ returns1
内容的提问来源于stack exchange,提问作者angel
相关产品推荐
相关产品推荐

