回 帖 发 新 帖 刷新版面

主题:[原创]do while语句的应用?

怎样do while语句控制多个条件?
   比如:变量buf是字符串型,如果它左边的第一位不是“=”,并且它的长度不为9,
(left(buf,1)<>"="and len(buf) <> 9)就进行循环,如果它左边的第一位是“=”,并且它的长度为9,就退出循环!
      我这样写的程序:
                     do
                        if left(buf,1)<>"="and len(buf) <> 9 then
                           text1.text = ""
                           buf = ""
                           buf = msc.input
                        else
                            exit do
                      loop
           这样写对吗?我运行了几次,好象逻辑上不对!有没有好的办法,请高手帮忙!

回复列表 (共33个回复)

11 楼

天!
这么生气啊?
不回自己加一副括号?

你运行下面的代码要不成立,我就不再写vb代码了。
不过你要没有在窗体上放置command1的话,可不要怪我!
Dim xing, ming, xingbie, nianling

Private Sub Command1_Click()
i = 0
Do While ((xing(i) = "zhang" And xingbie(i) = "nan" Or xing(i) = "li" And xingbie(i) = "nv") And i < 10)
Print xing(i); ming(i), xingbie(i), nianling(i)
i = i + 1
Loop
End Sub

Private Sub Form_Load()
Me.AutoRedraw = True
xing = Array("zhang", "wang", "li", "zhao", "qian", "sun", "zhou", "wu", "zheng", "han", "chen")
ming = Array("dashan", "xiaosi", "wuer", "huda", "jiawu", "liuer", "qier", "baer", "jiuer", "shier", "lingling")
xingbie = Array("nan", "nan", "nv", "nv", "nan", "nan", "nv", "nv", "nv", "nan", "nan")
nianling = Array(12, 15, 13, 16, 12, 14, 16, 12, 13, 15, 16)
End Sub

12 楼

对不起!没有生气,是我在往上面写的时候语气重了一些,无意的,请不要在意!
我加了括号!
Option Explicit

Dim ary() As String
Dim buf As Variant
Dim i As Integer

Private Sub Form_Load()
MSC.CommPort = 2
MSC.Settings = "1200,n,8,1"
MSC.InBufferCount = 0
MSC.OutBufferCount = 0
MSC.InputLen = 9
MSC.RThreshold = 9
MSC.PortOpen = True
End Sub

Private Sub Form_Unload(Cancel As Integer)
If MSC.PortOpen = True Then MSC.PortOpen = False
End Sub

Private Sub MSC_OnComm()
Select Case MSC.CommEvent
       Case comEvReceive
       buf = MSC.Input
       Do While (Left(buf, 1) <> "=" And Len(buf) <> 9)
            txtReceive.Text = ""
            buf = ""
            buf = MSC.Input
        Loop
        txtReceive.Text = buf
        Case comEvSend
End Select
End Sub
仪表所发送过来的数据是以“=”开始的9位数据,比如=51.07000=51.07000=51.07000=……,在这里用的do while … loop语句是为了防止出现乱码,如果(Left(buf, 1) <> "=") And (Len(buf) <> 9)将进行循环等待,是为了保证给txtReceive.Text所赋值是以“=”开始的9位数据!
     以上这两种方法都不行,不知那儿错了,是不是我哪儿有逻辑方面的错误?请您指正,如果您有更好的办法,请您提醒一下!谢谢!

13 楼

Do While MsgBox("abc", vbYesNo, "YES") = vbYes And MsgBox("DDD", vbYesNo, "YES") = vbYes
    MsgBox ("KKK")
Loop

从这个程序可以看出来,
VB并没有优化的去判断条件,
虽然是 and 条件,
但仍将所有条件值从左到右都计算出结果后再进行 and 运算
未免有点浪费,而且失去了一些容错的判断优势.

在VFP里则不同,
会从左到右判断,而且会参照逻辑运算的符号,
如果是 or ,第一个条件成立了就不会去计算第二个条件了.
同样道理, and 的第一个条件不成立也就不会再去管第二个条件了.
这时候,一些复合条件以及容错表达式就得到了很好的处理.
比如:
do while vartype(T1)=2 and T1+T2 > 36 诸如此类

VB例子:
[quote]T1 = 9
T2 = 31
Do While VarType(T1) = 2 And T1 + T2 > 36
    MsgBox ("KKK")
    T1 = "ABC"
Loop[/quote]

VFP例子:
[quote]T1=9
T2=31
DO WHILE VARTYPE(T1)="N" AND T1+T2>36
    MESSAGEBOX("KKK")
    T1="ABC"
ENDDO[/quote]

而在楼主的程序里,
已经设定了接收长度为9
好像已经没有必要再去检查了.
当然,多此一举也未尝不可.
[quote]Do
   buf = MSC.Input
Loop Until Left(buf, 1) = "=" And Len(buf) = 9
txtReceive.Text = buf[/quote]
我觉得这样子已经足够使用了.
如果说不能正常接收到数据,
不妨以调试方式来检查一下数据,
[quote]Do
   buf = MSC.Input
[color=ff00ff]   Debug.Print buf;"/";[/color]
Loop Until Left(buf, 1) = "=" And Len(buf) = 9
txtReceive.Text = buf[/quote]

14 楼

而且你的程序里好像只有一个条件,
用 If MSC.CommEvent=comEvReceive Then 就可以了,
没有必要用 Select Case

15 楼

谢谢moz,谢谢你的提醒和帮助。

16 楼

Do
   buf = MSC.Input
   Debug.Print buf;"/";
Loop Until Left(buf, 1) = "=" And Len(buf) = 9
txtReceive.Text = buf
我用您这个程序调试了一下,如果buf的第一个数据能够满足Left(buf, 1) = "=" And Len(buf) = 9,则运行正常,如果buf的第一个数据不能满足Left(buf, 1) = "=" And Len(buf) = 9,好象后面对buf的重新赋值都不能满足Left(buf, 1) = "=" And Len(buf) = 9,就进入了死循环。
  真的不知怎样写这段代码了?有没有好的方法给提醒一下?

17 楼

假如接收字节出现了错位的话,
可以全部接收过来检测一下,
但因为你的程序是使用过程来接收的,
所以丢失的数据怎么处理你自己考虑一下.

[quote]Do
   buf = buf & MSC.Input
Loop Until len(buf)-instr(buf,"=")>7
txtReceive.Text = mid(buf,instr(buf,"=")+1,8)[/quote]

18 楼

为避免死循环,
循环体最好还是加多两行
T1=T1+1
if T1>10000 then exit do 
或者检测时间变化也行.比如设定十秒钟之类的.
T1=timer()
do......
loop until  ..... or abs(timer()-T1)>10

19 楼

19楼的你有病呀

20 楼

谢谢moz,
为避免死循环,
循环体最好还是加多两行
T1=T1+1
if T1>10000 then exit do 
加上以后就好了,这样是不是就大大减少数据错位的概率了?

我来回复

您尚未登录,请登录后再回复。点此登录或注册