Quelle est la meilleure façon d'accéder à un port série de VBA?
-
05-09-2019 - |
Question
Quelle est la meilleure façon d'accéder à un port série de VBA?
J'ai besoin que certains de nos représentants commerciaux puissent envoyer une chaîne simple sur le port série à partir d'un bouton d'action dans PowerPoint. Je n'utilise généralement pas de VBA, surtout pour quelque chose comme ça. Normalement, je le transformerais en une sorte d'application, mais je ne pense pas que l'idée est si mauvaise. Ce sera un outil pratique pour eux pour faire la démonstration de cet appareil avec un projecteur et parler à d'autres vendeurs et à des personnes non techniques. De plus, ce vendeur n'aura aucun problème à apporter de petites modifications à la présentation VBA ou PowerPoint, mais ne ferait pas aussi bien avec la recompilation d'une application .NET.
Je sais que nous pourrions le faire via un fichier batch exécuté à partir de la présentation sur l'action, mais cela ne me rend pas très heureux. Je pense que nous pourrions probablement accéder à un objet COM et courir à partir de là, mais encore une fois, je ne suis pas réel sur les dernières et les meilleures bibliothèques à utiliser dans VBA, et ce serait également bien d'obtenir une petite apprêt rapide dans la façon d'ouvrir facilement, Envoyer et fermer la connexion.
Étant donné que cela devra être exécuté sur plusieurs ordinateurs de personnes, ce serait bien s'il serait facilement transportable vers d'autres machines. Je devrais être en mesure de dire qu'il doit fonctionner à l'Office 2007 et Windows XP. La compatibilité avec quoi que ce soit d'autre serait un bon bonus.
Comment dois-je gérer cela? De bons conseils ou astuces? Recommandations de la bibliothèque?
La solution
L'API WIN32 gère le port série en tant que fichier. Vous pouvez accéder directement aux ports en série en appelant ces fonctions API à partir de VBA. J'ai dû le faire pour une ancienne application .NET mais VBA n'est pas différente.
Plutôt que de le hacher pour vous sur ce site, voici une référence à laquelle je me suis accroché au fil des ans. Comment effectuer des communications de port série dans VBA
Autres conseils
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
Cela fonctionne pour moi. Je ne sais pas si l'Open configure le taux de bauds, car j'ai utilisé Teraterm pour la première fois. Mon port com est une connexion USB à un kit de prototypage Basys3. Il crache des personnages à 9600, des enregistrements de 36 caractères se terminant par CR. Je peux envoyer au hasard des commandes de 9 caractères. Dans le code ci-dessus, je génère ces chaînes de commande chaque fois que j'ai reçu une nouvelle ligne. La façon dont j'ai choisi le personnage à envoyer est un peu maladroit: peut-être une meilleure façon est d'avoir un pointeur de personnage et un certain nombre de caractères, et lorsque ceux-ci sont égaux pour les définir tous les deux sur zéro.
Voici un bref module de code VBA qui peut envoyer et recevoir des messages sur un port série PC. Ce n'est pas très élégant, mais il est simple et devrait fonctionner sur les versions modernes d'Excel et de Windows.
Vous êtes laissé seul pour étendre la fonctionnalité et stocker ou analyser les messages. Cela montre simplement les éléments de bas niveau à traiter avec le port série.
Les 5 premières lignes déclarent la fonction de bibliothèque "Sleep" en millisecondes (basée sur la version Excel).
Le sous-programme Serialport () décrit les étapes pour ouvrir le port, transmettre certaines données, recevoir des données, essayer à nouveau de recevoir des données (pour montrer qu'elle ne fonctionne vraiment pas sur l'erreur "Fin of Fichier") et fermer le Port.
#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