Public Sub GetSuggestions( _
ByVal str_Word As String, _
ByVal sndx As String)
Dim n As Integer
Dim l As Integer
Dim best As Integer
Dim lev As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim tst1 As Integer
Dim tst2 As Integer
Dim tst3 As Integer
Dim tst4 As Integer
Dim sndx2 As String
Dim w As String
Dim w2 As String
Dim w3 As String
Dim cons As String
Dim cons2 As String
Dim c1 As String
Dim c2 As String
Dim keys(4) As String
Dim roW As Long
Dim col As Long
Dim adjacent As Boolean
Dim got1 As Boolean
Dim wID As Long
Dim q As Long
Dim q1 As Long
Dim q2 As Long
Dim q3 As Long
Dim sug(1000) As String
Dim capWord As String
Dim tempWord As String
Dim z As Long
Dim runOnWords() As String
Dim s As String
Dim changingSndx As Boolean
Dim originalSndx As String
If Len(str_Word) < 2 Then Exit Sub
lstSuggestions.Clear
lstSuggestions.Height = lb_Links.Height - b_CloseSuggestions.Height
lstSuggestions.Visible = True
b_CloseSuggestions.Visible = True
b_UseSuggestion.Visible = True
CheckSndx:
s = LCase$(Left$(str_Word, 1))
cons = Replace$(LCase$(str_Word), "a", "")
cons = Replace$(LCase$(cons), "e", "")
cons = Replace$(LCase$(cons), "i", "")
cons = Replace$(LCase$(cons), "o", "")
cons = Replace$(LCase$(cons), "u", "")
If InStr("aeiou", s) > 0 Then cons = s & cons
With WordsRS
' Swap out each letter and look for words: '
.Index = "Text"
k = Len(str_Word)
For i = 1 To k
w2 = str_Word
c1 = Mid$(w2, i, 1)
z = Asc(c1)
For j = 97 To 122
If j <> z Then
Mid$(w2, i, 1) = Chr$(j)
.Seek "=", w2
If Not .NoMatch Then
lstSuggestions.AddItem !Text
End If
End If
Next
Next
q1 = InStr(str_Word, "'")
q2 = InStr(q1 + 2, str_Word, "'")
q3 = InStr(q2 + 2, str_Word, "'")
If q1 > 1 And q2 > 0 Then
w2 = Left$(str_Word, q1 - 1)
.Seek ">=", w2
If Not .NoMatch Then
z = Len(w2)
q = Len(str_Word)
Do
Do While q <> Len(!Text) And w2 = LCase$(Left$(!Text, z))
.MoveNext
Loop
If w2 <> Left$(!Text, z) Then Exit Do
tempWord = !Text
Mid$(tempWord, q1) = "'"
Mid$(tempWord, q2) = "'"
If q3 > 0 Then Mid$(tempWord, q3) = "'"
If tempWord = str_Word Then
lstSuggestions.AddItem !Text
End If
.MoveNext
Loop
End If
End If
w = t_Word
MatchSndx:
.Index = "Soundex"
.Seek "=", sndx
If Not .NoMatch Then
CortexRS.Index = "WordID"
CortexRS.Seek "=", !id
If Not CortexRS.NoMatch Then
If CortexRS!linkID = 31015 Or CortexRS!linkID = 31040 Then
If Not IsNull(CortexRS!startID) Then
wID = CortexRS!startID
CortexRS.Index = "ID"
CortexRS.Seek "=", wID
If CortexRS.NoMatch Then Stop
If IsNull(CortexRS!WordID) Then Stop
.Index = "ID"
wID = CortexRS!WordID
.Seek "=", wID
If .NoMatch Then Stop
For i = 1 To 6: lstSuggestions.AddItem " ": Next
lstSuggestions.AddItem !Text, 0
Exit Sub
End If
End If
End If
Do While !Soundex = sndx
lstSuggestions.AddItem !Text
.MoveNext
If .NoMatch Then
Exit Do
End If
Loop
End If
If Left$(w, 2) = "aq" Then
w = "acq" & Mid$(w, 3)
sndx = Soundex(w)
GoTo MatchSndx
End If
w2 = sndx
c2 = Mid$(w2, 2, 1)
Mid$(w2, 2, 2) = Mid$(w2, 3, 1) & c2
.Seek ">=", w2
If Not .NoMatch Then
Do While Left$(!Soundex, Len(w2)) = w2
lstSuggestions.AddItem !Text
.MoveNext
If .EOF Then Exit Do
Loop
End If
' Swap 2nd-3rd digits (e.g.: 15 -> 51): '
w2 = sndx
c2 = Mid$(w2, 3, 1)
If Not (Mid$(w2, 4, 1) = "0" And c2 = "0") Then
' Don't swap one 0 for another. '
Mid$(w2, 3, 2) = Mid$(w2, 4, 1) & c2
.Seek ">=", w2
If Not .NoMatch Then
Do While !Soundex = w2
lstSuggestions.AddItem !Text
.MoveNext
If .EOF Then Exit Do
Loop
End If
End If
' See if text is a run-on word: '
If Len(str_Word) > 3 Then
int_Nested = 0
FindRunOns str_Word, ""
FindAffixes str_Word
End If
keys(0) = " "
keys(1) = " qwertyuiop "
keys(2) = " asdfghjkl '"
keys(3) = " zxcvbnm "
keys(4) = " "
' Check for dropped first letter: '
.Index = "Text"
For j = 97 To 122 ' a - z '
w2 = Chr$(j) & str_Word
.Seek "=", w2
If Not .NoMatch Then
lstSuggestions.AddItem w2
got1 = True
End If
Next
j = Len(str_Word)
For i = 1 To j
c1 = LCase$(Mid$(str_Word, i, 1))
c2 = LCase$(Mid$(str_Word, i + 1, 1))
If c2 = "'" And Right$(" " & str_Word, 3) = "in'" And i = j Then
' e.g.: runnin' '
w2 = ChopRight(str_Word, 1) & "g"
.Seek "=", w2
If Not .NoMatch Then
lstSuggestions.AddItem w2
got1 = True
End If
End If
If c2 = "-" Then Exit For
If c2 > "z" Then Stop: Exit For
col = InStr(keys(1), c2)
If col > 0 Then
roW = 1
Else
col = InStr(keys(2), c2)
If col > 0 Then
roW = 2
Else
col = InStr(keys(3), c2)
roW = 3
End If
End If
adjacent = False
For j = -1 To 1 ' row '
For k = 0 To 2 ' col '
If Mid$(keys(roW + j), col + k, 1) = c1 Then
adjacent = True
End If
w2 = Left$(str_Word, i - 1) & Mid$(str_Word, i + 1)
.Seek "=", w2
If Not .NoMatch Then
Do While !Text <> w2 And LCase$(!Text) = LCase$(w2)
.MoveNext
If .EOF Then Exit Do
Loop
If !Text = w2 Then
lstSuggestions.AddItem w2
got1 = True
End If
End If
Next
Next
If Not adjacent Then
col = InStr(keys(1), c1)
If col > 0 Then
roW = 1
Else
col = InStr(keys(2), c1)
If col > 0 Then
roW = 2
Else
col = InStr(keys(3), c1)
roW = 3
End If
End If
For j = -1 To 1
If roW + j = 0 Then j = 0 ' row 0 is blank '
For k = -1 To 1
w2 = str_Word
c2 = Mid$(keys(roW + j), col + k, 1)
If c2 <> " " Then
Mid$(w2, i, 1) = Mid$(keys(roW + j), col + k, 1)
.Seek "=", w2
If Not .NoMatch Then
Do While !Text <> w2 And LCase$(!Text) = LCase$(w2)
.MoveNext
If .EOF Then Exit Do
Loop
If !Text = w2 Then
lstSuggestions.AddItem w2
got1 = True
End If
End If
End If
Next
If roW + j = 3 Then Exit For ' row 4 is blank '
Next
End If
w2 = str_Word
Mid$(w2, i, 2) = Mid$(w2, i + 1, 1) & Mid$(w2, i, 1)
.Seek "=", w2
If Not .NoMatch Then
Do While !Text <> w2 And LCase$(!Text) = LCase$(w2)
.MoveNext
If .EOF Then Exit Do
Loop
If !Text = w2 Then
lstSuggestions.AddItem w2
got1 = True
End If
End If
If i < Len(str_Word) Then
w3 = str_Word
If Mid$(str_Word, i, 1) = "'" Then
w3 = Left$(w3, i - 1) & Mid$(w3, i + 1)
End If
For j = 97 To 122 ' a - z '
w2 = Left$(w3, i) & Chr$(j) & Mid$(w3, i + 1)
.Seek "=", w2
If .NoMatch Then
If i = 1 Then
w2 = Chr$(j) & w3
Else
w2 = Left$(w3, i - 1) & Chr$(j) & Mid$(w3, i)
End If
.Seek "=", w2
End If
If Not .NoMatch Then
Do While !Text <> w2 And LCase$(!Text) = LCase$(w2)
.MoveNext
If .EOF Then Exit Do
Loop
If !Text = w2 Then
lstSuggestions.AddItem w2
got1 = True
End If
End If
Next
End If
Next
For j = 97 To 122 ' a - z '
w2 = str_Word & Chr$(j)
.Seek "=", w2
If Not .NoMatch Then
Do While !Text <> w2 And LCase$(!Text) = LCase$(w2)
.MoveNext
If .EOF Then Exit Do
Loop
If !Text = w2 Then
lstSuggestions.AddItem w2
got1 = True
End If
End If
Next
If Left$(str_Word & " ", 3) = "non" Then
w2 = Mid$(str_Word, 4)
.Index = "Text"
.Seek "=", w2
If Not .NoMatch Then
lstSuggestions.AddItem "non" & w2
End If
End If
i = InStr(str_Word, "chu")
If i > 0 Then
w2 = Replace$(str_Word, "chu", "tu")
.Index = "Text"
.Seek "=", w2
If Not .NoMatch Then
lstSuggestions.AddItem w2
End If
End If
If InStr(str_Word, "-n-") > 0 Then ' May need to do this for 'n' as well. '
' cut-n-paste = cut-and-paste '
w2 = Replace$(str_Word, "-n-", "-and-")
.Index = "Text"
.Seek "=", w2
If Not .NoMatch Then
lstSuggestions.AddItem w2
End If
End If
End With
If originalSndx <> "" Then
' See code further down which '
' sets "originalSndx". '
i = Val(Right$(sndx, 1))
j = Val(Right$(originalSndx, 1))
i = i + 1
If i = j Then i = i + 1
If i < 10 Then
sndx = ChopRight(sndx, 1) & i
GoTo CheckSndx
End If
End If
' Filter suggestions to get reasonable matches: '
With lstSuggestions
If .ListCount > 0 Then
ReDim scores(1, .ListCount - 1) As Integer
ReDim hiQ(1) As Integer
i = 0
' Remove duplicates: '
Do While i < .ListCount - 1
Do While .List(i) = .List(i + 1)
.RemoveItem i
Loop
i = i + 1
Loop
If .ListCount = 0 Then
GoTo WikiList
End If
i = 0
Do While i < .ListCount
w3 = .List(i)
Do While InStr(.List(i), " ") > 0
i = i + 1
If i = .ListCount Then Exit Do
Loop
If i = .ListCount Then Exit Do
If str_Word <> w3 Then
If Abs(Len(str_Word) - Len(w3)) > 2 Then
scores(0, i) = 0
scores(1, i) = 0
Else
scores(0, i) = qGram(str_Word, w3) _
- Abs(Len(str_Word) _
- Len(w2))
scores(1, i) = nGram(str_Word, w3)
End If
For j = 0 To 1
If scores(j, i) > hiQ(j) Then
hiQ(j) = scores(j, i)
End If
Next
End If
i = i + 1
Loop
n = .ListCount - 1
For i = n To 0 Step -1
sug(i) = .List(i)
Do While InStr(.List(i), " ") > 0
sug(i) = .List(i)
i = i - 1
If i < 0 Then Exit For
Loop
If str_Word <> sug(i) Then
k = LevDist(str_Word, sug(i))
If k < 5 Or (sug(i) <> "zzzz" And scores(0, i) > 0 And _
(scores(1, i) > 0 Or _
Len(str_Word) < 4)) _
Then
tst1 = Len(str_Word) > 4 And _
hiQ(0) - scores(0, i) > 2
tst2 = Len(str_Word) > 2 And _
Len(str_Word) < 5
tst3 = scores(0, i) < 2
tst4 = hiQ(1) - scores(1, i) > 1 And _
Len(str_Word) - hiQ(1) < 4
w = Left$(sug(i), 1)
cons2 = Replace$(sug(i), "a", "")
cons2 = Replace$(cons2, "e", "")
cons2 = Replace$(cons2, "i", "")
cons2 = Replace$(cons2, "o", "")
cons2 = Replace$(cons2, "u", "")
If InStr("aeiou", w) > 0 Then cons2 = w & cons2
If (tst1 And tst2 And tst3) Or _
tst4 Or _
Abs(Len(str_Word) - Len(w3)) > 2 _
Then
If LCase$(cons) <> LCase$(cons2) And k > 3 Then
sug(i) = "zzzz"
End If
End If
ElseIf i < .ListCount And _
str_Word <> Replace$(sug(i), "-", "") And _
str_Word <> Replace$(sug(i), "'", "") _
Then
sug(i) = "zzzz"
Else
Stop
End If
End If
Next
End If
.Clear
j = 0
Do
If sug(j) <> "zzzz" Then .AddItem sug(j)
j = j + 1
Loop While sug(j) <> "" Or j < n
Do While .List(0) = "" And .ListCount > 0
.RemoveItem 0
Loop
If .ListCount > 0 Then
lev = 999
n = 0
Do
w3 = .List(n)
.RemoveItem n
If (Abs(Len(str_Word) - Len(w3)) < 4 Or _
InStr(w3, " ") > 0) And _
Left$(w3, 2) <> " P" _
Then
If InStr(w3, " ") > 0 And Left$(w3, 1) > "9" Then
' Split up a run-on word. '
' Make it go after after '
' non-split words with 1. '
.AddItem "2 - " & w3
n = n + 1
Else
If str_Word = w3 Then
l = 0
Else
l = LevDist(str_Word, w3)
End If
If (l < 3 Or (l = 3 And Len(str_Word) > 5)) And w3 <> " " Then
FindWordID w3 ' sets long_WordID '
FindWordIDEntry w3, long_WordID ' sets long_CortexID '
If long_CortexID = 0 Then
w3 = w3 & " (Not in Cortex.)"
'Stop
End If
.AddItem l & " - " & w3
n = n + 1
If l < lev Then lev = l
End If
End If
End If
Loop While n < .ListCount
End If
End With
WikiList:
' Look in Wikipedia's list of common misspellings: '
With WikiSpellRS
.Index = "Wrong"
.Seek "=", str_Word
If Not .NoMatch Then
Do
w3 = !Right
lstSuggestions.AddItem "0 - " & w3 & " (WikiSpell table)", 0
.MoveNext
Loop While !Wrong = w3
End If
End With
With WordsRS
If Len(str_Word) > 5 And Val(lstSuggestions.List(0)) > 1 Then
w2 = Left$(str_Word, 3)
.Seek ">=", w2
If Not .NoMatch Then
Do
i = LevDist(str_Word, !Text)
If i < 3 And InStr(!Text, " ") = 0 Then ' arbitrary '
lstSuggestions.AddItem i & " - " & !Text
End If
.MoveNext
If .EOF Then Exit Do
Loop While w2 = Left$(LCase$(!Text), 3)
' Remove duplicates: '
i = 0
Do While i < lstSuggestions.ListCount - 1
Do While Replace$(lstSuggestions.List(i), _
" (Not in Cortex.)", "") = _
Replace$(lstSuggestions.List(i + 1), _
" (Not in Cortex.)", "")
lstSuggestions.RemoveItem i
Loop
i = i + 1
Loop
End If
End If
End With
n = lstSuggestions.ListCount - 1
sug(0) = ""
With WordsRS 'WordFreqRS
WordsRS.Index = "Text"
For i = 0 To n
sug(i) = lstSuggestions.List(i)
j = Val(sug(i))
w3 = Mid$(sug(i), 5)
z = InStr(w3, " (")
If z > 0 Or Left$(w3, 1) = "0" Then
s = Mid$(w3, z)
w3 = Left$(w3, z - 1)
Else
s = ""
End If
If InStr(w3, " ") = 0 Then
.Seek "=", w3
If Not WordsRS.NoMatch Then
If WordsRS!Text <> w3 Then WordsRS.MoveNext
k = WordsRS!Text <> w3
Else
k = 0
End If
If WordsRS.NoMatch Or k Or IsNull(WordsRS!FreqUsed) Then
sug(i) = j & " (z) - " & w3
ElseIf WordsRS!FreqUsed < "4" Or str_Word = w3 Then
sug(i) = j & " (" & WordsRS!FreqUsed & ") - " & w3
Else
sug(i) = ""
End If
If sug(i) <> "" Then sug(i) = sug(i) & s
Else
' Run-on word splits: '
sug(i) = j & " (s) - " & w3
'Words = Split(w3)
'Stop
End If
Next
End With
With lstSuggestions
.Clear
k = Val(sug(0))
For i = 0 To n
If sug(i) <> "" Then
If InStr(sug(i), "- =") > 0 Then
sug(i) = "0.0.0 (0) - " & Mid$(sug(i), 11)
z = 0
ElseIf Len(cons) > 2 Then
j = InStr(sug(i), "-")
cons2 = Mid$(sug(i), j + 2)
s = Left$(cons2, 1)
j = InStr(cons2, "(")
If j > 0 Then cons2 = Left$(cons2, j - 2)
q2 = Abs(Len(cons2) - Len(t_Word))
cons2 = Replace$(cons2, "a", "")
If Right$(cons2, 2) = "gn" Then
cons2 = Left$(cons2, Len(cons2) - 2) & "n"
End If
cons2 = Replace$(cons2, "e", "")
cons2 = Replace$(cons2, "i", "")
cons2 = Replace$(cons2, "o", "")
cons2 = Replace$(cons2, "u", "")
If InStr("aeiou", s) > 0 Then cons2 = s & cons2
z = LevDist(cons2, cons)
sug(i) = Left$(sug(i), 1) & "." & z & "." & q2 & Mid$(sug(i), 2)
Else
sug(i) = Left$(sug(i), 1) & ".0.0" & Mid$(sug(i), 2)
End If
If z < 10 Then
.AddItem sug(i)
End If
End If
Next
If .ListCount = 2 Then
If originalSndx = "" Then
originalSndx = sndx
If Right$(sndx, 1) = "0" Then
sndx = ChopRight(sndx, 1) & "1"
Else
sndx = ChopRight(sndx, 1) & "0"
End If
GoTo CheckSndx
Else
.AddItem " - No suggestions found."
Exit Sub
End If
End If
For i = 2 To .ListCount - 1
w3 = .List(i)
w3 = Replace$(w3, "(z", "(_")
.List(i) = w3
Next
End With
End Sub