Background
Adding an AutoDialer button with the Command Button Wizard creates an embedded macro that runs Windows’ built-in Dialer.exe, a Telephone API (TAPI) application that reads configuration data and dialing rules from Control Panel’s Phone and Modem tool. By default, the macro transfers the phone number from the preceding control in the tab order to a text box. Clicking the button opens a dialog that lets the user confirm (and, optionally, edit the number), and then click OK to dial or Cancel to abort it:
Clicking OK also activates an AutoDialer icon in the taskbar:
Clicking the taskbar icon opens the following two dialogs anchored ot the top left of the screen:
Most developers and their clients will consider these two dialogs superfluous and confusing to end users. What’s worse, there appears to be no readily apparent method for preventing the Phone Dialer dialog from appearing when the user just wants to hang up. Users expect to “hang up” simply by placing the handset on hook.
Extensive searching with Bing and Google disclosed no free, turnkey code for creating a simple autodialer by executing the Hayes ,,ATDT+1###-###-####;H command to dial the number and hang up.
Creating the No-Frills Dialer with David M. Hitchner's modCOMM Library
Access 2010’s VBA 7 doesn’t have a feature that emulates VB 6’s MSComm control, but David M. Hitchner has thoughtfully posted a VB module containing a collection of routines to perform serial port I/O without using the Microsoft Comm Control component here. His CommIO.zip file contains a CommIO.bas and SampleCode.txt files. Rename CommIO.bas to CommIO.txt, open it in Notepad and paste it into a new module.
Important: Be sure to add PtrSafe to CommIO’s Declare statement if you’re running 64-bit Access or either 32-bit or 64-bit Access under Windows 8 or Server 2012, as in:
Declare PtrSafe Function GetCommModemStatus Lib "kernel32" _
(ByVal hFile As Long, lpModemStat As Long) As Long
Here’s my code for a procedure that accepts arguments for the form name, control name of the text box with the phone number, and name of the dialed party, opens this message box:
and sends the COM port number (2) and ATDT command text to a subprocedure based on David’s SampleCode.txt example:
Public Sub AutoDial(strForm As String, strControl As String, strParty As String)
' Dial with Hayes-compatible command set
On Error GoTo ErrorHandler
Dim Phone As Control
Dim Party As Control
Dim strNumber As String
Dim strDialCmd As String
Dim strMsg As String
Dim varRetVal As Variant
Set Phone = Forms(strForm).Controls(strControl)
Set Party = Forms(strForm).Controls(strParty)
varRetVal = Application.SysCmd(acSysCmdClearStatus)
If Len(Phone.Value) = 12 Then
If Left(Phone.Value, 3) = "510" Then
' Local call
strNumber = Mid(Phone.Value, 5)
Else
' 1-AAA-PPP-NNN
strNumber = "1-" & Phone.Value
End If
strMsg = "Click OK to dial " & strNumber
If Len(Party.Value) > 0 Then
strMsg = strMsg & " for " & Party.Value
End If
strMsg = strMsg & " and pick up handset within 10 seconds."
strMsg = strMsg & vbCrLf & vbCrLf & "Or click Cancel to abort the call."
strDialCmd = ",,ATDT" & strNumber & ";H"
varRetVal = Application.SysCmd(acSysCmdSetStatus, "Dialing " & strDialCmd)
If MsgBox(strMsg, vbOKCancel + vbQuestion, "Pacific Park Plaza Autodialer") = vbOK Then
ModemDialer 2, strDialCmd & vbCrLf
End If
Else
MsgBox "Phone number not valid.", vbOKOnly + vbExclamation, "Autodialer Error"
End If
Set Phone = NothingExitPoint:
Exit Sub
ErrorHandler:
MsgBox Err.Description, vbExclamation, "Unexpected Autodialer Error"
Resume ExitPoint
End Sub
You must specify the modem’s COM port to correspond with Control Panel’s Phone and Modem tool in the first argument of the above ModemDialer 2, strDialCmd & vbCrLf instruction:
Here’s the modified procedure for invoking CommIO functions:
Sub ModemDialer(intPortID As Integer, strData As String)
' Truncated version of David M. Hitchner's SampleCode.txt from modCOMM.zip
' Requires installation of David M. Hitchner's modCOMM library downloaded from
' http://www.thescarms.com/vbasic/CommIO.aspx
On Error GoTo ErrorHandler
' intPortID = 1, 2, 3, 4 for COM1 - COM4
' strData = Phone number with area code removed for local numbers and
' +1 prepended for out-of-area numbers
Dim lngStatus As Long
Dim lngSize As Long
Dim strError As String
Dim varRetVal As Variant' Initialize Communications
lngStatus = CommOpen(intPortID, "COM" & CStr(intPortID), _
"baud=9600 parity=N data=8 stop=1")
DoEvents
' Write data to serial port.
lngSize = Len(strData)
lngStatus = CommWrite(intPortID, strData)
If lngStatus = lngSize Then
varRetVal = Application.SysCmd(acSysCmdSetStatus, strData)
Else
varRetVal = Application.SysCmd(acSysCmdSetStatus, "Error: " & strData)
End If
DoEvents
' 10 seconds to pick up phone; see procedure below
Pause 10
varRetVal = Application.SysCmd(acSysCmdClearStatus)
Call CommClose(intPortID)
ExitPoint:
Exit SubErrorHandler:
MsgBox Err.Description, vbInformation + vbOKOnly, "Error Opening COM Port"
Resume ExitPoint
End Sub
This is wonderful! Never knew that TAPI could be integrated with Access programming, as always relied on a mean VB program to take care of auto dialing. But with access, especially in case of database driven applications, availability of TAPI will make the application a lot more fast.
ReplyDelete