Solved

event action during the Next.......For cycle

Posted on 2002-04-26
14
293 Views
Last Modified: 2008-02-01
G'day,
Is it possible to wait for a typing event to be activated during the For.. Next cycle ??
For instance:
I want to spell a word with For...Next
For t = 1 to Len("myword")
Letter=Mid("myword",t,1)
  'now go to a sub 'Compare'where the user is enabled to type the 'Letter' and if correct back to the next For...next cycle and so on.
This is similar to a recently answered question but I am still interested in this particular approach.
Thank you,    Dan
0
Comment
Question by:dierdan
  • 6
  • 5
  • 2
  • +1
14 Comments
 
LVL 1

Expert Comment

by:COAtheGREAT
ID: 6970651
use DoEwents inside For.. Next cycle if you want to enable user to do something while you are in cycle, but this is not god approach
0
 
LVL 2

Expert Comment

by:corvanderlinden
ID: 6970669
I do not know if I understand the problem, but wouldn't it be more logical to call the For ..Next in the DataChanged event of the textBox ?

0
 
LVL 43

Expert Comment

by:TimCottee
ID: 6970946
DoEvents will not work in this scenario as it doesn't actually pause processing, you SHOULD use the TextBox_Change event to determine what is going on. Alternatively you could also use the KeyPress event of the texbox.

It would help to understand what you are trying to achieve to best advise you on this.
0
 
LVL 1

Expert Comment

by:COAtheGREAT
ID: 6971090
TextBox_Change will not fier until he exit for..next only way he can catch TextBox_Change or TextBox_KeyPress  event is DoEvents.
0
 

Author Comment

by:dierdan
ID: 6972794
Thank you all for your interest.
Sorry if I haven't made myself clear enough regarding my question.
My project has a speech engine say a random word from a word list. This word I want spelled out (by the speech engine) for the user to type. My approach is shown in my question but I have been unsuccesful doing a 'comparison' outside of a For..Next cycle.
The For...Next counts through all cycles instead of allowing the user to type a response to the vocalised Letter.
Hope this clarifies the question.          Dan
0
 

Author Comment

by:dierdan
ID: 6974191
Increased points
0
 
LVL 43

Expert Comment

by:TimCottee
ID: 6976628
dierdan, a rethink of your structure is necessary. Here is an example of the pseudo-code that you would use:

Private strWord As String

Private Sub cmdNewWord_Click()
  strWord = "Random Word"
  SpeechEngine.Say strWord
End Sub

Private Sub txtWord_Change()
  For intLetter = 1 To Len(txtWord)
    If Mid(txtWord.Text,intLetter,1) <> Mid(strWord,intLetter,1) Then
      'Handle an incorrect letter
    Else
      'Presumably continue with no action
    End If
  Next
  If WordSpeltCorrectly And WordIsComplete Then
    Msgbox "Well Done you got it correct!"
  End If
End Sub

Of course this code will not compile as written but the structure is appropriate for this sort of task. You just need to implement your "random word" creation and neaten up the _Change event code and you are done.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:dierdan
ID: 6982493
Thank you TimCottee for your comment.

I have tried your code structure;however,your solution doesn't meet my requirements which in essence are:
Word is generated
Word is spoken
First letter of word is spoken
Textbox has focus and waits for a Keypress
If Keypress is correct letter then next letter is spoken
If Keypress is incorrect letter then "wrong" indication and wait for the correct Keypress

The crux of the problem seems to be:
How do you hold a For...Next cycle in a textbox keypress and return to the For...Next only after the appropriate Keypress.
Cheers,      Dan
0
 
LVL 43

Expert Comment

by:TimCottee
ID: 6982947
Dan, in essence you cannot. This breaks the event-driven model of VB you can only code in such a way as to deal with the process in an eventdriven manner. Some slight changes to the structure I posted can comply with your process.

Private strWord As String
Private intLetter As Integer

Private Sub cmdNewWord_Click()
 intLetter = 1
 strWord = "Random Word"
 SpeechEngine.Say strWord
End Sub

Private Sub SayLetter()
 SpeechEngine.Say Mid(strWord,intLetter,1) 'The next Letter
End Sub

Private Sub txtWord_Change()
 Static blnChanging As Boolean
 If blnChanging Then
   Exit Sub 'This will avoid re-entrance to the change event when the contents of the text box are changed within the event
 End If
 blnChanging = True
 For intLetter = 1 To Len(txtWord)
   If Mid(txtWord.Text,intLetter,1) <> Mid(strWord,intLetter,1) Then
     'Handle an incorrect letter
     txtWord.Text = Left(txtWord.Text,Len(txtWord.Text) -1)
     'trim off the last entered letter as it is wrong
     'optionally display an error message here
     Msgbox "Wrong Letter, sorry!",vbExclamation + vbOKOnly
   Else
     'Presumably continue with no action
     intLetter = intLetter + 1
     SayLetter 'Say the next letter
   End If
 Next
 If WordSpeltCorrectly And WordIsComplete Then
   Msgbox "Well Done you got it correct!"
 End If
 blnChanging = False 'reset the flag so that the next change can be processed.
End Sub
0
 

Author Comment

by:dierdan
ID: 6985160
Tim, there seems to be a problem with 'inLetter'.
If you run the code you will find that if you spell the word correctly ( ignore the spoken spelling) all's well.
The spoken spelling repeats letters and correctly spells every second letter. I experimented with the sequence of events but got into all sorts of strife.
Thanks for your interest,     Dan

'References:Microsoft speech objects library

Public V As SpeechLib.SpVoice
Public S As SpeechLib.ISpeechObjectToken
Dim Voice As SpVoice
Dim intLetter As Integer
Private strWord As String

Private Sub cmdNewWord_Click()
intLetter = 1
strWord = "random"
Voice.Speak strWord
 SayLetter
End Sub

Private Sub SayLetter()
Voice.Speak Mid(strWord, intLetter, 1)  'The next Letter
txtWord.SetFocus
End Sub

Private Sub Form_Load()
    Set Voice = New SpVoice
    Dim strVoice As String
End Sub

Private Sub txtWord_Change()
Static blnChanging As Boolean
If blnChanging Then
  Exit Sub 'This will avoid re-entrance to the change event when the contents
  'of the text box are changed within the event
End If
blnChanging = True
For intLetter = 1 To Len(txtWord)
  If Mid(txtWord.Text, intLetter, 1) <> Mid(strWord, intLetter, 1) Then
    'Handle an incorrect letter
    txtWord.Text = Left(txtWord.Text, Len(txtWord.Text) - 1)
    'trim off the last entered letter as it is wrong
    'optionally display an error message here
    MsgBox "Wrong Letter, sorry!", vbExclamation + vbOKOnly
  Else
    'Presumably continue with no action
    intLetter = intLetter + 1
    SayLetter 'Say the next letter
  End If
Next
'If WordSpeltCorrectly And WordIsComplete Then
'  MsgBox "Well Done you got it correct!"
'End If
blnChanging = False 'reset the flag so that the next change can be processed.
End Sub



0
 
LVL 43

Expert Comment

by:TimCottee
ID: 6985446
Purely and simply my fault, I made a fairly basic error in that I used the same variable as the next letter and to iterate the letters in the word. This would cause the second letter to be spoken each time. If you change the iterative variable intLetter to intLetter2Check as below this should resolve this issue.

Public V As SpeechLib.SpVoice
Public S As SpeechLib.ISpeechObjectToken
Dim Voice As SpVoice
Dim intLetter As Integer
Private strWord As String

Private Sub cmdNewWord_Click()
intLetter = 1
strWord = "random"
Voice.Speak strWord
SayLetter
End Sub

Private Sub SayLetter()
Voice.Speak Mid(strWord, intLetter, 1)  'The next Letter
txtWord.SetFocus
End Sub

Private Sub Form_Load()
   Set Voice = New SpVoice
   Dim strVoice As String
End Sub

Private Sub txtWord_Change()
Static blnChanging As Boolean
If blnChanging Then
 Exit Sub 'This will avoid re-entrance to the change event when the contents
 'of the text box are changed within the event
End If
blnChanging = True
For intLetter2Check = 1 To Len(txtWord)
 If Mid(txtWord.Text, intLetter2Check, 1) <> Mid(strWord, intLetter2Check, 1) Then
   'Handle an incorrect letter
   txtWord.Text = Left(txtWord.Text, Len(txtWord.Text) - 1)
   'trim off the last entered letter as it is wrong
   'optionally display an error message here
   MsgBox "Wrong Letter, sorry!", vbExclamation + vbOKOnly
 Else
   'Presumably continue with no action
   intLetter = intLetter + 1
   SayLetter 'Say the next letter
 End If
Next
'If WordSpeltCorrectly And WordIsComplete Then
'  MsgBox "Well Done you got it correct!"
'End If
blnChanging = False 'reset the flag so that the next change can be processed.
End Sub
0
 

Author Comment

by:dierdan
ID: 6989518
Thanks Tim.
If you run your last code you will find several errors.
Several letters are uttered before they are due for typing because 'Sayword' is within the For..Next loop.
Fix: made this a conditional 'Sayword'
For correct spelling:  ok

We now have 2 Wrong-spelling defects:
1. next letter after wrong one is said before wrong letter is correctly typed
2.cursor is located at the start of the text

I have no idea how to programatically place a text cursor.

Cheers,      Dan
0
 

Author Comment

by:dierdan
ID: 6989533
'Your modified code:

Public V As SpeechLib.SpVoice
Public S As SpeechLib.ISpeechObjectToken
Dim Voice As SpVoice
Dim intLetter As Integer
Dim intLetter2Check As Integer
Private strWord As String

Private Sub cmdNewWord_Click()
intLetter = 0
strWord = "random word"
Voice.Speak strWord
SayLetter
End Sub

Private Sub SayLetter()
  intLetter = intLetter + 1
Voice.Speak Mid(strWord, intLetter, 1)  'The next Letter
txtWord.SetFocus
End Sub

Private Sub Form_Load()
  Set Voice = New SpVoice
  Dim strVoice As String
End Sub

Private Sub txtWord_Change()
Static blnChanging As Boolean
If blnChanging Then
Exit Sub 'This will avoid re-entrance to the change event when the contents
'of the text box are changed within the event
End If
blnChanging = True
For intLetter2Check = 1 To Len(txtWord)
If Mid(txtWord.Text, intLetter2Check, 1) <> Mid(strWord, intLetter2Check, 1) Then
  'Handle an incorrect letter
  txtWord.Text = Left(txtWord.Text, Len(txtWord.Text) - 1)
  'trim off the last entered letter as it is wrong
  'optionally display an error message here
  MsgBox "Wrong Letter, sorry!", vbExclamation + vbOKOnly
  If intLetter > 1 Then
  intLetter = intLetter - 2
  Else: intLetter = 0
  End If
  SayLetter
Else
  'Presumably continue with no action
  Label1.Caption = intLetter & " " & Len(txtWord)
If intLetter = Len(txtWord) Then SayLetter  'Say the next letter
End If
Next
'If WordSpeltCorrectly And WordIsComplete Then
'  MsgBox "Well Done you got it correct!"
'End If
blnChanging = False 'reset the flag so that the next change can be processed.
End Sub
0
 
LVL 43

Accepted Solution

by:
TimCottee earned 200 total points
ID: 6993554
Ok, had another look and this time it appears to be ok, no spurious letters and included the final check that the entire word is correct.

Private Sub txtWord_Change()
Static blnChanging As Boolean
If blnChanging Then
Exit Sub 'This will avoid re-entrance to the change event when the contents
'of the text box are changed within the event
End If
blnChanging = True
For intLetter2Check = 1 To Len(txtWord)
If Mid(txtWord.Text, intLetter2Check, 1) <> Mid(strWord, intLetter2Check, 1) Then
 'Handle an incorrect letter
 txtWord.Text = Left(txtWord.Text, Len(txtWord.Text) - 1)
 'trim off the last entered letter as it is wrong
 'optionally display an error message here
 MsgBox "Wrong Letter, sorry!", vbExclamation + vbOKOnly
' If intLetter > 1 Then
 intLetter = intLetter - 1
' Else: intLetter = 0
' End If
 SayLetter
Else
 'Presumably continue with no action
 Label1.Caption = intLetter & " " & Len(txtWord)
If intLetter2Check = Len(txtWord) Then SayLetter  'Say the next letter
End If
Next
txtWord.SelStart = Len(txtWord.Text)
If txtWord.Text = strWord Then
  MsgBox "Well Done you got it correct!"
End If
blnChanging = False 'reset the flag so that the next change can be processed.
End Sub
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now