| |
VB.NET - Ein- und UmsteigerSerielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 16.02.12 19:42 |
| Hallo Liebes Forum,
ich brauche mal wieder eure Hilfe.
Ich bekomme von einen Gerät ein serielles Protokoll über RS485 zugeschickt.
Dieses wandel ich auf RS232 auf die Com1.
Das Protokoll ist wie folgt aufgebaut:
1.Byte „Start“ 0hFF
2.Byte „Version“ 0h30
3.Byte „Ziel“ 0h01
4.Byte „Quelle“ 0hFD
5,6. Byte „Anzahl der Parameter“ 0hFF
7.Byte „Kommando“ 0h66
8 bis n.Byte „Parameter“ 0hxx
n+1.Byte „Checksumme“ 0hxx
Dabei kann die Anzahl der Parameter variieren.
Kurz gesagt ich habe kein Hard- u. Soft Handshake und keine feste Paketgröße.
Mit folgenden Code habe ich leider vergleich versucht das Protokoll zu empfangen:
'Einrichten der Com
Private Sub verbinden_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles verbinden.Click
With SerialPort1
If Not .IsOpen Then
Try
.PortName = ComboBox1.Text
.BaudRate = 38400
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.WriteTimeout = 100 ' 1000 ms = 1 Sek.
.ReadTimeout = 100 ' 1000 ms = 1 Sek.
.Open()
verbinden.BackColor = Color.Green
verbinden.Text = "Verbunden"
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler beim Open", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
End If
End With
End Sub
...
Me.SerialPort1.ReceivedBytesThreshold = 1 'nach 1 Bytes DataReceived Event
' auslösen
...
Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As _
System.IO.Ports.SerialDataReceivedEventArgs) Handles _
SerialPort1.DataReceived
With SerialPort1
Try
Bufferbyte = .ReadByte
Select bytezähler
Case 0
If Bufferbyte = &HFF Then 'Start
bytezähler = 1
End If
Case 1
If Bufferbyte = &H30 Then 'Version
bytezähler = 2
Else
bytezähler = 0
End If
Case 2
If Bufferbyte = &H1 Then 'Ziel
bytezähler = 3
Else
bytezähler = 0
End If
Case 3
quelle = Bufferbyte 'Quelle
bytezähler = 4
Case 4
anzahlpara = Bufferbyte * 255
bytezähler = 5
Case 5
anzahlpara = anzahlpara + Bufferbyte
bytezähler = 6
zahler = 0
Case 6
ByteArray(zähler) = Bufferbyte
zähler += 1
Debug.Print(zähler)
If zähler = anzahlpara - 1 Then
MsgBox("hallo")
End If
End Select
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler beim Empfangen ComPort...")
If SerialPort1.IsOpen Then .DiscardInBuffer()
End Try
End With
End Sub Der Debug.Print zeigt mir an das ich nur bis zum 3 oder 5 Parameter komme obwohl ich h33 = 21 Parameter erhalten sollte, die auch per hTerm immer ankommen.
So jetzt zu meinen Fragen
- ist der Lösungsansatz von mir für so ein Problem (kein Handshake) richtig? oder macht man das anders?
- könnt Ihr euch erklären warum ich nur bis zu 5 Parameter empfange?
- habt Ihr oder kennt Ihr ähnliche Projekte?
- seit Ihr so NETT mir zu helfen?
gruß
Matthias | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: sv00010 | Datum: 18.02.12 12:13 |
| ...
Me.SerialPort1.ReceivedBytesThreshold = 1 'nach 1 Bytes DataReceived Event
' auslösen
... Du kannst dich nicht darauf verlassen dass nur 1 Byte im Puffer ist.
Es muss >= 1 sein. 0 | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 19.02.12 13:09 |
| Hallo
wenn ich
Me.SerialPort1.ReceivedBytesThreshold >= 1 schreibe, bekomme ich fehler:
Fehler1 Eigenschaftenzugriff muss der Eigenschaft zugewiesen werden oder deren Wert verwenden.
Fehler2 Ausdruck erwartet.
Fehler3 Methodenargumente müssen in Klammern stehen. | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Manni01 | Datum: 19.02.12 16:02 |
| Ich habe damit noch nicht gearbeitet, aber so wie ich es sehe, kann man es sich nicht so einfach machen. Als erstes musst Du wissen wie lang ein Telegramm ist, hast Du einen eindeutige Längeninformation in dem Telegramm? Die Daten werden in einen Puffer geschrieben, wenn das Ereignis ausgelöst wird, heisst das nicht, das schon ALLE Daten da sind. Ich würde in einem eigenen Thread in einer Schleife immer den Puffer auslesen. In dem Haupt-Thread würde ich dann die empfangenen Daten auswerten. In der Hilfe findet man u.a. auch noch diese wichtigen Hinweise:
Serielle Empfangsereignisse können von jedem Element in der SerialData-Enumeration verursacht werden. Da das Betriebssystem bestimmt, ob dieses Ereignis ausgelöst wird, werden nicht alle Paritätsfehler gemeldet.
Die Ereignisse PinChanged, DataReceived und ErrorReceived können u. U. in der falschen Reihenfolge auftreten, und es kann zu einer geringfügigen Verzögerungen kommen, wenn der zugrunde liegende Stream den Fehler meldet und der Ereignishandler ausgeführt wird. Es kann immer nur jeweils ein Ereignishandler ausgeführt werden.
Das DataReceived-Ereignis wird nicht unbedingt für jedes empfangene Byte ausgelöst. Verwenden Sie die BytesToRead-Eigenschaft, um den Umfang der Daten im Puffer zu bestimmen, die noch gelesen werden müssen.
Das DataReceived-Ereignis wird in einem sekundären Thread ausgelöst, wenn Daten vom SerialPort-Objekt empfangen werden. Da dieses Ereignis in einem sekundären Thread und nicht im Hauptthread ausgelöst wird, kann der Versuch, Elemente wie UI-Elemente im Hauptthread zu ändern, eine Threadausnahme auslösen.Falls es erforderlich ist, Elemente im Haupt- Form oder im Haupt- Control zu ändern, senden Sie Änderungsanforderungen mithilfe von Invoke zurück, der den Vorgang dann auf dem richtigen Thread ausführt. | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 20.02.12 12:18 |
| Hallo und Danke für die Antwort,
das Problem was ich habe das ich vor dem empfang nicht weiß wie lang das Telegramm wird. Die länge des Telegramms habe ich erst wenn ich den Kopf des Telegramms auslese (Parameter länge).
Ich habe es jetzt erstmal so gemacht das ich
Me.SerialPort1.ReceivedBytesThreshold = 7 nehme (anzahl der Byts im Kopf des Telegramms die immer da sind) und wenn das Ereigniss auslöst warte ich 10ms bevor ich den Buffer auslese, so kommen die Telegramme eigendlich fast immer richtig an.
Aber irgendwie glaube ich nicht das dass der richtige Weg ist.
gruß
Matthias
Beitrag wurde zuletzt am 20.02.12 um 12:19:28 editiert. | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 21.02.12 17:57 |
| Hallo,
hier nochmal meine Lösung wie ich es bis jetzt mache:
Option Explicit On
Option Strict Off
Imports System.IO.Ports
Imports Microsoft.Win32
Imports Microsoft.VisualBasic
Public Class Form1
Dim T3_IO_Status_Array(0 To 100) As Byte
Dim ByteArray(0 To 100) As Byte
Private Delegate Sub DelegateSub()
Private Aktualisieren As New DelegateSub(AddressOf updateForm)
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
'Com-Ports finden
Dim EinzelPort As String
For Each EinzelPort In My.Computer.Ports.SerialPortNames
ComboBox1.Items.Add(EinzelPort)
Next EinzelPort
End Sub
Private Sub verbinden_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles verbinden.Click
With SerialPort1
If Not .IsOpen Then
Try
.PortName = ComboBox1.Text
.BaudRate = 38400
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.WriteTimeout = 1000 ' 1000 ms = 1 Sek.
.ReadTimeout = 1000 ' 1000 ms = 1 Sek.
.ReceivedBytesThreshold = 8
.Open()
verbinden.BackColor = Color.Green
verbinden.Text = "Verbunden"
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler beim Open", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
End If
End With
End Sub
Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As _
System.IO.Ports.SerialDataReceivedEventArgs) Handles _
SerialPort1.DataReceived
'System.Threading.Thread.Sleep(50)
Delay(50) 'warten bis Telegramm empfangen ist
If DatenPruefen() = True Then
If ByteArray(1) = &H30 And ByteArray(2) = &H1 And ByteArray(6) = _
&H66 Then 'Staus
ByteArray.CopyTo(T3_IO_Status_Array, 0) 'Datenübertrag
Me.Invoke(Aktualisieren)
End If
End If
End Sub
Function DatenPruefen() As Boolean
DatenPruefen = False
With SerialPort1
Try
Dim count As Integer = .BytesToRead 'Anzahl der empangenden
' Byts
.Read(ByteArray, 0, count)
If ByteArray(0) = 255 And Checksumme(ByteArray) = True Then
DatenPruefen = True
End If
.DiscardInBuffer()
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler beim Empfangen" & _
"T3-ComPort...")
If .IsOpen Then .DiscardInBuffer()
End Try
End With
End Function
Function Checksumme(ByVal Daten As Array) As Boolean
Dim summe As Integer = 0
For zähler As Integer = 2 To 39
summe = summe + (Daten(zähler))
Next
summe = summe Mod 256
If summe = 255 Then summe = 0
If Daten(40) = summe Then
Checksumme = True
Else
Checksumme = False
End If
End Function
Private Sub Delay(ByVal Zeit As Integer)
Dim Zeit1 As Integer = System.Environment.TickCount
While (System.Environment.TickCount - Zeit1) < Zeit
Application.DoEvents()
End While
End Sub
Sub updateForm()
TextBox1.Text = "Hallo"
End Sub
End Class falls jemand von euch eine bessere Idee hat dann immer gerne her damit
gruß
Matthias | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Preisser | Datum: 21.02.12 20:08 |
| Hallo,
ich verstehe grade nicht ganz, warum du ein Delay einbauen musst, um die Daten richtig zu empfangen (DoEvents sollte man sowieso immer vermeiden). Wenn der Head immer aus 7 Bytes besteht und ihm die Länge der restlichen Daten enthalten ist, weißt du ja nach dem Lesen des Heads, wieviele Daten noch kommen werden.
Wäre es hier nicht einfacher, z.B. einen neuen Thread zu starten, der in einer Schleife immer Daten empfängt (also Blocking I/O), anstatt ein Event zu verwenden? Dann könntest du z.B. eine Schleife machen, die immer zuerst den Head einliest, und danach den Rest, und hinterher den GUI-Thread benachrichtigt.
Also z.B. sowas wie
Private Sub verbinden_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles verbinden.Click
With SerialPort1
If Not .IsOpen Then
Try
.PortName = ComboBox1.Text
.BaudRate = 38400
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.WriteTimeout = 1000 ' 1000 ms = 1 Sek.
'.ReadTimeout = 1000 ' 1000 ms = 1 Sek.
.Open()
verbinden.BackColor = Color.Green
verbinden.Text = "Verbunden"
Dim readThread As New Thread( 'Lesethread
Sub()
ReadSerialPort(SerialPort1)
End Sub)
readThread.Start()
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler beim Open", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
End If
End With
End Sub
'Wird im Lesethread aufgerufen
Private Sub ReadSerialPort(port As SerialPort)
' Lesen
While True
' 7 Bytes Head lesen
Dim head As Byte() = New Byte(6) {}
Dim headBytesRead As Integer = 0
While headBytesRead < head.Length
Dim read As Integer = port.Read(head, headBytesRead, head _
.Length - headBytesRead)
headBytesRead += read
End While
'jetzt aus Head die Größe der restlichen Daten auslesen
Dim restlicheGroesse As Integer = .....
Dim body As Byte() = New Byte(restlicheGroesse - 1) {}
Dim bodyBytesRead As Integer = 0
While bodyBytesRead < restlicheGroesse
Dim read As Integer = port.Read(body, bodyBytesRead , _
restlicheGroesse - bodyBytesRead )
bodyBytesRead += read
End While
'GUI-Thread benachrichtigen, dass Telegramm empfangen wurde
BeginInvoke(New Action(Of Byte(), Byte())(AddressOf _
TelegramEmpfangen), head, body)
End While
End Sub
'Wird im GUI-Thread aufgerufen, wenn Telegramm empfangen wurde
Private Sub TelegramEmpfangen(head As Byte(), body As Byte())
'Weiterverarbeiten..
End Sub Die Read()-Methode kann allerdings eine TimeoutException werfen, weshalb ich das Setzen der Timeout-Eigenschaft oben auskommentiert habe (standardmäßig wird ein unendliches Timeout verwendet).
Beitrag wurde zuletzt am 21.02.12 um 20:18:27 editiert. | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Manni01 | Datum: 21.02.12 20:30 |
| Genau so meinte ich es.... | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 22.02.12 14:51 |
| Ahhhh, ich verstehe...
werde ich heute Abend gleich mal testen, gebe dann rückmeldung.
gruß
Matthias | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 23.02.12 20:50 |
| So,
dank euch habe ich zwei neu Lösungen für mein Problem
und auch gleich ein paar neu Fragen
Hier erstmal die Lösung nach Preisser und Manni01:
Private Sub verbinden_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles verbinden.Click
With SerialPort1
If Not .IsOpen Then
Try
.PortName = ComboBox1.Text
.BaudRate = 38400
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.WriteTimeout = 1000 ' 1000 ms = 1 Sek.
'.ReadTimeout = 1000 ' 1000 ms = 1 Sek.
.Open()
verbinden.BackColor = Color.Green
verbinden.Text = "Verbunden"
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler beim Open", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
End If
End With
End Sub
Private Sub Start_Click(sender As System.Object, e As System.EventArgs) _
Handles Start.Click
Dim start As New ParameterizedThreadStart(AddressOf ReadSerialPort)
Dim empfangen As New Thread(start)
empfangen.Start(SerialPort1)
End Sub
Private Sub ReadSerialPort(port As SerialPort)
' Lesen
Do
' 7 Bytes Head lesen
Dim head_array As Byte() = New Byte(6) {}
Dim headBytesRead As Integer = 0
While headBytesRead < head_array.Length
Dim read As Integer = port.Read(head_array, headBytesRead, ( _
head_array.Length - headBytesRead))
headBytesRead += read
End While
If head_array(0) = &HFF And head_array(1) = &H30 And head_array(2) _
= &H1 Then
Dim parameterlänge As Integer = (head_array(4) * 255) + _
head_array(5) + 1
Dim body_array As Byte() = New Byte(parameterlänge - 1) {}
Dim bodyBytesRead As Integer = 0
While bodyBytesRead < parameterlänge
Dim read As Integer = port.Read(body_array, bodyBytesRead, _
parameterlänge - bodyBytesRead)
bodyBytesRead += read
End While
If Checksumme(head_array, body_array) = False Then
MsgBox("nicht ok")
port.DiscardInBuffer()
Else
'GUI-Thread benachrichtigen, dass Telegramm empfangen wurde
BeginInvoke(New Action(Of Byte(), Byte())(AddressOf _
TelegramEmpfangen), head_array, body_array)
End If
Else
port.DiscardInBuffer()
End If
Loop
End Sub
Function Checksumme(ByVal Hader_Daten As Array, ByVal Body_Daten As Array) As _
Boolean
Dim summe As Integer = 0
For zähler As Integer = 2 To 6
summe = summe + (Hader_Daten(zähler))
Next
For zähler As Integer = 0 To Body_Daten.Length - 2
summe = summe + (Body_Daten(zähler))
Next
summe = summe Mod 256
If summe = 255 Then summe = 0
If Body_Daten(Body_Daten.Length - 1) = summe Then
Checksumme = True
Else
Checksumme = False
End If
End Function
'Wird im GUI-Thread aufgerufen, wenn Telegramm empfangen wurde
Private Sub TelegramEmpfangen(head As Byte(), body As Byte())
empfänger += 1
TextBox1.Text = empfänger
End Sub | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 23.02.12 20:52 |
| Die Lösung läuft wie gewünscht und an dieser Stelle nochmals vielen DANK an euch.
Da ich aber noch nicht so viel Erfahrung mit Multithreading habe, habe ich versucht mich damit etwas mehr zu beschäftigen. (falls jemand von euch noch ein gutes "Deutsches" Tutorial zu diesen Thema kennt, bitte sagen, hatte bis jetzt nur für c.net was gutes gefunden).
Dabei bin ich auf diese Lösung gestoßen: | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 23.02.12 20:53 |
| Dim WithEvents BGW As New System.ComponentModel.BackgroundWorker With _
{.WorkerReportsProgress = True, .WorkerSupportsCancellation = True} _
' BackgroundWorker deklarieren
Private Sub verbinden_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles verbinden.Click
With SerialPort1
If verbinden.Text = "Verbinden" Then
If Not .IsOpen Then
Try
.PortName = ComboBox1.Text
.BaudRate = 38400
.DataBits = 8
.Parity = Parity.None
.StopBits = StopBits.One
.WriteTimeout = 1000 ' 1000 ms = 1 Sek.
'.ReadTimeout = 1000 ' 1000 ms = 1 Sek.
.Open()
Catch ex As Exception
MessageBox.Show(ex.Message, "Fehler beim Open", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub
End Try
End If
If Not BGW.IsBusy Then 'wenn BackgroundWorker aus -> Starten
BGW.RunWorkerAsync(SerialPort1)
End If
verbinden.BackColor = Color.Green
verbinden.Text = "Verbunden"
Else 'Verbindung abbrechen
If BGW.IsBusy Then 'wenn BackgroundWorker an
BGW.CancelAsync() 'BackgroundWorker abbrechen
End If
verbinden.BackColor = Color.Red
verbinden.Text = "Verbinden"
End If
End With
End Sub
Private Sub BGW_DoWork(sender As Object, e As _
System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
'SerialPort lesen
Do
' 7 Bytes Head lesen
Dim head_array As Byte() = New Byte(6) {}
Dim headBytesRead As Integer = 0
While headBytesRead < head_array.Length
Dim read As Integer = e.Argument.Read(head_array, _
headBytesRead, (head_array.Length - headBytesRead))
headBytesRead += read
If BGW.CancellationPending Then 'BackgroundWorker
' abbrechen
Exit Do
End If
End While
If head_array(0) = &HFF And head_array(1) = &H30 And head_array(2) _
= &H1 Then
Dim parameterlänge As Integer = (head_array(4) * 255) + _
head_array(5) + 1
Dim body_array As Byte() = New Byte(parameterlänge - 1) {}
Dim bodyBytesRead As Integer = 0
While bodyBytesRead < parameterlänge
Dim read As Integer = e.Argument.Read(body_array, _
bodyBytesRead, parameterlänge - bodyBytesRead)
bodyBytesRead += read
If BGW.CancellationPending Then 'BackgroundWorker
' abbrechen
Exit Do
End If
End While
If Checksumme(head_array, body_array) = False Then
MsgBox("nicht ok")
e.Argument.DiscardInBuffer()
Else
'Daten an Form geben
BGW.ReportProgress(Nothing, New BGWUserState With _
{.BGW_head_array = head_array, .BGW_body_array = _
body_array})
End If
Else
e.Argument.DiscardInBuffer()
End If
Loop
End Sub
Class BGWUserState
Public BGW_head_array() As Byte
Public BGW_body_array() As Byte
End Class
Private Sub BGW_ProgressChanged(sender As Object, e As _
System.ComponentModel.ProgressChangedEventArgs) Handles _
BGW.ProgressChanged
Dim UserState As BGWUserState = DirectCast(e.UserState, BGWUserState)
If UserState.BGW_head_array(0) = 255 Then
empfänger += 1
TextBox1.Text = empfänger
End If
End Sub
Private Sub BGW_RunWorkerCompleted(sender As Object, e As _
System.ComponentModel.RunWorkerCompletedEventArgs) Handles _
BGW.RunWorkerCompleted
SerialPort1.DiscardInBuffer()
SerialPort1.Close()
' MsgBox("BGW abgebrochen")
End Sub
Function Checksumme(ByVal Hader_Daten As Array, ByVal Body_Daten As Array) As _
Boolean
...
End Function Die Frage könnt Ihr euch bestimmt schon denken
wo liegen die Vor und Nachteile der beiden Metoden, wann wendet man welche an?
Leider habe ich nichts gefunden was mir meine Fragen beantwortet, daher hoffe ich das Ihr kurz was dazu sagen könnt.
Ach ja verbesserungs Vorschläge zum Code sind immer herzlich willkommen.
gruß
Matthias | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 28.02.12 07:42 |
| Ok Leute,
obwohl meine VB.Net Bücher noch nicht angekommen sind habe ich versucht mich im Netz ein wenig zu meiner Frage schlau zu machen.
Control.Invoke wartet bis der GUI- Thread die Aktion ausgeführt hat.
Control.BeginInvoke fügt den Arbeitsauftrag die Nachrichtenschlange des GUI-Threads ein und kehrt sofort zurück.
Control.Invoke soll eine vergleichsweise langsame Operation sein(wie auch immer das zu deuten ist). Daher soll die Laufzeit von Invoke-Threads möglichs kurz gehalten werden.
Wenn man die BackgroundWorker-Klasse verwendet, werden alle Zugriffe auf das GUI einfach aus den ProgressChanged- oder RunWorkerCompleted-EventHandlern durchgeführt, explizites Control.Invoke ist beim BackgroundWorker nicht erforderlich, denn die ProgressChanged- und RunWorkerCompleted-EventHandler werden im Hintergrund automatisch per Control.BeginInvoke aufgerufen.
Ich hoffe das ich es soweit erstmal richtig verstanden habe?
Gruß
Matthias | |
Re: Serielles Protokoll ohne Handshake empfangen | | | Autor: Laserbrenner | Datum: 19.03.12 06:43 |
| Hallo,
kann sich jemand zu meiner Frage außern?
gruß
Matthias | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
Neu! sevPopUp 2.0
Dynamische Kontextmenüs!
Erstellen Sie mit nur wenigen Zeilen Code Kontextmenüs dynamisch zur Laufzeit. Vordefinierte Styles (XP, Office, OfficeXP, Vista oder Windows 8) erleichtern die Anpassung an die eigenen Anwendung... Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|