下面的一段代码,用的是RichText控件,实现的是RichText文本中字符串的全部查找并替换功能,在VB中调试时一点错误都没有,但是一旦编译成可执行文件后,执行这一段代码时却总是会出现“运行时错误5,无效的过程调用或参数”的错误信息,然后才出现msgbox的搜索完毕的对话框,点确定后整个可执行文件异常结束!那个错误处理根本就不管用,请教各位大虾这是怎么回事?!
Private Sub cmdReplaceAll_Click()
    On Error GoTo er1:
    Dim s1 As String, s0 As String, s2 As String, t As Integer
    t = 0
    s1 = txtS1.Text
    s2 = txtS2.Text
    curN = 0
    Dim n As Integer
    Do
        s0 = frmMain!txtCode.Text
        n = InStr(curN + 1, s0, s1)
        If n <> 0 Then
            frmMain!txtCode.SelStart = n - 1
            frmMain!txtCode.SelLength = Len(s1)
            frmMain!txtCode.SelText = s2
            t = t + 1
            curN = n - Len(txtS1.Text) + Len(txtS2.Text)
        Else
            Me.Hide
            MsgBox CStr(t) + "处搜索替换完毕!", vbInformation + vbOKOnly, "完成"
            Unload Me
            Exit Sub
        End If
    Loop
    Exit Sub
er1:
    Me.Hide
    MsgBox "未知错误!", vbExclamation + vbOKOnly, "错误"
    Unload Me
End Sub

解决方案 »

  1.   

    另外,既然是ReplaceAll,直接用Replace函数不好吗?
      

  2.   

    无效的过程调用或参数你循环里涉及到的过程就一个INSTR,那个LEN是不会有问题的,所以INSTR的第一个参数非常可疑,你最好每次执行都把该参数的内容显示出来看看。
    另外要实现你所想要的功能,上述代码似乎复杂化了,而且好象在结束后并不能保证全文不再出现要被替换的串。
      

  3.   

    同意楼上,用Replace函数
    还有do...loop是不是少了条件(condition)?
      

  4.   

    估计是frmMain窗体的代码有问题,你先把frmMain_Load里不相干的代码注释掉,再试试
      

  5.   

    我从来都没有这样写过,
    frmMain!txtCode.Text这样的,可能我說的不對.
    frmmain.txtcode.text
      

  6.   

    To rainstormmaster(暴风雨 v2.0):
    已试过,编译为P代码也不行;另外由于该窗体中除了“全部替换”外还有“替换”按钮(替换时也出现同样错误),无法用Replace来实现。To province_(雍昊):
    应该不是这个参数的问题,因为在VB环境中调试时根本不会出现错误,但是编译为exe以后执行与调试时相同的替换操作时就会出错,而且错误处理也不会被执行,这是我最想不通的地方!代码或许啰嗦点,因为这个替换窗口是总在最前的,不得不先hide再msgboxTo faysky2():
    frmmain本来就show着的啊,unload这个替换窗口后应该不会去执行frmMain_Load啊
      

  7.   

    curN = n - Len(txtS1.Text) + Len(txtS2.Text)
    这句有可能出现问题
    如当n为1时,len(txts1.text)为4,len(txts2.text)为3
    这时curn的结果就是-1
    当循环到n = InStr(curN + 1, s0, s1)这句时curN + 1=0
    OK,它出错了~~所以还是建议用replace函数好得多
      

  8.   

    你把代码中所有的InStr都用vba.instr代替试试
      

  9.   

    不过,说实话,考虑到系统开销,我是不建议用instr的,这不是instr本身的问题,而是利用instr函数,就不可避免的要访问richtextbox的text属性,当richtextbox内容较少的时候可能还不明显,但是,当richtextbox的内容很多时,你会发现,使用instr是多么愚蠢的一件事情
      

  10.   

    谢谢朋友们的参与,不管这段代码有没有bug,我现在最不明白的还是这个问题:为什么对于相同的替换操作,在VB调试环境中不会出错,而编译成exe文件后就会出错?!
    比如我打开一个3K左右的文件,把里面的0全部替换成1,在VB环境中会顺利替换成功,提示11处被替换,但是编译成exe文件以后,同样打开这个文件,把0全部替换成1,就会出现“运行时错误5,无效的过程调用或参数”的错误信息,确定后才出现11处被替换的提示,而此时点击确定按钮后会退出整个可执行文件!
      

  11.   

    关键在这里
    n = n - Len(txtS1.Text) + Len(txtS2.Text)
    下一次的搜索开始位置
    Option Explicit
    Private Sub cmdReplaceAll_Click()
        On Error GoTo er1:
        Dim s1 As String, s0 As String, s2 As String, t As Integer
        t = 0
        s1 = txtS1.Text
        s2 = txtS2.Text
        
        Dim n As Integer
        Do
            s0 = Me!txtCode.Text
            n = InStr(curn + 1, s0, s1)
            If n <> 0 Then
                Me!txtCode.SelStart = n - 1
                Me!txtCode.SelLength = Len(s1)
                Me!txtCode.SelText = s2
                t = t + 1
                n = n - Len(txtS1.Text) + Len(txtS2.Text)
            Else
                Me.Hide
                MsgBox CStr(t) + "处搜索替换完毕!", vbInformation + vbOKOnly, "完成"
                Unload Me
                Exit Sub
            End If
        Loop
        Exit Sub
    er1:
        Me.Hide
        MsgBox "未知错误!", vbExclamation + vbOKOnly, "错误"
        Unload Me
    End Sub
      

  12.   

    楼上朋友的代码也有问题:curN是一个窗体级的变量,用以存储替换完成的位置,使下次替换时从该位置往后进行,所以楼上朋友的n = InStr(curn + 1, s0, s1)。n = n - Len(txtS1.Text) + Len(txtS2.Text)肯定是不行的,把curn换成n也不行,会发生一个可捕获的错误。继续请教!!!撇开代码的问题不说,我始终搞不清的是:
    1、该段代码在VB的调试环境中无论怎样运行都不会发生错误,然而一旦编译成exe文件后就会出错,虽然执行的替换操作是一模一样的;
    2、运行exe文件时,当出现“运行时错误5,无效的过程调用或参数”的错误信息后,点“确定”后程序并不会立刻退出,而是继续往下运行,至出现 "xx处搜索替换完毕!"的对话框,点确定后整个程序才异常结束退出!
      

  13.   

    补充一句,我是在同一台计算机上操作的,并不是把软件复制或者安装到其他计算机以后出现这个错误,而是在同一台计算机上编译成exe以后就不行!
      

  14.   

    看了一下你的代码,因为你的Sub cmdReplaceAll_Click过程中有on error捕获错误,而“运行时错误5,无效的过程调用或参数”又是一个VB错误,所以我就没去仔细研究你的代码了,因为可以肯定,这个错误不是发生在这个过程中的!从你反映的现象看,我基本能断定这与MsgBox的运行机制有关,在IDE下VB收回消息处理权,是对所有窗体消息统一处理的,这样才能实现IDE下的可调试功能,MsgBox也是全局的,也就是说在它弹出时,IDE将不再处理所属其它窗体的消息,而在编译后则不同,不同窗体各自有自已的消息处理过程。这一点,可通过Timer事件试一下就知道了,调试时,当Msgbox弹出时Timer事件不会再发生,而编译后则照样会有Timer事件。从上面的分析,不难看出,在你的Msgbox弹出时一定发生了什么事件,而在这个事件的处理过程中你的代码不能正确执行,从而引发错误,VB崩溃,但崩溃前Msgbox的API调用已经发出,Windows会在VB错误对话框结束后继续弹出你的对话框。但VB已不在了。那这个事件是什么呢?最大的疑点就是你在frmMain的Form_Activate事件过程中有代码,而这个代码在Msgbox弹出时不能正确执行,我想十有八九是一个SetFocus调用^_^若我分析的正确,你只需在Form_Activate事件过程加上一句On Error Resume Next,即可搞定!
      

  15.   

    楼主大哥
    小弟不懂VB,来此学习
    看到你的问题想试着回答一下,错了表怪我VB代码有没有错或是其它的什么小弟就不知道了
    不过你的错误我是很熟悉的
    检查一下你的程序里有没有连接数据库的地方吧,不是连接数据库的方法错误,就是有对数据库进行操作时传递的参数错误
    特别是SELECT操作时,可能某个参数的值为NULL,将会报此错误
    不是的话表拍我
      

  16.   

    To SlamAI(摒弃AI):
    我的这个程序没有涉及到数据库操作,但是非常谢谢你的参与!To homezj(小吉):
    你真神了,分析得非常正确,我正是在frmMain的Active()事件中有个txtCode.SetFocus导致了这个错误,问题终于解决了,非常感谢你的解答,既解决了我多日来的难题,又让我学到了一个新知识!