Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to make "Autokey"? 4

Status
Not open for further replies.

catty1160

Technical User
Mar 10, 2003
38
0
0
US
I want to make some autokeys thah can bring in a paragraph of text into the field after I just type the autokeys(Key letters). Ex:

Autokeys(Key letters) Text

b Beginner class- Room 102

in intermediate class- Room 103

ad Advanced class - romm 105

I need the codes to make the program be able to input all the text for me after I just type the key letters, Ex:"b", maybe plus another key to indicate using of autokey, then the whole texts ("b" for "Beginner class... ", "in" for "intermediate class-...", .. and so on)will be entered into the field. Anybody can help? Thanks.

Catty
 
If your text values are unique (at least after the first character) you can put them in a table linked to the entry field on a form. Typing the one or two characters needed to find a unique match, followed by a tab to the next field or control, will put the required text value in the field. You will need to either allow the entry of new text values into the table via the form, or to prevent this from occurring. If you allow entry, be aware that any upper case required in new entries must be specifically keyed by the user. Apart from this, lower case can be used for all autokey entries.

HTH

John
 
This might get you started, put this code in the Key_Up Event of your text box, I've assumed your text box field name is [ClassType]:

'--code start--

If KeyCode = 32 Then 'if spacebar is pressed check ClassType
Refresh
Select Case Trim([ClassType])
Case "b"
[ClassType] = "Beginner Class- "
Case "in"
[ClassType] = "Intermediate Class- "
Case "ad"
[ClassType] = "Advanced Class- "
Case Else
[ClassType] = [ClassType] & " "
End Select
[ClassType].SelStart = Len([ClassType])
End If

'--code end--

I am also making a huge assumption that the first character entered into [ClassType] be of class type value ("b", "in" or "ad") as if anything else is entered first besides these values, it won't work.

Because this is hard coded it will make it cumbersome to adjust. Initially however, it should do what you want it to do.

Let me know how you get on
[yinyang]
 
Thank you, John. If I need to link to a table. How many fields should I have in that table? 2 or 1? I mean... do I have to have a field called "autokey" and another field called "text"? and which filed will be linked to the field in the entry field on a form. If I want to enter both text of "beginner class" and "intermediate class" inside the same field, can it be achieved?

Catty
 
ShannonP1:

Great, it works. But I have two problem now. Probably, I did not indicate my question enough at initial posting.

1.I need the entry field able to take multiple autokeys and text in the same field. Ex: In the entry field, I may need to type "Beginner class-..., intermediate class-,.." inside the same field. I hope there is a way allow me to type "b' (autokey for beginner class)), space, then "in"(autokey for intermediate class) then space to get the full 2 text inside one field. The code I tested only good for auto key in one text.

2. Your code works well to autokey in the text,but I do not know if I really want to type the word "in" (not the autokey"in"), how do I do it?

Able to resolve?

Catty
 
ShannonP1,

In problem 1, maybe I should let you know the job also requires to enter some extra text isome time n addition to the text we autokey in. Ex: The entry field may need to take " beginner class-, intermediate class-, Only available in evening" The text of "only avialble in the evening" is typed in by hand manualy inside the same field.

Catty
 
Catty,

I recommend that you restructure your table to place the various text items in separate fields, and then use the capabilities of Access to 'string' them together for reporting or other purposes.

The way I have implemented my suggestion in small applications is to link a combo box to a query based on the main table, as follows:

SELECT [tblWineList].Vineyard
FROM [tblWineList]
GROUP BY [tblWineList].Vineyard
HAVING ((Not ([tblWineList].Vineyard) Is Null))
ORDER BY [tblWineList].Vineyard;

If your main table is too big for this approach, or if you have a static list of values, you could have a 'text value' table with only one field, linked to your combo box.

HTH

John

 
Another whacky approach:

1) create a module with this function:

Function InsertData(KeyCode As Integer)
Dim CurCtrl As Control
Set CurCtrl = Nothing
On Error Resume Next
Set CurCtrl = Screen.ActiveControl

If Not CurCtrl Is Nothing Then
Dim InsertText As String
InsertText = ""
Select Case KeyCode
Case 1
InsertText = "something"
Case 2
InsertText = "something else"
End Select

If Len(InsertText) > 0 Then
Dim CurText As String
CurText = CurCtrl.Text

Dim SelPos As Integer
SelPos = CurCtrl.SelStart
Dim SelLen As Integer
SelLen = CurCtrl.SelLength

Dim NewText As String
NewText = Left(CurText, SelPos) & InsertText & Right(CurText, Len(CurText) - SelPos - SelLen)
CurCtrl.Value = NewText
End If
End If
End Function

2) Create an autokeys macro
a) create a new macro
b) right click to show macro names
c) enter names like ^A, ^B
d) for the action, make it RunCode
e) in function name, type in something like
InsertData(1) for ^A
InsertData(2) for ^B

This code will be always ON, so some tips:

1) check the control name before deciding if you want to actually insert text
2) you may want to make an access table containing the text you want to insert, so it can be easily changed later. In that case, use DLookup to find the correct text to be inserted.

If you find this approach to your liking, additional details can be provided.
 
Hi, John and Beetee: Both are appreciated. However, this is not exactly what I want. Please refer to my original thread. I like to have a table with two fields, one is the autokeys (like "b" for Beginner class; "in" for intermediate class; and so on) and another field is Text. The table is something like this:

Autokeys Text

b Beginner class
in Intermediate class-
ad Advance class
rt right
lt left

Also, there is a form with the same 2 fields for users to create their own autokeys and corespondent text. After the autokeys are created, they can just type the autokey and another keys(like space key or control key) in fields of the program and will bring in the full text that autokey represents,just like speedy keys function we see in someprograms. This is to save users' time to type the full text every time. Please note that the user should be able to use multi autokeys in the same fields. Ex: They can type "rt (control key or something else to indicate using the autokey)" and "lt(control key or something else)" to bring in the tex " right and left". Ideally, they can expand their autokeys collection as thier want by entering into the form we provide to them.

Hopefully, this will give you more idea of my wish. Appreciate any input. Thanks.
 
step 1)

create a module, and put this code in.


Type KeyboardMacroType
MacroName As String
Expanded As String
End Type

Dim MacroNamesRead As Boolean

Dim MacroNamesArray() As KeyboardMacroType
Dim MacroNamesArrayEls As Integer
Dim MacroNamesArraySize As Integer

Dim CurrentValue As String
Dim CurrentValueLen As Integer
Dim ExpandTo As String
Const c_Trigger = 32

Sub AddKeyCode(MacroName As String, Expanded As String)
If MacroNamesArrayEls >= MacroNamesArraySize Then
MacroNamesArraySize = MacroNamesArraySize + 16
ReDim Preserve MacroNamesArray(MacroNamesArraySize)
End If
Dim counter As Integer
For counter = 0 To MacroNamesArrayEls - 1
If MacroNamesArray(counter).MacroName > MacroName Then Exit For
Next counter

Dim InsertAt As Integer
InsertAt = counter

Do While counter < MacroNamesArrayEls
MacroNamesArray(counter + 1) = MacroNamesArray(counter)
counter = counter + 1
Loop
With MacroNamesArray(InsertAt)
.MacroName = MacroName
.Expanded = Expanded
End With
MacroNamesArrayEls = MacroNamesArrayEls + 1
End Sub

Sub ReadKeyCodeTable()
If Not MacroNamesRead Then
Dim MyDb As DAO.Database
Set MyDb = CurrentDb

Dim MyRst As DAO.Recordset
Set MyRst = MyDb.OpenRecordset(&quot;KeyboardMacros&quot;)
Do While Not MyRst.EOF
AddKeyCode MyRst(&quot;MacroName&quot;), MyRst(&quot;Expanded&quot;)
MyRst.MoveNext
Loop
MyRst.Close
Set MyRst = Nothing
MyDb.Close
Set MyDb = Nothing
MacroNamesRead = True
End If
End Sub

Sub ProcessKeyDown(KeyCode As Integer, Shift As Integer)
Dim CurCtrl As Control
Set CurCtrl = Nothing
On Error Resume Next
Set CurCtrl = Screen.ActiveControl
If Not CurCtrl Is Nothing Then
ReadKeyCodeTable
If (KeyCode = c_Trigger) Then
If CurrentValueLen > 0 Then
Dim CurText As String
CurText = CurCtrl.Text
Dim SelPos As Integer
SelPos = CurCtrl.SelStart
Dim SelLen As Integer
SelLen = CurCtrl.SelLength

Dim NewText As String
NewText = Left(CurText, SelPos - Len(CurrentValue) - 1) & ExpandTo & Right(CurText, Len(CurText) - SelPos - SelLen)
CurCtrl.Value = NewText
CurCtrl.Text = NewText
CurCtrl.SelStart = Len(NewText)
CurCtrl.SelLength = 0
End If
CurrentValue = &quot;&quot;
CurrentValueLen = 0
ExpandTo = &quot;&quot;
End If
Dim CurChar As String
CurChar = Chr(KeyCode)
If CurChar >= &quot;A&quot; And CurChar <= &quot;z&quot; Then
CurrentValue = CurrentValue & Chr(KeyCode)
CurrentValueLen = CurrentValueLen + 1
Dim counter As Integer
Dim HadMatch As Boolean
HadMatch = False
For counter = 0 To MacroNamesArrayEls - 1
If Left(MacroNamesArray(counter).MacroName, CurrentValueLen) = CurrentValue Then
HadMatch = True
If MacroNamesArray(counter).MacroName = CurrentValue Then
ExpandTo = MacroNamesArray(counter).Expanded
Exit For
End If
End If
Next counter
If Not HadMatch Then
CurrentValue = CurChar
CurrentValueLen = 1
End If
End If
End If
End Sub


step 2)
for every field that you want to handle special keys, add this keydown event handler:

Private Sub Description_KeyDown(KeyCode As Integer, Shift As Integer)
ProcessKeyDown KeyCode, Shift
End Sub

NOTES:
Change the constant c_Trigger to the trigger character. Perhaps the shift value could be used to map control or alt as the trigger character.

Additional modifications are likely necessary for the table name and field names you are using.


 
This is a good one! Have a star from me [smile]
[pipe]
Daniel Vlas
Systems Consultant
 
Thanks Daniel,

Of course, there are some tweaks that can be added.

I stored the keystroke list in sorted order, but did not take advantage of that in the comparison loop. The loop should be exited when the current text is > than the compared text.

NOTE to others: if you find a way to use Control or Alt or whatever (based on the shift parameter, I imagine), remember to remove one less character from the existing control text (currently, it's including the trigger character).
 
Hi, Beetee:

It is a master piece, however, my level is not as Daniel and you yet. I tried very hard to read your codes several times, still not able to understand all of them. But I do get the sense of fuctions of the codes. I am a beginner in Access writing. I know it is still hard for me to put them together to make it work. Is it possible you can e-mail a functional one in a simple database (which includs a table of keycodes with fields, like Keycode and Text. the modules to process the keycode and expand the keycode to Text, a form for me to add new keycodes and Text, and a sample data entry form to test entering data in fields with keycodes).

I appreciate a lot.

Catty
 
Hi, Beetee:

Finally, I think I am close there, however, still not able to get it to work yet. I got some &quot;Compile error&quot; when the trigger key is pushed. Let me tell you what happened, maybe you can help me out:

In order to make things simple, I create a table with fields to be named after the names in your code. I have a table named &quot;KeyboardMacros&quot;, with 2 fields - &quot;MacroName&quot; and &quot;Expanded&quot;. I copy your code to a new module called &quot;SpeedyKeys&quot; ( I don't think this name will matter, right?). Then I have a form for data entry, called &quot;DataEntry&quot; with 2 fields to test entering data. I do add the keydown event handler that you offered to each field.
I also have some sample Macroname and Expanded in the KeyboardMacros table for me to try, like &quot;b&quot; for Beginner, &quot;In&quot; for Intermediate, ... It looks to me everything is all set to go. But when I typed b then space key in one of the fields in DataEntry form, It did not work. Instead, I was prompt with a window in module codes area saying: Compile Error, use type not defined... The debugger grey out this line &quot;Dim MyDb AS DAO.Database&quot; under Sub ReadKeyCodeTable(). (By the way, I do named my database as MyDb)

Did I miss something or did anything wrong?

Also, if I prefer to changing trigger key from Space to CTRL or ALT key, how do I do it?

Please advise. Thank you a lot.

Catty
 
Hi Catty,

I have a table named &quot;KeyboardMacros&quot;, with 2 fields - &quot;MacroName&quot; and &quot;Expanded&quot;.

That should work just fine.

I copy your code to a new module called &quot;SpeedyKeys&quot; ( I don't think this name will matter, right?).

No, the module name doesn't matter (unless you happen to give a module the same name as a function. In general, I put the word 'Module' at the end of a module name just in case).


Then I have a form for data entry, called &quot;DataEntry&quot; with 2 fields to test entering data. I do add the keydown event handler that you offered to each field.

That also sounds good.

I also have some sample Macroname and Expanded in the KeyboardMacros table for me to try, like &quot;b&quot; for Beginner, &quot;In&quot; for Intermediate, ... It looks to me everything is all set to go. But when I typed b then space key in one of the fields in DataEntry form, It did not work. Instead, I was prompt with a window in module codes area saying: Compile Error, use type not defined... The debugger grey out this line &quot;Dim MyDb AS DAO.Database&quot; under Sub ReadKeyCodeTable(). (By the way, I do named my database as MyDb)

Did I miss something or did anything wrong?


That problem is usually because you need to set a reference. The process is
1) open a module
2) select Tools:References from the menu
3) scroll down until you find Microsoft DAO 3.6
4) mark it in the check box as enabled.

Also, if I prefer to changing trigger key from Space to CTRL or ALT key, how do I do it?

after some testing, I discovered the algorithm is flawed, so here's a version that actually works:



Option Compare Database
Option Explicit

Type KeyboardMacroType
MacroName As String
MacroNameLen As Integer
Expanded As String
End Type

Dim MacroNamesRead As Boolean

Dim MacroNamesArray() As KeyboardMacroType
Dim MacroNamesArrayEls As Integer
Dim MacroNamesArraySize As Integer

Const c_Trigger = 32

Sub AddKeyCode(MacroName As String, Expanded As String)
If MacroNamesArrayEls >= MacroNamesArraySize Then
MacroNamesArraySize = MacroNamesArraySize + 16
ReDim Preserve MacroNamesArray(MacroNamesArraySize)
End If
Dim counter As Integer
For counter = 0 To MacroNamesArrayEls - 1
If MacroNamesArray(counter).MacroName > MacroName Then Exit For
Next counter

Dim InsertAt As Integer
InsertAt = counter

Do While counter < MacroNamesArrayEls
MacroNamesArray(counter + 1) = MacroNamesArray(counter)
counter = counter + 1
Loop
With MacroNamesArray(InsertAt)
.MacroName = MacroName
.MacroNameLen = Len(MacroName)
.Expanded = Expanded
End With
MacroNamesArrayEls = MacroNamesArrayEls + 1
End Sub

Sub ReadKeyCodeTable()
If Not MacroNamesRead Then
Dim MyDb As DAO.Database
Set MyDb = CurrentDb

Dim MyRst As DAO.Recordset
Set MyRst = MyDb.OpenRecordset(&quot;KeyboardMacros&quot;)
Do While Not MyRst.EOF
AddKeyCode MyRst(&quot;MacroName&quot;), MyRst(&quot;Expanded&quot;)
MyRst.MoveNext
Loop
MyRst.Close
Set MyRst = Nothing
MyDb.Close
Set MyDb = Nothing
MacroNamesRead = True
End If
End Sub

Function TextMatches(TextIn As String, MacroLen As Integer, Expanded As String) As Boolean
Dim RetVal As Boolean
RetVal = False
Dim counter As Integer
counter = 0
Do While counter < MacroNamesArrayEls And Not RetVal
With MacroNamesArray(counter)
If Right(TextIn, .MacroNameLen) = .MacroName Then
MacroLen = .MacroNameLen
Expanded = .Expanded
RetVal = True
End If
End With
counter = counter + 1
Loop
TextMatches = RetVal
End Function

Sub ProcessKeyDown(KeyCode As Integer, Shift As Integer)
Dim CurCtrl As Control
Set CurCtrl = Nothing
On Error Resume Next
Set CurCtrl = Screen.ActiveControl
If Not CurCtrl Is Nothing Then
ReadKeyCodeTable
' If (KeyCode = c_Trigger) Then ' enable this for the space character
' If Shift = 2 Then ' enable this for the control key
If Shift = 4 Then ' enable this for the alt key
Dim CurText As String
CurText = CurCtrl.Text

Dim SelPos As Integer
SelPos = CurCtrl.SelStart

Dim Expanded As String
Dim MacroLen As Integer
If TextMatches(CurText, MacroLen, Expanded) Then

Dim NewText As String
NewText = Left(CurText, SelPos - MacroLen) & Expanded & Right(CurText, Len(CurText) - SelPos)

CurCtrl.Value = NewText
CurCtrl.Text = NewText
CurCtrl.SelStart = Len(NewText)
CurCtrl.SelLength = 0
KeyCode = 0
End If
End If
End If
End Sub


 
BeeTee:

It works! Please accept my BIG star. Thank You.

Catty
 
Thanks Catty,

You're quite welcome; I like your keyboard macro concept, and I'll probably wind up using that code too.
 
Hi, Beetee:

Can I ask you a question from your presentation? I am new in Tek-Tips. I do not know how to chnage the color of the text in thread like you do. I did read the tips for tag from Tek-Tips, but still do not get it. Can you tell me how you can change your texts in thread to red color, green color or make some of them bold.

Ex:

Please make these
two lines become red.

Please make this line in green.

Please make these
two lines of text become bold.

Thank you, Beetee.

Catty
 
After typing in a reply, use the 'Preview Post' button. They have all the instructions of the formatting options.

It's difficult to illustrate formatting options in a post because they take effect.

 
Hi, Beetee:

Just a follow up of your code. I tried your new version code (The one you wrote in green) in my database. It did work, however, after multiple tests, I found some problem:

1. When you just invent first several keycodes, they work fine. Say i have the following keycodes and their expands:

Keycode Expand
1 1aaaaa
2 2bbbbb
3 3ccccc
4 4ddddd
abd abdomen

They work fine originally. But if I add new keycode &quot;13&quot; for '13thirteen' and &quot;abdP&quot; for 'abdominal pain'. I will find the original keycode 3 and abd were disabled , they no longer work. The more I tried, the more same incidences happened. (The new keycodes will disable several existing keycodes that original work). If I delete the new keycodes, then I may save some existing keycodes back, but some, I can not in spite I delete the new keycodes.

2. If I create a new keycode and its expand through a form and feed it to the keyboardmacros table and save it. I was unable to use it unless I have to close the whole program and reopen the program then the new keycode will start to work. Is there any way to set it not need to turn off the whole program to make the new ones work?

Do you find same problems? Can we fix it? Appreciated.

Catty
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top