Introduction
Basic Application.Speech.Speak Example
Arguments
Examining SpeakAsync
Examining Purge
Function to Say Results
Change Voice and Speed
List Available Voices
Final Thoughts

Introduction

Believe it or not, you can make Excel talk to you with the Application.Speech.Speak method of VBA. By default, there’s not a way to change the voice or speed, but you can add a reference to the sapi.dll Microsoft Speech Object Library to control all that.

I’ll show you how!


Example - Application.Speech.Speak

Sub TalkToMe()
Application.Speech.Speak "Excel is talking to me"
End Sub

Make powerful macros with our free VBA Developer Kit

This is actually pretty neat. If you have trouble understanding or remembering it, our free VBA Developer Kit can help. It’s loaded with VBA shortcuts to help you make your own macros like this one - we’ll send a copy, along with our Big Book of Excel VBA Macros, to your email address below.

I'll take a free VBA Developer Kit

Application.Speech.Speak Arguments

The Application.Speech.Speak function gets Microsoft Excel to play whatever string you pass it. By default, it waits until the voice finishes talking before it continues with your macro, but you can change that!

Fortunately, Application.Speech.Speak accepts many arguments. Four arguments as a matter of fact. The first one, we know, is the string you want your computer to say. This is a required argument.

The other 3 arguments are optional and are described below:

  1. SpeakAsync - By setting this to True, the VBA compiler will continue to march through your code while the voice is speaking. This is usually a good idea because it speeds up your code execution. The default is False. In other words, by default your macro will pause until the voice finishes speaking.
  2. SpeakXML - Setting this to True will cause your string to be interpreted as XML and any XML tags you have will not be spoken. The default is False, since most of the time you’re not feeding the script any XML. Keeping it False is usually good.
  3. Purge - If you set this to True, your macro will stop saying anything it was in the process of saying and start saying your new string, instead. In other words, it “purges” the queued up text in favor of your new text. The default is False.

Let’s go through a few examples to see how the arguments change the behavior of the speech method:


Examining SpeakASync

First, we’ll add a MsgBox at the end of our original example macro:

Sub TalkToMe2()
Application.Speech.Speak "Excel is talking to me"
MsgBox "test"
End Sub

When you run this macro, you’ll notice the MsgBox doesn’t appear until AFTER the voice finishes saying “Excel is talking to me.” What happens when we set SpeakAsync to True?

Sub TalkToMe3()
Application.Speech.Speak "Excel is talking to me", SpeakAsync:=True
MsgBox "test"
End Sub

Notice the MsgBox immediately pops up! Your macro continues to run while your computer is talking. This is a great feature, and I’m glad it was included in speak property.

Examining Purge

To test the purge property, we’ll add a 1 second delay after our first command starts talking. We’ll set the SpeakAsync property to True so our macro will continue running.

Sub TalkToMe4()
Application.Speech.Speak "Excel is talking to me", SpeakAsync:=True
Application.Wait (Now + TimeValue("00:00:01"))
Application.Speech.Speak "Hello, friend!", SpeakAsync:=True, Purge:=True
End Sub

When you play the code, the voice will stop saying the first string mid-sentence and will start saying “Hello, friend!” instead. It clears everything it had planned to say and says your new expression.

Play around and set the Purge property to false - you’ll see that it completely waits to finish saying your first string before starting your second one.


Function to Say Results

Arguably one of the most helpful ways you can get Excel to talk to you is by forcing it to say the value of a cell or multiple cells buried deep on another worksheet.

Another useful application is when you’re performing data entry. Let’s say you’re looking at data on a PDF, sticky note or website. You need to enter some of these values into Excel. Normally, you would look at your source of data, type the data, then look at your spreadsheet to make sure you typed the data correctly. By making Excel repeat the contents of your cells as you enter them, you can confirm whether or not you’ve entered your data correctly.

One way I like to do this is with a custom function (a UDF) designed to let Excel speak the contents of whatever cell I give it.

Function SayIt(cell1 As Variant, Optional bAsync As Boolean, Optional bPurge As Boolean)
Application.Speech.Speak (cell1), bAsync, , bPurge
SayIt = "Speaking"
End Function

Let’s say I’m playing around with my spreadsheet and I want to know the value in cell A1 each time it changes, but I don’t want to stop what I’m doing to look at that cell each time. I would enter the formula =SayIt(A1,TRUE) into any cell and now anytime cell A1 changes, my computer will tell me the new value! It won’t waste my time telling me when other cells change - just when the contents of cell A1 changes.

Application.Speech.Speak VBA

SayIt accepts 3 arguments, but the last 2 are optional. The two optional arguments control the SpeakAsync and Purge arguments. They’ll default to False, just like the Application.Speech.Speak method.


Change Voice and Speed

Things get a little more complicated when you want to change the voice of your narrator or the speed at which the narrator talks. To change the voice or speed, you have to add a reference to the sapi.dll Microsoft Speech Object Library.

To do this from your VBA editor, go to Tools > References and scroll down until you see “Microsoft Speech Object Library.” I have two references with that title. You want to make sure you check the box next to the one that says sapi.dll in the Location field. If you don’t have this library, you’ll need to download it.

Microsoft Speech Object Library sapi.dll

Once you do that, paste the following macro into a module:

Sub ChangeVoiceDemo()
SuperTalk "Excel is talking to me.", "BOY", 2, 100
SuperTalk "Excel is talking to me.", "GIRL", 2, 100
SuperTalk "Excel is talking to me.", "BOY", -10, 30
SuperTalk "Excel is talking to me.", "GIRL", 10, 70
End Sub

Private Sub SuperTalk(Words As String, Person As String, Rate As Long, Volume As Long)
Dim Voc As SpeechLib.SpVoice
Set Voc = New SpVoice

With Voc
    If UCase(Person) = "BOY" Then
        Set .Voice = .GetVoices.Item(0)
    ElseIf UCase(Person) = "GIRL" Then
        Set .Voice = .GetVoices.Item(1)
    End If
    .Rate = Rate
    .Volume = Volume
    .Speak Words
End With
End Sub

The VBA macro SuperTalk lets you change the voice, speed and volume of your voice. The macro ChangeVoiceDemo demonstrates the different voices, different talking speeds and different volumes on my machine. It calls the VBA macro SuperTalk 4 times and passes the subroutine 4 variables.

  1. Words - the string you want your macro to say
  2. Person - the voice you want your computer to use. In my example, it can be “BOY” or “GIRL.” See the List Available Voices section for more information about available voices.
  3. Rate - whole number corresponding to how fast you want your voice to talk. It can range from -10 (very slow) to +10 (very fast).
  4. Volume - whole number corresponding to how loud you want your voice to talk. It can range from 0 (muted) to 100 (max volume).

List Available Voices

Note: On my computer, I have 2 available voices: one male and one female. I hardwired the “BOY” variable to be the first voice and the “GIRL” variable to be the second voice. Your order and available voices may be different!

You may have more or less so feel free to modify your macro. The following macro prints the number of available voices, provides a sample of each voice, and writes a description of each voice to your Immediate Window:

Sub AvailableVoices()
Dim i As Long
Dim voc As SpeechLib.SpVoice
Set voc = New SpVoice
Debug.Print voc.GetVoices.Count & " available voices:"
For i = 0 To voc.GetVoices.Count - 1
    Set voc.Voice = voc.GetVoices.Item(i)
    Debug.Print "   " & i & " - " & voc.Voice.GetDescription
    voc.Speak "test audio"
Next i
End Sub

When I run this, I get the following list of available voices:

2 available voices:
   0 - Microsoft David Desktop - English (United States)
   1 - Microsoft Zira Desktop - English (United States)

Your list may vary.


Final Thoughts

A lot of people already know about using Application.Speech.Speak, but few people are aware you can adjust the voice, speed and volume of the narrator by using VBA. This skill is great for self checking data entry and even better for good, ole-fashioned messing with people:-p

It’s also good if you have a macro that takes a really long time to run. You can go about your day doing other things and get your computer to tell you with an audio cue when your macro is complete.

For more macros like this, join our VBA Insiders using the form below.