F8单步调试正常,但是直接运行时接收的数据就不对了。
下面是程序的一段While Not rs.EOF
send1 = CStr("AT+CMGF=1") + Chr(13) + Chr(10)'需要发送的命令字Do
Comm.Output = send1'发送第一条命令
Loop Until Comm.OutBufferCount = 0 '此处设置一个停顿,用来在一定时间内等待接收ok字符
iTime = CInt(txtWait.Text)
Timer1.Enabled = True
Call Timer1_Timer
DoEvents (窗体加载时timer的enable是false,此时启动timer,每秒执行一次,倒计时结束后才返回,继续下面的语句。但每次执行完一次后就返回到这里了,不再执行了,而我实际上需要一个循环,doevents加了和没加效果一样,是不是我加的地方不对?)
下面是程序的一段While Not rs.EOF
send1 = CStr("AT+CMGF=1") + Chr(13) + Chr(10)'需要发送的命令字Do
Comm.Output = send1'发送第一条命令
Loop Until Comm.OutBufferCount = 0 '此处设置一个停顿,用来在一定时间内等待接收ok字符
iTime = CInt(txtWait.Text)
Timer1.Enabled = True
Call Timer1_Timer
DoEvents (窗体加载时timer的enable是false,此时启动timer,每秒执行一次,倒计时结束后才返回,继续下面的语句。但每次执行完一次后就返回到这里了,不再执行了,而我实际上需要一个循环,doevents加了和没加效果一样,是不是我加的地方不对?)
定义个窗体变量 delay
dim delay as boolean然后改成这样看看
delay=true
iTime = CInt(txtWait.Text)
Timer1.Enabled = True
do while delay
DoEvents
loop'timer事件里面设置delay=false
private sub iTime_timer()
delay=falseend sub
For i = 1 To 5000
DoEvents
Next i
你的textwait写了多少
Dim delay As BooleanPrivate Sub Command1_Click()
Timer1.Interval = 5000
Timer1.Enabled = True
delay = True
Do While delay
DoEvents
Loop
MsgBox "delay ok"
End SubPrivate Sub Timer1_Timer()
delay = False
Timer1.Enabled = False
End Sub看我这一段 在一个窗体上放一个timer 设置enable=false
然后点击command1 会在5秒以后msgbox
不过,要是一定要用延时函数的话到可以:
Private Sub Relate() '延时函数
ct = Timer
While Timer - ct < 0.05(自己定义要延长的时间 单位/秒)
DoEvents
Wend
Private Sub Delay(ByVal lngmSec As Long)
Dim lngStartmSec As Long
lngStartmSec = GetTickCount
Do While GetTickCount - lngStartmSec <= lngmSec
DoEvents
Loop
End Sub
第一条命令发出后开始等待接收命令,比如3秒钟,时间到了还没有收到返回的命令就放弃,开始向下一个目标发送命令,如果收到返回的命令无论等待时间是否到都继续发送第二条命令。
我用单步执行的时候,如果收到了返回命令那么程序可以正常执行,但是如果没收到返回命令,程序只是执行了一次Timer事件就返回了,并没有象我所设计的那样循环。
我现在试了几种延时的方式,效果都不是很好,想请教一下有没有比较可靠,速度也比较快的方式。
部分代码如下:'先从数据库中提取flags=1也就是需要呼叫的手机号
sql = "select tel from ip where flags=1"
Set rs = gcn.Execute(sql)
While Not rs.EOF'需要发送的命令字
send1 = CStr("AT+CMGF=1") + Chr(13) + Chr(10)
send2 = CStr("AT+CMGS=") + "" & Trim(rs!tel) & "" + Chr(13) + Chr(10)
send3 = CStr("ADRES") + Chr(&H11) + Chr(&H7A)
send4 = CStr("IP") + "" & txtIP.Text & ""'发送第一条命令
Comm.Output = send1'此处设置一个停顿,用来在一定时间内等待接收ok字符'这是第一种方法,设置delayTime标志,收到返回命令或者倒计时结束了就将其设为false,但是他的反应速度好象比较慢,本机测试,链路通的情况下,40条命令(每条命令都不长)需要35秒时间,而且最重要的,在数据发送过程中,我没法停止,即便我把程序关掉了,他仍然在运行,必须等他运行完了,我单击VB中的结束按键他才停,虽然我已经在UnLoad事件中写了Timer1.enabled=falsedelayTime = True
iTime = CInt(txtWait.Text) '设置的等待回应时间
Timer1.Enabled = True
Call Timer1_Timer
Do While delayTime
DoEvents
Loop'第二种方法,不能使用,程序就象死机一样
'Sleep (1000)'第三种方法
'Delay (1500)'Delay的定义(写在这里以便阅读)
'Private Sub Delay(ByVal lngmSec As Long)
'Dim lngStartmSec As Long
'lngStartmSec = GetTickCount
'Do While GetTickCount - lngStartmSec <= lngmSec
'DoEvents
'Loop
'End Sub
'此处用来判断返回是因为接收到了ok字符还是等待时间到了
'如果接收到了ok字符,那么向该手机发送下一条命令,否则数据库指针
'下移一条,向下一个手机发送第一条命令If flags = 0 Then '超时未收到OK字符
List1.AddItem "未收到手机" & Trim(rs!tel) & " 的返回信息,现在向下一个手 机发送命令"
GoTo NextI '数据库指针下移一个Else '收到OK字符
flags = 0 '将flags 清0以免与第二次OK回应混淆
List1.AddItem "手机" & Trim(rs!tel) & " 第一次返回OK"
End IfComm.Output = send2 '发送第二条命令'等待处理同第一条命令'将该手机连接成功标志位置为1
sql = "update ip set flags=0 where tel='" & sDel & "'"
sqlSuccess = "update ip set connectTel=1 where tel= '" & Trim(rs!tel) & "' "
Set rsSuccess = gcn.Execute(sqlSuccess)NextI:
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
Set rsSuccess = Nothing'timer事件
Private Sub Timer1_Timer()
Dim Buffer As Variant
iTime = iTime - 1
Do While Comm.InBufferCount <> 0 '从缓冲区中读数据
DoEvents
Buffer = Comm.Input
If Buffer = "ok" Then
flags = 1
delayTime = False
Timer1.Enabled = False
Exit Sub
End If
Loop
If iTime = 0 Then
flags = 0
delayTime = False
Timer1.Enabled = False
Exit Sub
End If
End Sub
当一个函数已通过 DoEvents 放弃控制时,可相当安全地再次调用函数。例如,下一过程将检测质数并用 DoEvents 语句周期地启动其它应用程序处理事件:Function PrimeStatus (TestVal As Long) As Integer
Dim Lim As Integer
PrimeStatus = True
Lim = Sqr(TestVal)
For I = 2 To Lim
If TestVal Mod I = 0 Then
PrimeStatus = False
Exit For
End If
If I Mod 200 = 0 Then DoEvents
Next I
End Function该代码中每重复 200 次就调用一次 DoEvents 语句。这样一来,当该环境的其余部分对事件作出响应时,只要有必要,PrimeStatus 过程就可继续计算。考虑在调用 DoEvents 期间发生的事情。在其它窗体和应用程序处理事件时将暂停执行应用程序代码。这些事件之一有可能是一个按钮单击操作,它将再次启动 PrimeStatus 过程。这将导致重新进入 PrimeStatus 过程的,但是,因为在函数每次出现时,堆栈都为其参数和局部变量分配了空间,所以重入不会引发冲突。当然,如果过多调用 PrimeStatus,则可能出现“溢出堆栈空间”错误。如果 PrimeStatus 使用或改变模块级变量或全局数据,情况就会完全不同。此时,在 DoEvents 能够返回之前执行 PrimeStatus 的另一个实例,这将导致模块数据或全局数据的值完全不同于它们在调用 DoEvents 之前的值。于是,PrimeStatus 的结果将会难以预料。你的Timer事件函数就会出现函数没有被返回而出现多次调用的情况。'部分代码修改如下:
发送第一条命令
Comm.Output = send1
lngTime=CLng(txtWait.Text)
Dim lngStartmSec As Long
Dim Buffer as Variant
lngStartmSec = GetTickCount
Do While GetTickCount - lngStartmSec <= lngTime
If Comm.InBufferCount<>0 Then
Buffer=Comm.Input
If Buffer="ok" Then
'加入处理程序
Else
'加入处理程序
End If
Exit Do
End If
DoEvents '重点说明:如果VB能方便实现安全的多线程,那么在后台线程实现整个发送代码很方便且不影响界面线程。正是由于VB的缺陷,使得你在界面响应和后台处理上难以平衡,从而导致你的代码出现问题。还是建议在VB中尽量避免使用DoEvents语句,因为你把控制权交给系统后对应用程序就失控了,所以结果就很难预料。
Loop
'将该手机连接成功标志位置为1
Comm.Output = send2 '发送第二条命令
Dim tmpTime As Double tmpTime = Timer
If tmpTime + SleepTime >= 86400 Then
tmpTime = tmpTime - 86400
End If
Do While (Timer - tmpTime) < SleepTime
DoEvents
Loop
End Sub