# text to speech with Access



## Chris_E (Feb 16, 2006)

Hello!

I have an Access 2003 database. I have a specific text field that I would like to have read out to the user when a command button is pressed.

I have seen notes on MS site about "Microsoft Agent Part 1: Animating Office Applications with Microsoft Agent" but it assumes too much of this poor beginner!

For info, see

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/ODC_MSAgent-I.asp

This code apparently gives me a pop up Merlin wizard (like you might get in Office 'Help') and it can do stuff like read text etc.

I just can't get it to work. I can get its hat in the toolbar (ok) but when I try anything after, even using the sample code from MS, it errors or does nothing at all.

So, 64,000 dollar question - has anyone experience of text to speech in Access and if so, how did you do it?

Best wishes all!

Chris


----------



## cristobal03 (Aug 5, 2005)

I have not used Microsoft Agent. ActiveX controls are tricky, and this sounds annoyingly similar to the Office Assistant. However, we can probably make it work. What code have you developed so far?

chris.


----------



## Chris_E (Feb 16, 2006)

Well Chris, you are bang on in your suspicion of this being similar to Office Assistant. In fact, it is the same tool, but here you can get the "character" to do what you want it to do.

The link in the previous posting tells me to create a Class Module and two standard modules. To help, I have essentially copied the text from that web page and edited it as if I were describing what I had to do.... The web site talks about using the code in PowerPoint, but I just changed it to "Access"

Quote:

Before I could start using the animation features in Agent, I needed to add a reference to the Microsoft Agent Control 2.0 (click References on the Tools menu).

>> Done this.

I then had to create one class module (for the database) and two standard code modules (one for the Agent Control and one for the main macro).

I had to name the class module, so I called it "clsAccess".

At the top of the class module, I had to declare a variable, I called it appAccess. It has to use the "WithEvents" keyword.

>> I have no idea what this means but I tried this as the content of the Class Module AppAccess:


> ---------------------------------------------
> Option Compare Database
> Dim WithEvents appAccess As Agent
> ---------------------------------------------


The first standard code module I had to create, I named AgtMerlin. Inside the code module I had to declare two global variables. I declared the variable g_ctlAgent as an Agent variable type,

Next, I had to declare the variable g_charMerlin as an IAgentCtlCharacter variable type.

The code for this is in a standard module called agtMerlin

Looks like this:


> Option Compare Database
> 
> Dim g_ctlAgent As New Agent
> Dim g_charMerlin As IAgentCtlCharacter


Then I needed to create the connection between the Agent Control and my VBA code and use the Load method of the IAgentCtlCharacter object to specify the character I want to use.

The following example should load the Agent and assign the Merlin character to my g_charMerlin variable. I should then use this object variable throughout the rest of my code to save myself a lot of typing. (apparently)

The code for this last section is again inside the agtMerlin module...



> Sub LoadMerlin()
> 
> 'Set the object variable for the Microsoft Agent ActiveX control.
> Set g_ctlAgent = New Agent
> ...


So, I did what they said and created, in all 3 modules.

I then created a button and assigned code to it on click:



> Private Sub Test_Merlin_Click()
> 
> Call LoadMerlin
> 
> End Sub


But, on_Click, this throws the error:



> Run-Time Error 448
> Named Argument Not Found


On pressing "Debug",

The following line is highlighted in my code:



> Set g_charMerlin = g_ctlAgent.Characters(CharacterID:="merlin")


which sits in the agtMerlin module.

I am now lost.

If you look at the weblink, you'll see you can get the merlin to speak. I want pass text from a field "lets call it "[MessageString]" from the form hosting the button that calls the merlin.

Then I want the Merlin to go away again....

I'm probably asking too much and if so, I apologise, but your support is gratefully accepted!!

All the best

Chris


----------



## cristobal03 (Aug 5, 2005)

I'm in a hurry so just a quick note.

If you use the keyword *Call* to call a subroutine, you *must* include the routine's parentheses, even if no arguments are passed. The statement in that *Test_Merlin_Click* event handler should read

*Call LoadMerlin()*​Or, you can drop the *Call* and leave off the parentheses.

chris.


----------



## Chris_E (Feb 16, 2006)

Hi Chris

If I enter :

Call LoadMerlin() in the VBA editor, it automatically removes the ()!

But, either way, it still errors the same way.

'preciate your support Chris

Chris


----------



## cristobal03 (Aug 5, 2005)

Okay, sorry I was rushed last night. The parentheses are only required if you use *Call* in conjunction with a routine that takes arguments, so the parentheses weren't necessary after all.

The piece that's failing is the *CharacterID*. VBA procedures can take arguments in one of two ways: 1) in the order they appear in the procedure's declaration, or 2) in any order, delineated by argument name. If you use unnamed arguments--or arguments ordered by the procedure's declaration--you must include a marker for every argument up to the last one you provide. Conversely, you need only supply the arguments you use if you opt for named arguments. That may not make much sense. Let's take an example using the *MsgBox* function.

*MsgBox(prompt[, buttons] [, title] [, helpfile, context])*​In the above declaration, arguments in brackets are optional. Notice the *prompt* argument is required. If we wanted a message box with a prompt and a title, using the default buttons argument value, we would call the routine in one of several ways (depending on what we want to do with the return value):

*Call MsgBox("This is a prompt.", , "This is a title.")
MsgBox "This is a prompt.", , "This is a title."
ReturnValue = MsgBox("This is a prompt.", , "This is a title.")*​Notice the extra comma between the prompt argument and the optional title argument. This is to mark the space for the optional buttons argument that falls _before_ the title argument in the function's declaration. If we omitted the comma, we would see a compile error.

Using named arguments, on the other hand, allows us to only include those arguments in which we're interested, in any order. Like so:

*Call MsgBox(Title:="This is a title.", Prompt:="This is a prompt.")
MsgBox Title:="This is a title.", Prompt:="This is a prompt."
ReturnValue = MsgBox(Title:="This is a title.", Prompt:="This is a prompt.")*​By using the argument's name, we can exclude the buttons argument and rearrange the order of arguments.

That was all some FYI.

The trouble you're encountering is that the compiler doesn't find the argument *CharacterID* in the list of arguments in method *Characters*'s declaration. Having never used Agent, I don't know if I can suggest a solution. If you type that line,

*Set g_charMerlin = g_ctlAgent.Characters*​and type a parenthesis, the VBA Editor should display a ControlTip listing the arguments for the method. You could type commas until you hit the *CharacterID* argument (which will probably have a different name, like *CharacterName* or something) then type *"merlin"* and a closing parenthesis. That might work. Or you can just use the correct name in your named argument, if you discover that the argument list doesn't include *CharacterID*.

Does that make any sense?

chris.


----------



## Chris_E (Feb 16, 2006)

Hi Chris

Yes, it makes good sense.

Trouble is that even adding a parenthesis, VBA gives me no options!

Not a big deal this one though - I was just thinking it would be a nice to have.

Seems there is a load of code about for using Merlin in straight VB, but nothing so far on VBA or Access in particular. Is there a difference?

Cheers!

Chris


----------

