Domanda

Qual è il modo migliore per accedere a una porta seriale da VBA?

Ho bisogno che alcuni dei nostri rappresentanti di vendita possano inviare una semplice stringa sulla porta seriale da un pulsante di azione in PowerPoint. Non uso comunemente VBA, soprattutto per qualcosa del genere. Normalmente lo trasformerei in un'applicazione di qualche tipo, ma in realtà non credo che l'idea sia così male. Sarà uno strumento utile per loro per dimostrare questo dispositivo con un proiettore e parlare con altri vendite e persone non tecniche. Inoltre, questo ragazzo di vendita non avrà problemi a apportare piccole modifiche alla presentazione VBA o PowerPoint, ma non farebbe altrettanto bene con l'applicazione .NET.

So che potremmo farlo attraverso un file batch eseguito dalla presentazione dell'azione, ma questo non mi rende molto felice. Immagino che probabilmente potremmo accedere a un oggetto COM e correre da lì, ma di nuovo non sono reale sulle ultime e più grandi librerie da usare in VBA, e sarebbe anche bello ottenere un piccolo primer veloce su come aprire facilmente, Invia e chiudi la connessione.

Poiché questo dovrà essere eseguito sui computer di più persone, sarebbe bello se fosse facilmente trasportabile per altre macchine. Dovrei essere in grado di dire che deve essere funzionato in Office 2007 e Windows XP. La compatibilità con qualsiasi altra cosa sarebbe un bel bonus però.

Come dovrei gestire questo? Qualche buon consiglio o trucchi? Consigli sulla biblioteca?

È stato utile?

Soluzione

L'API Win32 gestisce la porta seriale come file. È possibile accedere direttamente alle porte seriali chiamando queste funzioni API all'interno di VBA. Ho dovuto farlo per una vecchia applicazione .NET ma VBA non è diverso.

Invece di averlo fuori di testa su questo sito, ecco un riferimento a cui ho appeso nel corso degli anni. Come eseguire comunicazioni portuali seriali in VBA

Altri suggerimenti

Sub Stinky()
Dim COM_Byte As Byte
Dim Received_Lines As Long
Dim Input_Buffer As String
Dim Output_Buffer As String
Dim Chars2Send As Long
Dim CharsRemaining As Long
Dim lfsr As Long
    Open "COM7:9600,N,8,1" For Random As #1 Len = 1
    Input_Buffer = ""
    CharsRemaining = 0
    Do
    Get #1, , COM_Byte
    If COM_Byte Then
        If COM_Byte = 13 Then           ' look for CR line termination
            Debug.Print Input_Buffer, Now   ' print it
            Input_Buffer = ""               ' and clear input buffer
        '   generate some output (9 characters)
            lfsr = &H3FFFFFFF - 2 ^ (Received_Lines And 15)
            Output_Buffer = "?@@@@@@@@"
            Chars2Send = 9
            CharsRemaining = 9
            For j = 0 To 2
                Mid(Output_Buffer, 2 + j, 1) = Chr(Asc(Mid(Output_Buffer, 2 + j, 1)) + (31 And Int(lfsr / 32 ^ (2 - j))))
            Next j
            Debug.Print Output_Buffer
        '   show what I generated
            Received_Lines = Received_Lines + 1 ' keep track of received line count
        Else
            Input_Buffer = Input_Buffer & Chr(COM_Byte) ' assemble output buffer
        '   process any characters to send
            If CharsRemaining Then
                CharsRemaining = CharsRemaining - 1
                COM_Byte = Asc(Mid(Output_Buffer, Chars2Send - CharsRemaining, 1))
                Put #1, , COM_Byte
            End If
        End If
    End If
    DoEvents
    Loop
    Close
End Sub

Questo funziona per me. Non sono sicuro se l'apertura imposti effettivamente il tasso di baud, dato che ho usato per la prima volta Teraterm. La mia porta COM è una connessione USB a un kit di prototipazione BASYS3. Sta perdendo personaggi a 9600, record di 36 caratteri che terminano con Cr. Posso inviare casualmente comandi di 9 caratteri. Nel codice sopra, genero queste stringhe di comando ogni volta che ho ricevuto una nuova riga. Il modo in cui ho scelto quale personaggio inviare è un po 'goffo: forse un modo migliore è avere un puntatore del personaggio e un numero di personaggi, e quando quelli vanno uguali per impostare entrambi a zero.

Ecco un breve modulo del codice VBA che può inviare e ricevere messaggi su una porta seriale PC. Questo non è molto elegante, ma è semplice e dovrebbe funzionare su versioni moderne di Excel e Windows.

Sei lasciato da solo per espandere la funzionalità e archiviare o analizzare i messaggi. Questo mostra solo le cose di basso livello per affrontare la porta seriale.

Le prime 5 righe dichiarano la funzione della libreria "Sleep" Millisecond (basata sulla versione Excel).

La subroutine SerialPort () delinea i passaggi per aprire la porta, trasmettere alcuni dati, ricevere alcuni dati, riprovare a ricevere alcuni dati (per mostrare che in realtà non si aggira per l'errore "fine del file") e chiudere il porta.


#If VBA7 Then ' Excel 2010 or later
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
#Else ' Excel 2007 or earlier
    Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
#End If

Public Sub SerialPort()
    ' open a COM port, transmit a message, gather results, close the port.

    ' open the COM port as file #1
    Debug.Print "Open COM port 4"
    Open "COM4:115200,N,8,1" For Binary Access Read Write As #1

    transmit$ = Chr(2) + "Hello, World." + Chr(13)
    receiveDummy$ = "~~~"

    ' transmit a message
    Put #1, , transmit$
    Debug.Print "Message sent."

    ' wait a bit for a response
    Sleep 100

    ' check for received message
    Debug.Print "Look for incoming message."
    On Error Resume Next
    Do While True
        receive$ = receiveDummy$  'dummy value
        Input #1, receive$
        If receive$ = receiveDummy$ Then Exit Do  'the string didn't change, so move on
        Debug.Print receive$
    Loop
    On Error GoTo 0

    ' do it again to show that the empty input queue doesn't stop the flow
    Debug.Print "Look again for incoming message (should not stop on error)."
    On Error Resume Next
    Do While True
        receive$ = receiveDummy$  'dummy value
        Input #1, receive$
        If receive$ = receiveDummy$ Then Exit Do  'the string didn't change, so move on
        Debug.Print receive$
    Loop
    On Error GoTo 0

    ' close the serial port
    Debug.Print "Close COM port."
    Close #1

    Debug.Print "Done."
End Sub
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top