Microsoft Access VBA Technical Information

Product Information
Supported Versions
Sample Programs
Project Setup

Technical Notes

Supported Version

ExceleTel TeleTools v3.7 works with virtually all Windows development environments that support ActiveX technology.  This includes Microsoft Access and Visual Basic for Applications (VBA).

Sample Programs

Click here for a complete list available sample programs provided by ExceleTel.

Here is a sample programs for VBA and Microsoft Access.  It was written using Access 2000, but will work in any version of Access :


Project Setup

The steps to create all sample projects within Microsoft Access are as follows:

  1. Run MS Access.

  2. From the file menu, select "new" and then select "database" from the "general" tab. Press OK, give your database a name and select "create".

  3. From the "tools" menu, select "activex controls".  You should see the TeleTools components in your list of registered components all starting with 'et' as in etLine, etPhone, etPlay and etRecord.

  4.   Click in your form window and make sure you can see your toolbox window.  Click on the "more controls icon"  and find your component and click on it.  Move your mouse to your form and click again.  You have now dropped a TeleTools component on your form.

  5.   In the properties window for the new etLine control, click on the "All" tab and then click once on the "AboutLoadSerialNumber" property to load your serial number into the component.

  6.   Right click on your form and select "Build Event".  If this is the first time editing your form, you will get another box where you must select "code editor".  Now you can program your application.

  7. You might want to add the etTTConst.bas file. It contains definitions for interpreting information from telephony devices. Select “Import File" from the File menu. Navigate to the Program Files\ExceleTel\TeleTools\3.x\bin\ActiveX directory and select the file, then press “Ok.”

 When you drop a TeleTools component on the form, you will see one or more of  the following icons:





Be sure to review the information in the sections Creating Controls Design-Time, Creating Controls at Run-Time and Why Serial Numbers Are Important. This will explain how to use the AboutLoadSerialNumber properties to set the AboutSerialNumber properties.

Before using a TeleTools control it must be enabled. This is done by setting the Enabled or EnableControl property to True.

NOTE: If you just drop your components on a form, you will not have your Intellisense auto-completion help available, nor will certain events be recognized property by Access.  Please read the technical notes below.

Technical Notes - Important Information

Try using VB or another Development Environment with your Access database

Access is a database language, as such it was not designed to be as robust for application development as a something like Visual Basic, Delphi, C++ or the dotNet languages.  If at all possible, we recommend people use Access to create and edit their database .mdb files and then use a development environment to work with the database in the finished application.  Here is an example of how simple it is to use VB to work with an Access database:

' Make sure you have a reference set to the DAO (Data Access Objects) 
' library.

' Define the database and recordset variables
Dim db As Database
Dim rs As Recordset

' Open the database 
Set db = OpenDatabase(App.Path & "\" & "names.mdb")

' Add some records to the database
db.Execute " INSERT INTO people" & "(fName,lName, Address) VALUES " _
       & "('Fred', 'Decker', '4909 Waters Edge Drive');"
db.Execute " INSERT INTO people" & "(fName,lName, Address) VALUES " _
       & "('Pete', 'Berry', 'the planet Jupiter');"

' Open the recordset object
Set rs = db.OpenRecordset("SELECT * FROM people ORDER BY fName")
rs.MoveFirst  'find the first record
FirstPersonsName = rs("fName") 'get the name

db.close 'close the database

Getting Around the Access ActiveX Wrapper

  • gets your Intellisense auto-completion help back

  • fixes lost events or events not firing as expected

  • makes sure properties don't disappear when set in the properties dialog at design time

If you don't have another development environment, or simply want to use only Access for your application you should be aware of a few of it's limitations.  One is that Microsoft implemented a very poor ActiveX wrapper in Access.  All external ActiveX controls, not just TeleTools controls, will automatically get wrapped up and insulated by Access.  This means that unless you follow the suggestions here, you will lose your "Intellisense" help.  Intellisense automatically completes your code lines and shows the methods and properties of an object when you type it's name and press the period key.  In addition, without inserting a delay using certain methods, Access may fail to fire events as it should.  For example, you may try to use the etLine.CallAnswer method in the OnRing event handler to answer the phone on a certain ring.  The OnConnected event fires, but is lost inside the Access wrapper because it is too slow to catch quick-firing events. 

You can get around these Access issues by creating all of your TeleTools controls (and other ActiveX controls) dynamically at runtime from inside your program instead of dropping them visually on your forms.  It's easy, here's how to do it:

In the General section of you code, place the line:

Public WithEvents etLine1 As etTT37.etLine   

In the the code section put:

Set etLine1 = New etTT37.etLine
etLine1.AboutSerialNumber = "YOUR_SERIAL_NUMBER"
etLine1.Enabled = True

You can do this for as many components as you need.  This effectively bypasses the faulty Microsoft Access ActiveX wrapper, returning full functionality back to you.  Please see the etQuickDial sample program and our information about creating controls dynamically at runtime in the help file under "Programming with TeleTools | Advanced Concepts".

Another Way

If you have a reason for putting your components on the form at design time, you can get your Intellisense back by creating your own object based on an object you dropped on the form and using that alias when referring to that object in your code.  Here are the steps:

  1. Drop an etLine component on a form and name it etLine0 (you could use any component also)

  2. Put the line "Public etLine1 As etTT37.etLine" in the General section

  3. Alias the etLine0 on your form with a new name with "etLine1 = etLine0.Object"

Now all of the event handlers must be created by clicking on the etLine0 events, but everywhere else in your code you can reference etLine1 which now points to etLine0, but is now stripped of the Access ActiveX wrapper.  We have found that if you use this second method instead of dynamically creating your controls at runtime, you may also have to use the Access form timer to introduce a tiny delay into fast firing events.  For example if you are trying to answer the phone on the 3rd ring with etLine.CallAnswer in the OnRing event handler or trying to use etLine.CallHangup in the OnDisconnected event handler to hangup the phone when the remote party has disconnected, you may have to put that code in the Form Timer event instead.

Another strange Access feature is it's support for only one timer and tying that to your form.  In order to keep you from having to find a separate timer component, here is a trick to use the default form timer to delay calling certain methods inside an event handler by 100 milliseconds.  This code will use the form timer to answer and hangup the phone instead of placing that code as you normally would inside another event handler. You DO NOT need this code if you are creating the TeleTools components dynamically at runtime as shown in option 1 above.

    ' ******************************************************************************
    ' Answer the call on the 3rd ring and use a state machine to fire the
    ' Access form timer to insert a small delay before calling a method
    ' like etLine.CallAnswer
    ' ******************************************************************************
    Private Sub etLine1_OnRing(ByVal Count As Long, ByVal RingMode As Long)
        WriteLog ("OnRing: Count = [" & Str(Count) & "]")
        if count >= 3 then
            sTimerStatus = "Answer"
            Form.TimerInterval = 100 'have to use a timer again because of the Access bug
        End If
    End Sub

    Private Sub cmdHangup_Click()
    ' ***************************************************************************
    ' Hangup - make sure any waves are stopped and then hangup the call
    ' would like to just call the etLine.CallHanup method here, but
    ' Access has a bug that prevents certain events from firing without
    ' the timer workaround unless you use the first option on this page.
    ' ***************************************************************************
        If etLine1.CallActive Then 'check to see if we have an active call first
            WriteLog ("Hangup")
            sTimerStatus = "Hangup"
            Form.TimerInterval = 100 'have to use a timer again because of the Access bug
            WriteLog ("No Call to hangup!")
        End If
    End Sub

    Private Sub Form_Timer()
    ' ******************************************************************************
    ' Form_Timer - Access provides only one timer and makes it part of the form,
    ' use it to get around the Access bug where some events don't fire
    ' if they are called from another event.
    ' ******************************************************************************
        On Error GoTo err_Form_Timer
        Form.TimerInterval = 0
        If sTimerStatus = "Answer" Then 'answer the call
            etLine1.CallOwner = True
            If Not etLine1.CallAnswer Then
                WriteLog("Error Answering the call: " & etLine1.ErrorText)
            End If
        End If
        If sTimerStatus = "Hangup" Then 'hangup the call
            etLine1.CallOwner = True
            If Not etLine1.CallHangup Then
                WriteLog ("Error Hanging Up: " & etLine1.ErrorText)
            End If
        End If
        Exit Sub

        MsgBox ("Error Timer" & Err.Description)
    End Sub

Other Things to Watch in Access

Certain functions may or may not work without the VBA preface to the method.  For example, this sample program uses "Chr(Digit)"  to display the DTMF digit returned in the OnDigitReceived event.  On some systems you have to write this as "VBA.Chr(Digit)"

Global constants from an include file may work on the development machine but not on a deployed machine.  Make sure to either include the constants in project or to import the etTTConts.bas constants file if you are going to use contants