我同事给我发数据,数据就是这样的格式A527510905221125361234EEEE050006030503005101590375EEEEEEEE05000603000026,同一条数据发3遍,间隔60毫秒。我收到一条数据后先判断这条数据是不正确的。判断方法就是从A5开始不带进位相加,一直加到26(A5+27+51+-----+00+00+26)结果为0说明数据正确,然后开始提取我需要的数据出来,显示。剩下的两条就不接收。如果结果不为0,就说明数据错误,需要接收60毫秒后的数据。这个怎么实现阿,我下边的数据接收没有判断,就直接接收了,希望大家帮我在我的代码里加上判断数据是否正确的代码。还有就是我收到正确的数据后提取我需要的信息显示出来的同时要保存在数据库中。但是我现在的这段代码保存的时候同一条数据保存多次,希望大家能帮我看看问题出在什么地方。下边是我的代码,谢谢大家了。(每段代码的功能,请看我代码后边的注释,谢谢)Option Explicit
    Dim strData As String
    Dim dateSj As String
    Dim timeSj As String
    Dim zjhSj As String
    Dim gzdlSj As String
    Dim swsjSj As String
    Dim pfdlSj As String
    Dim pfsjSj As String
    Dim TCUSj As String
    Dim f51Sj As String
    Dim f61Sj As String
    Dim f52Sj As String
    Dim f62Sj As String
    Dim BhSj As String
    Dim jgSj As StringPrivate Sub Command2_Click()                   '这是我将显示出来的数据保存在数据库中。如果我人工点击Command2
Dim sql As String                              '保存的数据就为一条,但是如果我调用call command2_click保存的就
sql = "select * from 数据 "                    '是相同的数据保存3条。不知道为什么。
Adodc1.Refresh
Adodc1.Recordset.AddNew                        '将文本框中用户输入的各个字段取值填入相应的字段
Adodc1.Recordset.Fields("日期") = Text2.Text
Adodc1.Recordset.Fields("主机编号") = Text4.Text
Adodc1.Recordset.Fields("时间") = Text3.Text
Adodc1.Recordset.Fields("上网时间") = Text5.Text
Adodc1.Recordset.Fields("工作电流") = Text6.Text
Adodc1.Recordset.Fields("排风电流") = Text7.Text
Adodc1.Recordset.Fields("排风时间") = Text8.Text
Adodc1.Recordset.Fields("TCU状态") = Text9.Text
Adodc1.Recordset.Fields("500风压1值") = Text10.Text
Adodc1.Recordset.Fields("500风压2值") = Text13.Text
Adodc1.Recordset.Fields("600风压1值") = Text11.Text
Adodc1.Recordset.Fields("600风压2值") = Text14.Text
Adodc1.Recordset.Fields("检测结果") = Text12.Text
Adodc1.Recordset.Update
Adodc1.Refresh
End SubPrivate Sub mscomm1_oncomm()               '这就是我接收数据的代码,但是我不会添加那个判断数据是否正确的代码,
    Dim inByte() As Byte                   '请大家帮我写下代码学习下。
    Dim i As Integer
    Dim l As Long, q As Long, e As Long, t As Long, u As Long, k As Long, s As Long, b As Long, c As Long
    
    Select Case MSComm1.CommEvent
        Case comEvReceive
        inByte = MSComm1.Input
        For i = 0 To UBound(inByte)
        If Len(Hex(inByte(i))) = 1 Then
            strData = strData & "0" & Hex(inByte(i))
        Else
            strData = strData & Hex(inByte(i))
        End If
        Next
        Text1.Text = strData
        '以下写符合通信协议规定的判断代码处理接收数据
        
        If Mid(strData, 1, 2) = "A5" And Len(strData) >= 66 Then
            dateSj = Mid(strData, 7, 2) & "-" & Mid(strData, 9, 2) & "-" & Mid(strData, 11, 2)     '日期显示
            Text2 = dateSj
            
            BhSj = Mid(strData, 3, 4)                                                              '检测台编号
            Text15 = BhSj
            
            timeSj = Mid(strData, 13, 2) & ":" & Mid(strData, 15, 2) & ":" & Mid(strData, 17, 2)   '时间显示
            Text3 = timeSj
            
            zjhSj = Mid(strData, 19, 4)                                                            '主机号显示
            Text4 = "K" & zjhSj
            
            TCUSj = Mid(strData, 37, 2)                                                            'TCU状态
            Text9 = TCUSj
            
            jgSj = Mid(strData, 67, 4)                                                             '结果显示
            Text12 = jgSj
            
    l = CLng("&H" & jgSj)
    q = CLng("&H4000")                      '上网时间校验值
    e = CLng("&H0004")                      '工作电流校验值
    t = CLng("&H0008")                      '排风电流校验值
    u = CLng("&H0080")                      '排风时间校验值
    k = CLng("&H0020")                      '500风压1校验值
    s = CLng("&H0040")                      '600风压1校验值
    b = CLng("&H0200")                      '500风压2校验值
    c = CLng("&H0400")                      '600风压2校验值
            
            swsjSj = Mid(strData, 35, 2)                                                           '上网时间
            If (l And q) = 0 Then
            Text5 = swsjSj & "S"
            Else
            Text5 = swsjSj & "S*"
            End If
            
            gzdlSj = Mid(strData, 39, 2) & "." & Mid(strData, 41, 2)                               '工作电流
            If (l And e) = 0 Then
            Text6 = Format(gzdlSj, "0.00") & "A"
            Else
            Text6 = Format(gzdlSj, "0.00") & "A*"
            End If
            
            pfdlSj = Mid(strData, 43, 2) & "." & Mid(strData, 45, 2)                               '排风电流
            If (l And t) = 0 Then
            Text7 = Format(pfdlSj, "0.00") & "A"
            Else
            Text7 = Format(pfdlSj, "0.00") & "A*"
            End If
            
            pfsjSj = Mid(strData, 47, 2) & "." & Mid(strData, 49, 2)                               '排风时间
            If (l And u) = 0 Then
            Text8 = Format(pfsjSj, "0.00") & "S"
            Else
            Text8 = Format(pfsjSj, "0.00") & "S*"
            End If
            
            f51Sj = Mid(strData, 27, 4)                                                            '500风压1值
            If (l And k) = 0 Then
            Text10 = Format(f51Sj, "000") & "Kpa"
            Else
            Text10 = Format(f51Sj, "000") & "Kpa*"
            End If
            
            f61Sj = Mid(strData, 31, 4)                                                            '600风压1值
            If (l And s) = 0 Then
            Text11 = Format(f61Sj, "000") & "Kpa"
            Else
            Text11 = Format(f61Sj, "000") & "Kpa*"
            End If
            
            f52Sj = Mid(strData, 59, 4)                                                            '500风压2值
            If (l And b) = 0 Then
            Text13 = Format(f52Sj, "000") & "Kpa"
            Else
            Text13 = Format(f52Sj, "000") & "Kpa*"
            End If
            
            f62Sj = Mid(strData, 63, 4)                                                            '600风压2值
            If (l And c) = 0 Then
            Text14 = Format(f62Sj, "000") & "Kpa"
            Else
            Text14 = Format(f62Sj, "000") & "Kpa*"
            End If
            strData = ""
            
            If TCUSj = 0 Then
            Text9.Text = "A异常B上网"
            ElseIf TCUSj = 1 Then
            Text9.Text = "A上网B异常"
            ElseIf TCUSj = 2 Then
            Text9.Text = "A正常B上网"
            ElseIf TCUSj = 3 Then
            Text9.Text = "A上网B正常"
            End If
           
            If jgSj = 0 Then
            Text12 = "正常"
            Else
            Text12 = "异常"
            End If
            End If
     End Select
     
     call command2_click
   
End SubPrivate Sub Form_Load()    With MSComm1
        .CommPort = 1
        .Settings = "9600,n,8,1"
        .InBufferCount = 0
        .InputLen = 0
        .RThreshold = 1
        .InputMode = comInputModeBinary '以2进制接收
        .PortOpen = True
    End With
    Text1 = ""
End Sub'关闭通信端口,停止程序运行
Private Sub cmdquit_click()
  MSComm1.PortOpen = False
  End
End Sub
 

解决方案 »

  1.   

    Private Sub Mscomm1_OnComm() '这就是我接收数据的代码,但是我不会添加那个判断数据是否正确的代码,
        Dim inByte() As Byte         '请大家帮我写下代码学习下。
        Dim i As Integer
        Select Case MSComm1.CommEvent
            Case comEvReceive
                inByte = MSComm1.Input
                For i = 0 To UBound(inByte)
                If Len(Hex(inByte(i))) = 1 Then
                    strdata = strdata & "0" & Hex(inByte(i))
                Else
                    strdata = strdata & Hex(inByte(i))
                End If
                Next
                Text1.Text = strdata
                '以下写符合通信协议规定的判断代码处理接收数据
                If Mid(strdata, 1, 2) = "A5" And Len(strdata) >= 66 Then '这里接收字节长度与LZ给出的字节长度不一致,似乎有问题.
                    Dim j As Integer
                    Dim jyh As Long
                    For j = 1 To Len(sj) Step 2
                        jyh = jyh + Val("&H" & Mid(strdata, j, 2))
                    Next
                    If jyh Mod 256 = 0 Then '所谓不带进位相加,最后结果等于零,即全部字节和能整除256
                        Text3 = "OK"
                        '进入数据处理
                        
                       End If
                    strdata = ""
                End If
        End Select
    End Sub
      

  2.   

    sql = "select * from 数据 " 
    sql = "select * from 数据 where "......
    open 开,如果存在,则不保存,如果不存在,则保存 
      

  3.   

    楼上,你的回复与LZ要求不相干,属于数据库查询的SQL语句.
      

  4.   

    你好,你刚才给我的代码里边这条For j = 1 To Len(sj) Step 2,说是(sj)这个变量为定义。这是怎么回事啊,对了还有你说的这个
    If Mid(strdata, 1, 2) = "A5" And Len(strdata) >= 66 Then '这里接收字节长度与LZ给出的字节长度不一致,似乎有问题.
    我同事给我发的数据里边一共36个字节,我这个>= 66是不应该写成>= 72阿?上边这个我看了也是你帮我弄得,真是太感谢你了。
      

  5.   

    抱歉!漏改一处,如果下位机返回数据帧始终是36字节,则可设置
    Mscomm1.RThreshold = 36 
    代码修改如下:
    Private Sub Mscomm1_OnComm() '这就是我接收数据的代码,但是我不会添加那个判断数据是否正确的代码,
        Dim inByte() As Byte         '请大家帮我写下代码学习下。
        Dim i As Integer
        Select Case MSComm1.CommEvent
            Case comEvReceive
                inByte = MSComm1.Input
                For i = 0 To UBound(inByte)
                If Len(Hex(inByte(i))) = 1 Then
                    strdata = strdata & "0" & Hex(inByte(i))
                Else
                    strdata = strdata & Hex(inByte(i))
                End If
                Next
                Text1.Text = strdata
                '以下写符合通信协议规定的判断代码处理接收数据
                If Mid(strdata, 1, 2) = "A5" And Len(strdata) = 72 Then '这里接收字节长度与LZ给出的字节长度不一致,似乎有问题.
                    Dim j As Integer
                    Dim jyh As Long
                    For j = 1 To Len(strdata) Step 2
                        jyh = jyh + Val("&H" & Mid(strdata, j, 2))
                    Next
                    If jyh Mod 256 = 0 Then '所谓不带进位相加,最后结果等于零,即全部字节和能整除256
                        Text3 = "OK"
                        '进入数据处理
                        
                       End If
                    strdata = ""
                End If
        End Select
    End Sub
      

  6.   

    你好,好像可以校验了,我能得到Text16= "OK",但是好像我同事给我发多条数据后,有的时候显示的还是上一条的数据。
    就是Text1.Text = strdata这个里边能显示当前的发过来的数据。但是我text2——text12里边显示的还是上一条的数据。
    同时我call command2_click 后保存的还是同一条数据保存多次。
    这是为啥阿?对了我把这个Mscomm1.RThreshold = 36加这了。不知道对不。
    Private Sub Form_Load()
    MSComm1.RThreshold = 36
        With MSComm1
            .CommPort = 1
            .Settings = "9600,n,8,1"
            .InBufferCount = 0
            .InputLen = 0
            .RThreshold = 1
            .InputMode = comInputModeBinary '以2进制接收
            .PortOpen = True
        End With
        Text1 = ""
    End Sub
      

  7.   

    既然Text1.Text = strdata这个里边能显示当前的发过来的数据,那就说明你数据处理的代码放置的位置有问题.
      

  8.   

    Private Sub Mscomm1_OnComm() '这就是我接收数据的代码,但是我不会添加那个判断数据是否正确的代码,
        Dim inByte() As Byte         '请大家帮我写下代码学习下。
        Dim i As Integer
        Select Case MSComm1.CommEvent
            Case comEvReceive
                inByte = MSComm1.Input
                For i = 0 To UBound(inByte)
                If Len(Hex(inByte(i))) = 1 Then
                    strdata = strdata & "0" & Hex(inByte(i))
                Else
                    strdata = strdata & Hex(inByte(i))
                End If
                Next
                Text1.Text = strdata
                '以下写符合通信协议规定的判断代码处理接收数据
                If Mid(strdata, 1, 2) = "A5" And Len(strdata) = 72 Then '这里接收字节长度与LZ给出的字节长度不一致,似乎有问题.
                    Dim j As Integer
                    Dim jyh As Long
                    For j = 1 To Len(strdata) Step 2
                        jyh = jyh + Val("&H" & Mid(strdata, j, 2))
                    Next
                    If jyh Mod 256 = 0 Then '所谓不带进位相加,最后结果等于零,即全部字节和能整除256
                        Text3 = "OK"
                        '进入数据处理
                           dateSj = Mid(strData, 7, 2) & "-" & Mid(strData, 9, 2) & "-" & Mid(strData, 11, 2)    '日期显示 
                           Text2 = dateSj                     
                       End If
                    strdata = ""
                End If
        End Select
    End Sub
      

  9.   

    将call command2_click句放置在
    If jyh Mod 256 = 0 Then 
      

  10.   

    你好,我试了,现在好像剩下的问题就是同一条数据保存多次了。我已经将call command2_click句放置在If jyh Mod 256 = 0 Then后了,但是同一条数据还是保存了3条。我估计是不这样啊,因为同事给我发数据是同一条数据发3遍,每条间隔是60毫秒,会不会我们处理完数据后还没有超过这60毫秒,然后后边的数据也接着处理了,照成同一条数据多次保存。(我刚看了下,是同一条数据保存了3次)
     
      

  11.   

    使用MID函数截取数据,然后相加(相加的结果Mod 256),例如:Dim intSum as integer
    intSum=0
    For I=1  TO  len(strP)\2-1
        intSum=(intSum+Hex("&H" & Mid(strP,2*(I-1)+1,2))) Mod 256
    next I将此段代码添加到OnComm控件中,以处理接受到的数据。
      

  12.   

    LZ:你应该和你的同事修改通信协议,可以在正确接收后由上位机发送正确接收的信息,如"OK",下位机收到"OK",停止发送否则继续发送数据.
    或者三次接收到同样数据则保存数据一次.
      

  13.   

    Option Explicit
        Dim strDataOld As String
        Dim strData As StringPrivate Sub Form_Load()
        MSComm1.RThreshold = 36
        MSComm1.InputLen = 0
        MSComm1.InputMode = comInputModeBinary
        MSComm1.PortOpen = True
    End SubPrivate Sub Mscomm1_OnComm() '这就是我接收数据的代码,但是我不会添加那个判断数据是否正确的代码,
        Dim inByte() As Byte         '请大家帮我写下代码学习下。
        Dim i As Integer
        Select Case MSComm1.CommEvent
            Case comEvReceive
                inByte = MSComm1.Input
                For i = 0 To UBound(inByte)
                    If Len(Hex(inByte(i))) = 1 Then
                        strData = strData & "0" & Hex(inByte(i))
                    Else
                        strData = strData & Hex(inByte(i))
                    End If
                Next
                Text1.Text = strData
                    Text5 = Len(strData)
                '以下写符合通信协议规定的判断代码处理接收数据
                If Mid(strData, 1, 2) = "A5" And Len(strData) = 72 Then '这里接收字节长度与LZ给出的字节长度不一致,似乎有问题.
                    Dim j As Integer
                    Dim jyh As Long
                    For j = 1 To Len(strData) Step 2
                        jyh = jyh + Val("&H" & Mid(strData, j, 2))
                    Next
                    If jyh Mod 256 = 0 Then '所谓不带进位相加,最后结果等于零,即全部字节和能整除256
                        Text3 = "OK"
                        '进入数据处理
                        Text2 = Mid(strData, 7, 2) & "-" & Mid(strData, 9, 2) & "-" & Mid(strData, 11, 2)    '日期显示
                        'Text2 = dateSj
                        If strDataOld <> strData Then
                            Text4 = "SAVE"
                            Call command2_click
                        Else
                            Text4 = ""
                        End If
                    End If
                    strDataOld = strData
                    strData = ""
                End If
        End Select
    End Sub
      

  14.   

    我这样添加完(上边代码如我发的帖子)
                If jgSj = 0 Then
                Text12 = "正常"
                Else
                Text12 = "异常"
                End If
                strData = ""
                 If strDataOld <> strData Then
                            Text18 = "SAVE"
                            Call Command2_Click
                        Else
                            Text18 = ""
                        End If
                        strDataOld = strData
                    strData = ""
                End If
                End If
         End Select
    End Sub
    最后的结果还是同一条数据保存了3遍,能不能在保存前添加点代码使同一条数据只保存一次阿?
    如果我这样添加
                If jgSj = 0 Then
                Text12 = "正常"
                Else
                Text12 = "异常"
                End If
                strData = ""
                 If strDataOld <> strData Then
                            Text18 = "SAVE"
                            Call Command2_Click
                        Else
                            Text18 = ""
                        End If
                        
                End If
                strDataOld = strData
                strData = ""
                End If
         End Select
    End Sub
    好像是接收区没有清空,再给我发送数据的时候text1里边还是上一条数据。
      

  15.   

    zdingyun你好,你看能不能这样,就是因为我同事是一条数据发3遍,间隔是60毫秒,能不能这样。我在Call Command2_Click前加一个延时的代码,只要延时达到200毫秒是不就可以把他后边发的2遍数据躲过去阿?
    如果能实现,你知道加什么延时代码吗,我从网上看了些都不知道怎么用。 
      

  16.   

    我在13楼处的代码完全能满足LZ的要求,甚至下位机的第二组3次数据与第一组的3次数据完全相同,它也只保存一次.
    至于LZ想把后边发的2遍数据躲过去,除非你能精确地接收到正确数据时关闭COM口和在第二组数据发送前打开COM口.但按你所想,最后可能COM口堵塞而是通信出错.
      

  17.   

    非常不好意思,我刚才发现我的代码里边多了一次调用Call Command2_Click,所以出了问题。谢谢你的帮助。但是我发现一个这个问题
    Select Case MSComm1.CommEvent
           Case comEvReceive
                inByte = MSComm1.Input
                For i = 0 To UBound(inByte)
                If Len(Hex(inByte(i))) = 1 Then
                    strData = strData & "0" & Hex(inByte(i))
                Else
                    strData = strData & Hex(inByte(i))
                End If
                Next
                Text1.Text = strData
                Text17 = Len(strData)            '以下写符合通信协议规定的判断代码处理接收数据
                If Mid(strData, 1, 2) = "A5" And Len(strData) = 72 Then 
                    Dim j As Integer
                    Dim jyh As Long
                    For j = 1 To Len(strData) Step 2
                        jyh = jyh + Val("&H" & Mid(strData, j, 2))
                    Next
                    If jyh Mod 256 = 0 Then 
                        Text16.Text = "ok"
                        '进入数据处理
                dateSj = Mid(strData, 7, 2) & "-" & Mid(strData, 9, 2) & "-" & Mid(strData, 11, 2)       '日期显示
                Text2 = dateSj
                     。
                     。
                     。
    If strDataOld <> strData Then
       Text18 = "SAVE"
       Call Command2_Click
    Else
       Text18 = ""
       End If

       strDataOld = strData
       strData = ""
       End If
       End If
    End Select
    我在最后的text18文本框里看见显示的是空的,但是我看数据库了是存进了数据的,这是为什么阿?正常代表保存数据text18文本框应该显示的是“save”。
      

  18.   

    我看这句strDataOld = strData
    是过滤掉相同的第二第三帧数据
    保存得一帧数据后,显示"SAVE",接下来的帧是相同的话,就显示""你说看见是空,又数据存进了,会不会还是存进了同一组数据第二次第三次?我看zdingyun的代码写得挺好,自己按步调试一下吧:)
      

  19.   

    我想问个问题,利用.CommEvent事件驱动串口的方式,好像是中断的方式
    如果串口一直不停的读,不会不会引起中断过频烦,而系统停滞呢?本人没尝试过用.CommEvent事件,一般都用轮询方式,所以想借楼主空地提一下:)
      

  20.   

    我是自己刚开始学VB,所以很多都不知道,只能看上代码自己一点一点地看,zdingyun得代码很好,已能满足我的设想,就是有些地方我还是不明白,想问一下。
    If Mid(strData, 1, 2) = "A5" And Len(strData) = 72 Then 
                    Dim j As Integer 
                    Dim jyh As Long 
                    For j = 1 To Len(strData) Step 2 
                        jyh = jyh + Val("&H" & Mid(strData, j, 2)) 
                    Next 
                    If jyh Mod 256 = 0 Then 
                        Text16.Text = "ok" 

    这里如果结果不为0是不就返回重新接收了阿?
    还有就是如果就像楼上说的.CommEvent事件,像我这样数据是不定时发送的,这样在如果不用.CommEvent事件怎么样好呢?
      

  21.   

    zdingyun不来了吗,还想问些问题,那要不我再开个贴吧。