# Visual Basic > Visual Basic 6 and Earlier >  any Improvements for this "word-spell-checking"

## baka

so, I want speed here and just spell-checking. word is a beast that can be used but I don't like it. sometimes resulting in crashes if used in real-time.
here my attempt, (very raw, early stuff)



```
Private Function CheckSpelling(w As String) As Boolean
    Dim i&, j&, l&, a&
    Static nw(1 To 31) As Byte
    
    With sSA
        .cElements1D = Len(w)
        .pvData = StrPtr(w)
        If .cElements1D > 30 Then .cElements1D = 30
        For i = 0 To .cElements1D - 1
            a = arrData2(i)
            If a > 64 And a < 91 Then a = a + 32
            If a > 96 And a < 123 Then
                l = l + 1
                nw(l) = a
            End If
        Next i
    End With
    
    If l < 2 Then CheckSpelling = True: Exit Function
        
    On Error GoTo dExit
    With word(nw(1)).l(l)
        For i = 1 To .len
            For j = 2 To l
                If .s(i).b(j) <> nw(j) Then GoTo dNext
            Next j
            CheckSpelling = True
            GoTo dExit
dNext:
        Next i
dExit:
    End With
End Function
```

so what Im doing:
- Im using safearray to read the string
- I want to skip non letter words and only checking lowercase, as u can see. (but I also ignore ' and that can be a problem here)
- if the length is 0/1 it will tell "its ok" otherwise it will do the spellchecking.

the next part is the dictionary. I have a UDT where I use A-Z and Length(1-31) (31 is the word in the max amount of letter for the words in the dictionary)
if something is not working, out of bound, it will result in error.

it works. but its not 100%
it will not understand some words combination. but I can add that into the list of words (again its not 100%)

the array is like this, for a word like: ABC = abc
a=97,b=98,c=99

word(97).l(3).S(1 to .len).b(2 to 3)
so it will only compare from 2 not 1 since we are inside the "a" array and only 3 letters words in the "l(3)" array.

I have a function that creates that UDT of course.

so any hints/suggestion to make it smarter without causing too much reading and comparing, its for speed and I dont need something perfect.

----------


## DaveDavis

ChatGPT reply：This function appears to be a custom spelling checker in Microsoft Visual Basic. It takes a single string argument w and returns a Boolean value indicating whether the string is spelled correctly or not.

The function first initializes an array nw of bytes and a variable l to 0. It then iterates through each character in the input string w, converts uppercase characters to lowercase, and stores only the lowercase alphabetical characters in the nw array. The length l of the nw array is also incremented for each lowercase alphabetical character found in the input string.

If the length l of the nw array is less than 2, the function immediately returns True since it is assumed that strings with less than two alphabetical characters are spelled correctly. Otherwise, the function searches through a data structure called word for a match to the input string and returns True if a match is found, False otherwise.

It is worth noting that this function uses the GoTo statement, which can make the code harder to read and maintain. It is generally recommended to avoid using GoTo in favor of more structured control flow statements such as If, For, and While.

----------


## baka

I seldom use Goto. but sometimes its useful and its fast.
since Im using a "with block" i need to be closed before I exit the function. that is why I need 2 goto,
one to just close the with before it exit.
if u can make it better Im all for it. but we should not be afraid of using Goto, since its not something bad, but as u say if u are not used of it it can be hard to read.

----------


## wqweto

> It is generally recommended to avoid using GoTo in favor of more structured control flow statements such as If, For, and While.

If, For, and While do not replace GoTo -- it is *Exit* For, *Exit* Do and *Exit* Sub which do.

Let's talk about the elephant in the room -- each of these Exit statements is a hidden goto. And so are break/continue statements in C/C++ and every other language which have these.

So not using GoTo explicitly does not mean you are not using goto in the sense Dijkstra considered in his famous Go To Statement Considered Harmful paper.

Everybody loves to break early their loops so let's accept reality for what it is for once :-))

cheers,
</wqw>

----------


## couttsj

I personally use the InkEdit Control for its spell checking facilities. It is fast and efficient. For further info, see:

https://www.vbforums.com/showthread....VB6-Ink-Editor

J.A. Coutts

----------


## baka

that is not working in windows 7. can't even start it. runtime error. 
but I don't like using a component, as u see, I can't even run it.

----------


## baka

```
Private Function arrsss() As Boolean
    sss = sss + 1
    If sss > eee Then arrsss = True
    iii = True
End Function

Private Function arreee() As Boolean
    eee = eee - 1
    If eee < sss Then arreee = True
    iii = True
End Function


Private Function CheckSpelling(w As String) As Boolean
    Dim i&, j&, l&, a&, f As Boolean
    
    sSA.cElements1D = Len(w)
    sSA.pvData = StrPtr(w)
    sss = 0
    eee = sSA.cElements1D - 1
    '
    Do
        iii = False
        ' "
        If arrData2(sss) = 34 Then If arrsss Then Exit Function
        If arrData2(eee) = 34 Then If arreee Then Exit Function
        ' ()
        If arrData2(sss) = 40 Then If arrsss Then Exit Function
        If arrData2(eee) = 40 Then If arreee Then Exit Function
        ' <>
        If arrData2(sss) = 60 Then If arrsss Then Exit Function
        If arrData2(eee) = 62 Then If arreee Then Exit Function
        ' []
        If arrData2(sss) = 91 Then If arrsss Then Exit Function
        If arrData2(eee) = 93 Then If arreee Then Exit Function
        ' : ; ,
        If arrData2(eee) = 58 Then If arreee Then Exit Function
        If arrData2(eee) = 59 Then If arreee Then Exit Function
        If arrData2(eee) = 44 Then If arreee Then Exit Function
        ' ! ? .
        If arrData2(eee) = 33 Then If arreee Then CheckSpelling = True: Exit Function
        If arrData2(eee) = 63 Then If arreee Then CheckSpelling = True: Exit Function
        If arrData2(eee) = 46 Then If arreee Then CheckSpelling = True: Exit Function
        If arrData2(sss) = 46 Then If arrsss Then CheckSpelling = True: Exit Function
        '
    Loop Until iii = False

    For i = sss To eee
        a = arrData2(i)
        If a > 64 And a < 91 Then a = a + 32
        If a = 39 Or a = 96 Then
            ' nothing
        Else
            If a > 96 And a < 123 Then f = True
            l = l + 1: nw(l) = a
        End If
    Next i

    If l < 2 Or f = False Then CheckSpelling = True: Exit Function
        
    On Error GoTo dExit
    With word(nw(1)).l(l)
        For i = 1 To .len
            For j = 2 To l
                If .s(i).b(j) <> nw(j) Then GoTo dNext
            Next j
            CheckSpelling = True
            GoTo dExit
dNext:
        Next i
dExit:
    End With
End Function
```

I update it a bit to be a bit smarter with the word if theres characters (instead of just remove it)
theres more calculations but its quite fast anyway.

----------


## wqweto

> ```
> Private Function arrsss() As Boolean
>     sss = sss + 1
>     If sss > eee Then arrsss = True
>     iii = True
> End Function
> 
> Private Function arreee() As Boolean
>     eee = eee - 1
> ...


I cant run your code by copy/paste under Windows 11 too  compiler says its missing. . . everything  :Smilie: )

----------


## baka

well. u need to add the UDT and some variables



```
Private Type SAFEARRAY1D
    cDims               As Integer
    fFeatures           As Integer
    cbElements          As Long
    cLocks              As Long
    pvData              As Long
    cElements1D         As Long
    lLbound1D           As Long
End Type

Private Type worddata2
    b()                 As Byte
End Type

Private Type worddata1
    s()                 As worddata2
    len                 As Integer
End Type
  
Private Type worddata
    l(1 To 31)          As worddata1
End Type

Dim nw(1 To 99) As Byte
Dim sss&, eee&, iii As Boolean
Dim word(97 To 122)  As worddata
Dim arrData2()  As Integer
```

and u need to initialize the safearray



```
Private Declare Function ShortArrayPtr Lib "msvbvm60" Alias "VarPtr" (a() As Integer) As Long
Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Addr As Long, ByVal NewVal As Long)

With sSA: .cbElements = 2&: .cDims = 1: End With
PutMem4 ShortArrayPtr(arrData2), VarPtr(sSA)
' dont forget to clear it
PutMem4 ShortArrayPtr(arrData2), 0
```

and u need to create the UDT with the words.
here the function I use in my "builder tool"



```
Sub AddWord(w$)
    Dim a$, l&, l1&, c&, i, B&
    
    a = Left$(w, 1)
    l1 = Asc(a)
    l = Len(w)
       
    If l > 1 Then
        c = word(l1).l(l).len + 1
        word(l1).l(l).len = c
        ReDim Preserve word(l1).l(l).s(1 To c)
        ReDim word(l1).l(l).s(c).B(2 To l)
        For i = 2 To l
            B = Asc(Mid$(w, i, 1))
            Select Case B
                Case 65 To 90: B = B + 32
                Case 39: B = 96 
            End Select
            word(l1).l(l).s(c).B(i) = B
        Next i
    End If
End Sub
```

u will need to use your own wordlist. should be easy enough for u

----------

