02/10/2018, 11:31

[MS ACCESS] Chia sẽ source code gởi và nhận tin nhắn SMS sử dụng VBA

Xin chào các bạn, bài viết hôm nay mình sẽ chia sẽ cho các bạn source code gởi và nhận tin nhắn SMS sử dụng DCom 3G. Để gởi tin nhắn SMS, thì các bạn cần tìm hiểu qua tập lệnh AT Command. Trong bài viết này, source code gởi và nhận tin nhắn ...

Xin chào các bạn, bài viết hôm nay mình sẽ chia sẽ cho các bạn source code gởi và nhận tin nhắn SMS sử dụng DCom 3G.

Để gởi tin nhắn SMS, thì các bạn cần tìm hiểu qua tập lệnh AT Command.

Trong bài viết này, source code gởi và nhận tin nhắn mình viết bằng VBA. 

Nay mình share cho các bạn nào đang tìm hiểu có thể phát triển thêm.

Giao diện ứng dụng Form trên Microsoft Access:

gởi và nhận tin nhắn sms vba access

1. Đầu tiên, các bạn cần tạo module bên dưới, để kết nối access với cổng COM 

Option Compare Database
Option Explicit

Global ComNum As Long           'This variable is used to store the Port number the API understand
Global ReadBytes(255) As Byte   'In this variable are stored the bytes replied from the device

'************************************************************************
'** Start of declaration of variables and Constants that the APIs need **
'************************************************************************

Type COMSTAT
    fCtsHold As Long
    fDsrHold As Long
    fRlsdHold As Long
    fXoffHold As Long
    fXoffSent As Long
    fEof As Long
    fTxim As Long
    fReserved As Long
    cbInQue As Long
    cbOutQue As Long
End Type

Type COMMTIMEOUTS
    ReadIntervalTimeout As Long
    ReadTotalTimeoutMultiplier As Long
    ReadTotalTimeoutConstant As Long
    WriteTotalTimeoutMultiplier As Long
    WriteTotalTimeoutConstant As Long
End Type

Type DCB
    DCBlength As Long
    BaudRate As Long
    fBinary As Long
    fParity As Long
    fOutxCtsFlow As Long
    fOutxDsrFlow As Long
    fDtrControl As Long
    fDsrSensitivity As Long
    fTXContinueOnXoff As Long
    fOutX As Long
    fInX As Long
    fErrorChar As Long
    fNull As Long
    fRtsControl As Long
    fAbortOnError As Long
    fDummy2 As Long
    wReserved As Integer
    XonLim As Integer
    XoffLim As Integer
    ByteSize As Byte
    Parity As Byte
    StopBits As Byte
    XonChar As Byte
    XoffChar As Byte
    ErrorChar As Byte
    EofChar As Byte
    EvtChar As Byte
End Type

Type OVERLAPPED
    Internal As Long
    InternalHigh As Long
    offset As Long
    OffsetHigh As Long
    hEvent As Long
End Type
Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type

Public Const FILE_SHARE_READ = &H1
Public Const FILE_SHARE_WRITE = &H2
Public Const OPEN_EXISTING = 3
Public Const FILE_ATTRIBUTE_NORMAL = &H80

'**********************************************************************
'** End of declaration of variables and Constants that the APIs need **
'**********************************************************************


'*******************************************
'** Start of declaration of the APIs Used **
'*******************************************

Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Declare PtrSafe Function GetLastError Lib "kernel32" () As Long

Declare PtrSafe Function ReadFile Lib "kernel32" _
    (ByVal hFile As Long, _
    lpBuffer As Any, _
    ByVal nNumberOfBytesToRead As Long, _
    lpNumberOfBytesRead As Long, _
    lpOverlapped As Long) As Long
    
Declare PtrSafe Function WriteFile Lib "kernel32" _
    (ByVal hFile As Long, _
    lpBuffer As Any, _
    ByVal nNumberOfBytesToWrite As Long, _
    lpNumberOfBytesWritten As Long, _
    lpOverlapped As Long) As Long
    
Declare PtrSafe Function SetCommTimeouts Lib "kernel32" _
    (ByVal hFile As Long, _
    lpCommTimeouts As COMMTIMEOUTS) As Long
    
Declare PtrSafe Function GetCommTimeouts Lib "kernel32" _
    (ByVal hFile As Long, _
    lpCommTimeouts As COMMTIMEOUTS) As Long
    
Declare PtrSafe Function BuildCommDCB Lib "kernel32" _
    Alias "BuildCommDCBA" _
    (ByVal lpDef As String, _
    lpDCB As DCB) As Long
    
Declare PtrSafe Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, lpDCB As DCB) As Long

Declare PtrSafe Function CreateFile Lib "kernel32" _
Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long

Declare PtrSafe Function FlushFileBuffers Lib "kernel32" (ByVal hFile As Long) As Long

'I had to replicate the fowling API CreateFile because an error
'produced by the CheckPort function that I couldn't understand

Declare PtrSafe Function CreateFile1 Lib "kernel32" _
   Alias "CreateFileA" _
  (ByVal lpFileName As String, _
   ByVal dwDesiredAccess As Long, _
   ByVal dwShareMode As Long, _
   lpSecurityAttributes As SECURITY_ATTRIBUTES, _
   ByVal dwCreationDisposition As Long, _
   ByVal dwFlagsAndAttributes As Long, _
   ByVal hTemplateFile As Long) As Long
   
'*****************************************
'** End of declaration of the APIs Used **
'*****************************************

Function Close_Port()
    Close_Port = CloseHandle(ComNum)
End Function

Function FlushComm()
    FlushFileBuffers (ComNum)
End Function

Function Port_Initialization(ComNumber As String, Comsettings As String) As Boolean
On Error GoTo handelinitcom
    Dim ComSetup As DCB, Answer, STAT As COMSTAT, RetBytes As Long
    Dim retval As Long
    Dim CtimeOut As COMMTIMEOUTS, BarDCB As DCB
    
    ' Open the comport for read/write access (&HC0000000).
    ' Must specify existing file (3).
    ComNum = CreateFile(ComNumber, &HC0000000, 0, 0&, &H3, 0, 0)
    
    If ComNum = -1 Then
        MsgBox "Com Port " & ComNumber & " not available.", 48
        Port_Initialization = False
        Exit Function
    End If
    
    'Setup Time Outs for comport
    
    CtimeOut.ReadIntervalTimeout = 20
    CtimeOut.ReadTotalTimeoutConstant = 1
    CtimeOut.ReadTotalTimeoutMultiplier = 1
    CtimeOut.WriteTotalTimeoutConstant = 10
    CtimeOut.WriteTotalTimeoutMultiplier = 1
    retval = SetCommTimeouts(ComNum, CtimeOut)
    
    If retval = -1 Then
        retval = GetLastError()
        MsgBox "Unable to set timeouts for port " & ComNumber & " Error: " & retval
        retval = CloseHandle(ComNum)
        Port_Initialization = False
        Exit Function
    End If
    
    retval = BuildCommDCB(Comsettings, BarDCB)
    
    If retval = -1 Then
        retval = GetLastError()
        MsgBox "Unable to build Comm DCB " & Comsettings & " Error: " & retval
        retval = CloseHandle(ComNum)
        Port_Initialization = False
        Exit Function
    End If
    
    retval = SetCommState(ComNum, BarDCB)
    
    If retval = -1 Then
        retval = GetLastError()
        MsgBox "Unable to set Comm DCB " & Comsettings & " Error: " & retval
        retval = CloseHandle(ComNum)
        Port_Initialization = False
        Exit Function
    End If
    
    Port_Initialization = True
handelinitcom:
    Exit Function
End Function

Function Read_Port() As String
On Error GoTo handelpurecom
    Dim RetBytes As Long, I As Integer, ReadStr As String, retval As Long
    Dim CheckTotal As Integer, CheckDigitLC As Integer
    retval = ReadFile(ComNum, ReadBytes(0), 255, RetBytes, 0)
    ReadStr = ""
    
    If (RetBytes > 0) Then
        For I = 0 To RetBytes - 1
            ReadStr = ReadStr & Chr(ReadBytes(I))
        Next I
    Else
        FlushComm
    End If
    
    'Return the bytes replied from serial port
    Read_Port = ReadStr
    
handelpurecom:
    Exit Function
End Function

Function Write_Port(COMString As String) As Integer
On Error GoTo handelwritelpt
    Dim RetBytes As Long, LenVal As Long
    Dim retval As Long
    
    If Len(COMString) > 255 Then
        Write_Port Left$(COMString, 255)
        Write_Port Right$(COMString, Len(COMString) - 255)
        Exit Function
    End If
    
    For LenVal = 0 To Len(COMString) - 1
        ReadBytes(LenVal) = Asc(Mid$(COMString, LenVal + 1, 1))
    Next LenVal
    
    ReadBytes(LenVal) = 0
    retval = WriteFile(ComNum, ReadBytes(0), Len(COMString), RetBytes, ByVal CLng(0))
    FlushComm
    Write_Port = RetBytes
    
handelwritelpt:
    Exit Function
End Function


Function CheckPort(Port As Long) As Boolean
    Dim hPort As Long
   
  
    Dim sPort As String              'In this variable is stored the port's number
    Dim sa As SECURITY_ATTRIBUTES
  
    If Val(Port) > 0 Then
        sPort = "\.COM" & Port      'The port number should be something like "\.COM1"
     
        'The API that opens the port
        'If the CreateFile API succeeds then it close the port again
     
        hPort = CreateFile1(sPort, _
            0, _
            FILE_SHARE_READ Or FILE_SHARE_WRITE, _
            sa, _
            OPEN_EXISTING, _
            FILE_ATTRIBUTE_NORMAL, 0)
                         
        If hPort Then CloseHandle hPort
      
            CheckPort = hPort > 0
       
        Else
            CheckPort = False
    End If
   
End Function

2. Source code cho các chức năng gởi, nhận, gọi và check money 

Option Compare Database
Dim PortsFound As Integer
Dim PortConfig As String
Dim PortNumber As String
Public ONNER As Boolean
Public RECEIVE_MESSAGE As Boolean
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Function GetPorts(list As ListBox) As Long
    
    
    Dim Port As Long
    For Port = 1 To 100
                       
        If CheckPort(Port) Then
            list.AddItem "COM" & Port & "  available"
            PortsFound = PortsFound + 1
        End If
      
    Next
    NumOfPorts.Caption = PortsFound
End Function


Private Sub btn_ReadMessage_Click()
   'Write_Port ("AT+CMGL=" & Chr(34) & "REC UNREAD" & Chr(34))
   Write_Port ("ATD 0933913122;")
    Write_Port (Chr$(13))
  
End Sub

Private Sub btn_call_Click()
    Write_Port ("ATD " & txt_phone.Value & ";")
    Write_Port (Chr$(13))
End Sub

Private Sub btn_ReceiveMessage_Click()
    If btn_ReceiveMessage.Caption = "OPEN RECEIVE" Then
        RECEIVE_MESSAGE = True
        btn_ReceiveMessage.Caption = "CLOSE RECEIVE"
    Else
        RECEIVE_MESSAGE = False
        btn_ReceiveMessage.Caption = "OPEN RECEIVE"
    End If
    
End Sub

Private Sub CMD_checkmoney_Click()
 Write_Port ("AT+CUSD=1," & Chr(34) & "*101#" & Chr(34))
    Write_Port (Chr$(13))
End Sub

Private Sub CmdClose_Click()
    
    Call Close_Port
    ONNER = True
        TxtCommand.SetFocus
    TxtCommand.SetFocus

    CmdClose.Enabled = False
    CmdOpen.Enabled = True
    CmdGet.Enabled = True
    LstPorts.Enabled = True
    cboBaubRate.Enabled = True
    cboDataBits.Enabled = True
    cboParity.Enabled = True
    cboStopBits.Enabled = True

End Sub

Private Sub CmdGet_Click()
      
    On Error Resume Next
    For I = 1 To 20000
    LstPorts.RemoveItem (I)
    Next I
    LstPorts.Requery
    PortsFound = 0
    Call GetPorts(LstPorts)
    CmdOpen.Enabled = True
End Sub

Private Sub CmdOpen_Click()
    PortConfig = cboBaubRate.Value & _
        "," & cboParity.Value & _
        "," & cboDataBits.Value & _
        "," & cboStopBits.Value
    
    If Me.LstPorts = "" Then
        MsgBox "Please Select a Port first"
        Exit Sub
    End If
    
   
    PortNumber = "\." & Mid(Me.LstPorts, 1, (Len(Me.LstPorts) - 11))
    
    
    If Not Port_Initialization(PortNumber, PortConfig) Then
        MsgBox PortNumber & " Not available!"
        Exit Sub
    End If
    ONNER = True
    TxtCommand.SetFocus
    CmdClose.Enabled = True
    CmdOpen.Enabled = False
    CmdGet.Enabled = False
    LstPorts.Enabled = False
    cboBaubRate.Enabled = False
    cboDataBits.Enabled = False
    cboParity.Enabled = False
    cboStopBits.Enabled = False

End Sub

Private Sub CmdSend_Click()

    If Write_Port(Me.TxtCommand) <> Len(Me.TxtCommand) Then
        MsgBox "Error writing to comm's"
        Exit Sub
    End If
    
    Write_Port (Chr$(13))
                            
                           
    Me.TxtCommand = ""

End Sub

Private Sub Command3_Click()
    'LstPorts.Clear
    PortsFound = 0
    Call GetPorts(LstPorts)
    CmdOpen.Enabled = True

End Sub

Private Sub ReadMessage()
    Write_Port ("AT+CMGL=" & Chr(34) & "REC UNREAD" & Chr(34))
    Write_Port (Chr$(13))
    Dim Reply As String
    Reply = Read_Port()
    
    MsgBox Reply
End Sub

Private Sub Command31_Click()
    Write_Port ("AT+CMGF=1") 'chedotext, pdu
    Write_Port (Chr$(13))
    Write_Port ("AT+CMGS=" & Chr(34) & txt_phone.Value & Chr(34))
    Write_Port (Chr$(13))
    Sleep 1000
    Write_Port (txt_message.Value & Chr(26))
    Write_Port (Chr$(13))
    Dim Reply As String
    Reply = Read_Port()
    
    MsgBox Reply
    
End Sub

Private Sub Command32_Click()
txt_phone.Value = Null
txt_message.Value = Null
TxtReply.Value = Null
TxtCommand.Value = Null
End Sub

Private Sub Form_Open(Cancel As Integer)
ONNER = False
RECEIVE_MESSAGE = False
Page34.SetFocus
Call CmdClose_Click
    cboBaubRate.Value = "9600"
    cboDataBits.Value = "8"
    cboParity.Value = "n"
    cboStopBits.Value = "1"

End Sub

Private Sub Form_Timer()
           
    If ONNER = False Then Exit Sub
    If RECEIVE_MESSAGE = True Then
      Write_Port ("AT+CMGL=" & Chr(34) & "REC UNREAD" & Chr(34))
      Write_Port (Chr$(13))
      Dim str_receive_message As String
        str_receive_message = Read_Port()
        If str_receive_message = "" Then Exit Sub
        Dim posOf_A As Integer
    
       posOf_A = InStr(1, str_receive_message, "UNREAD", vbTextCompare)
    If posOf_A > 0 Then
     Debug.Print str_receive_message
        txt_receiveMessage.Value = str_receive_message & txt_receiveMessage.Value
        FlushComm
    End If
        
        
       
     
       
    End If
     Dim Reply As String
        Reply = Read_Port()
        If Reply = "" Then Exit Sub
        Debug.Print Reply
        TxtReply.Value = TxtReply.Value & Reply
        FlushComm
    
   

End Sub

Private Sub Form_Unload(Cancel As Integer)
Call Close_Port
End Sub

HAPPY CODING heart

DOWNLOAD SOURCE

Tags: at commandsend smsreceive sms
0