ما هي أفضل طريقة للوصول إلى منفذ تسلسلي من VBA؟
-
05-09-2019 - |
سؤال
ما هي أفضل طريقة للوصول إلى منفذ تسلسلي من VBA؟
لدي حاجة لبعض ممثلين مبيعاتنا لتتمكن من إرسال سلسلة بسيطة عبر المنفذ التسلسلي من زر إجراء في PowerPoint. لا أستخدم VBA عادة، خاصة لأي شيء مثل هذا. عادة سأقلها إلى تطبيق من نوع ما، لكنني لا أعتقد أن الفكرة هي سيئة. ستكون أداة مفيدة لهم لتعيين هذا الجهاز مع أثناء وجود جهاز عرض وتتحدث مع رجال المبيعات الآخرين وغير التقنيين. أيضا، لن يكون لدى هذا الرجل المبيعات مشكلة في إجراء تعديلات صغيرة على عرض VBA أو عرض PowerPoint، ولكن لن تفعل ذلك أيضا مع إعادة ترجمة تطبيق .NET.
أعلم أننا قادرون على القيام بذلك من خلال ملف دفعي يعمل من العرض التقديمي على الإجراء، لكن هذا لا يجعلني سعيدا جدا. أنا على الأرجح أن نتمكن من الوصول إلى كائن COM وتشغيله من هناك، ولكن مرة أخرى أنا لست حقيقيا على أحدث وأكبر لمكتبات لاستخدامها في VBA، وسوف يكون من الجيد أيضا الحصول على التمهيدي القليل السريع في كيفية فتح بسهولة، إرسال وإغلاق الاتصال.
نظرا لأن هذا سيحتاج إلى تشغيله على أجهزة كمبيوتر متعددة الناس، فسيكون من الرائع أن تكون قابلة للنقل بسهولة إلى الأجهزة الأخرى. يجب أن أكون قادرا على القول إنه يجب أن يعمل على Office 2007 و Windows XP. التوافق مع أي شيء آخر سيكون مكافأة لطيفة رغم ذلك.
كيف يجب أن أذهب للتعامل مع هذا؟ أي نصائح جيدة أو الحيل؟ توصيات المكتبة؟
المحلول
Win32 API يتعامل مع المنفذ التسلسلي كملف. يمكنك الوصول إلى المنافذ التسلسلية مباشرة عن طريق استدعاء وظائف API هذه من داخل VBA. اضطررت للقيام بذلك للحصول على تطبيق .NET القديم ولكن VBA لا يختلف.
بدلا من التجزئة بها لك على هذا الموقع، إليك مرجع علقت على مر السنين. كيفية تنفيذ اتصالات الميناء التسلسلي في VBA
نصائح أخرى
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
هذا يعمل بالنسبة لي. لست متأكدا مما إذا كان مفتوحا يقوم فعلا بإنشاء معدل الباود، حيث استخدمت Teraterm لأول مرة. ميناء COM الخاص بي هو اتصال USB بمجموعة النماذج الأولية BasyS3. يتم نقل الشخصيات عند 9600، سجلات 36 حرفا تنتهي مع CR. يمكنني إرسال الأوامر عشوائيا من 9 أحرف. في التعليمات البرمجية أعلاه، أقوم بإنشاء سلاسل الأوامر هذه في كل مرة تلقيت فيها سطر جديد. الطريقة التي اخترت فيها الشخصية التي ترسلها هي clunky قليلا: ربما تكون هناك طريقة أفضل للحصول على مؤشر حرف وعدد من الأحرف، وعندما يذهب هؤلاء المساويون إلى حد سواء إلى الصفر.
فيما يلي وحدة موجزة من رمز VBA الذي يمكنه إرسال واستقبال الرسائل على منفذ تسلسلي للكمبيوتر الشخصي. هذا ليس أنيقا جدا، لكنه بسيط وينبغي أن يعمل على الإصدارات الحديثة من Excel و Windows.
تركت بنفسك لتوسيع الوظيفة وتخزين الرسائل أو تحليلها. هذا يدل فقط الأشياء المنخفضة المستوى للتعامل مع المنفذ التسلسلي.
تعلن الأسطر ال 5 الأولى وظيفة مكتبة "النوم" Millisecond (استنادا إلى إصدار Excel).
تحدد الروتين الفرعي Serialport () الخطوات لفتح المنفذ، وإرسال بعض البيانات، واحصل على بعض البيانات، وحاول مرة أخرى تلقي بعض البيانات (لإظهار أنه لا يعمل حقا في AFOL من خطأ "نهاية الملف")، وإغلاق ميناء.
#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