精品主页 | 软件下载 | 系统下载 | 精品导航| 精彩图片 | 转帖工具 | 版主申请 | 影视下载
发新话题
打印

VB应用程序中实现查找和替换功能

VB应用程序中实现查找和替换功能

  


                   一、前言


  尽管Visual Basic并不是我最喜欢的开发工具,但我喜欢它简单而又丰富的库集。每当开发一个需要处理大量文本数据的应用程序时,需要具有拼写错误纠正功能,例如,微软的Word程序,当运行"拼写检查"时,将提供给你一个改正错误的机会(尽管是建议),它同时也提供了"查找替换"工具,用以进行用户定义的单词替换。这篇文章我将解释如何在VB应用程序中实现"查找替换"功能。


  二、前提条件


  在解释代码的时候,我假定读者朋友们已经有使用Visual Basic的经验,熟悉Visual Studio开发环境中各种内置的控件及库函数(尽管我使用的不多)。我已经尝试着尽可能地简化程序代码,用不了多久你就可以明白程序的逻辑。如果想对一些库函数(如参数,语法)进一步详细地理解,可以参阅MSDN。图一是程序运行后的效果图:







三、基础工作


  首先创建一个标准的EXE类型的VB工程,将默认窗体更名为frmMainForm ,在默认窗体上增添一个菜单,具体设置如下(符号"&"用于加速键,单词mnu后的名字用来说明菜单项的名字(在代码中使用)):


&Edit

...&Find and Replace mnuFindandreplace

E&xit mnuExit


  向默认窗体添加一个TextBox控件,命名为txtClientArea。使用鼠标调整控件位置和尺寸,使它覆盖窗体的整个客户区,在属性窗口将这个TextBox控件的 MultiLine属性设置为"True"。


  使用Project > Add Form菜单向工程中添加另外一个窗体,将这个窗体命名为"frmFindReplace",并在属性窗口中将它的BorderStyle属性设置为"4 - FixedToolWindow"。现在,添加两个TextBox控件,并分别命名为"txtSearchTerm"和"txtReplaceWithString"。添加一个复选框,命名为chkCaseSense。最后,添加一个命令按钮控件,命名为"cmdReplace"。


  


                  


  在frmMainForm窗体中添加如下代码:


Private Sub mnuExit_Click()

 End

End Sub


Private Sub mnuFindandreplace_Click()

 frmFindReplace.FindnReplace txtClientArea

End Sub




从上面代码中可以非常明显地看出, 当点击Exit菜单时,我们想终结应用程序,当点击"Find and Replace"菜单时,想通过共用接口frmFindReplace及FindnReplace()方法来激活frmFindReplace窗体。这个公用的接口使查找算法具有普遍性,使用这个接口时,需要提供一个TextBox作为参数(在这里面,搜寻将被执行)。通过使用你自己的TextBox的名字来代替txtClientArea的名字,可以在多个文本框内执行"查找替换"功能,而不用更改代码。"查找和替换"的实现代码主要是在frmFindReplace窗体内,这个模块的代码如下:





' This variable is used for making the algorithm generic.

Dim txtClient As TextBox


' This method is the public interface to SnR functionality.


Public Sub FindnReplace(ByRef Tb As TextBox)

 Set txtClient = Tb

 Me.Show , txtClient.Parent

End Sub


Private Sub cmdReplace_Click()

 Dim CaseSense As Integer

 Dim SourceText As String

 Dim SourceTextCopy As String

 Dim Cnt As Integer


 ' Check for the case sensitivity options

 If (chkCaseSense.Value = vbChecked) Then

  CaseSense = 0

 Else

  CaseSense = 1

 End If


 ' One contains the original text and another contains replaced

 ' (updated) one.

 ' Used to check whether a replacement was done or not.

 SourceText = txtClient.Text

 SourceTextCopy = SourceText


 If Len(SourceText) = 0 Then

  Exit Sub

 End If


 On Error GoTo ErrHandler

 Dim SearchTermLen As Integer

 Dim FndPos As Integer


 SearchTermLen = Len(txtSearchTerm.Text)

 ' Search from the begining of the document.

 Cnt = 1


 ' This is endless loop (terminated on a condition checked inside

 ' the loop body).

 While (1)


 FndPos = InStr(Cnt, SourceText, txtSearchTerm.Text, CaseSense)

 

 ' When a match is found, replace it appropriately.

 If (FndPos > 0) Then

  SourceText = ReplaceFun(SourceText, FndPos, Len(txtSearchTerm.Text), txtReplaceWithString.Text)

  Cnt = FndPos   SearchTermLen

 Else

  Cnt = Cnt   1

 End If


 ' Whether a replacement was done at all or not

 If (Cnt >= Len(SourceText)) Then

  txtClient.Text = SourceText

  If (SourceTextCopy <> SourceText) Then

   MsgBox "Finished replacing all occurrences.", vbInformation   vbOKOnly, "Replaced All"

  Else

   MsgBox "No matching strings found. No text replaced.", vbInformation   vbOKOnly, "No Replacement"

  End If

  Unload Me

  Exit Sub

 End If

 ' Else Restart from henceforth

 Wend

 Exit Sub


ErrHandler:

 Response = MsgBox("An error ocurred while searching. Inform the developer with details.", _

vbExclamation   vbOKOnly, "Error Searching")

End Sub


Private Sub Form_Load()

 ' Default SearchTerm must be the one selected by the user in

 ' MainForm

 If Len(txtClient.SelText) <> 0 Then

  txtSearchTerm.Text = txtClient.SelText

 End If

End Sub


Function ReplaceFun(Source As String, FromPos As Integer, _

Length As Integer, StringTBReplaced _

As String) As String

 ' Replaces a source string with new one appropriately

 Dim ResultStr As String


 ResultStr = Left(Source, FromPos - 1)

 ResultStr = ResultStr & StringTBReplaced

 ResultStr = ResultStr & Right(Source, Len(Source) - FromPos - Length   1)


 ReplaceFun = ResultStr

End Function


Private Sub txtReplaceWithString_Change()

 Call EnableDisableReplaceButton

End Sub


Private Sub txtReplaceWithString_GotFocus()

 ' Select the contents of the textbox

 If Len(txtReplaceWithString.Text) <> 0 Then

  txtReplaceWithString.SelStart = 0

  txtReplaceWithString.SelLength = Len(txtReplaceWithString.Text)

 End If

End Sub


Private Sub txtSearchTerm_Change()

 Call EnableDisableReplaceButton

End Sub


Private Sub EnableDisableReplaceButton()

 If Len(txtSearchTerm.Text) <> 0 _

  And Len(txtReplaceWithString.Text) <> 0 Then

  cmdReplace.Enabled = True

 Else

  cmdReplace.Enabled = False

 End If

End Sub


Private Sub txtSearchTerm_GotFocus()

 ' Select the contents of textbox

 If Len(txtSearchTerm.Text) <> 0 Then

  txtSearchTerm.SelStart = 0

  txtSearchTerm.SelLength = Len(txtSearchTerm.Text)

 End If

End Sub


  


                  


  四、代码说明


  公用接口SearchnReplace的"查找替换"算法带有普遍性,使用这种方法,"查找替换"功能可以在任何应用程序中实现,而不用更改frmFindReplace的代码。只是在调用公用接口的地方需要做一些小的改动。


  "查找和替换"代码在cmdReplace_Click()过程与ReplaceFun() 函数下,让我们从cmdReplace_Click()过程开始。


  首先,变量CaseSense用于跟踪用户的选择,是否是大小写敏感,如果用户选择大小写敏感的话,它的值设置为0,否则,设置为1。变量SourceText和SourceTextCopy用于保存frmMainForm窗体中 txtClientArea的内容(或者是用户在主窗体中为TextBox提供的内容,对于本程序来说,它就是txtClientArea),两个变量保存同样的内容将在下面进行解释(一个是临时变量)。变量Cnt用来跟踪文档的结束,当重新从文档开始处进行"查找替换"时它将非常有用。这个变量含蓄地说明了当前光标的位置,下次的"查找替换"将从这个位置开始。


  主要的算法在while循环内,只要替换或是源TextBox被扫描时,这个循环都将被激活。


  第二步,我使用了InStr()库函数,它将从第一个参数规定的位置处开始搜索,如果在第二个参数字符串中发现与第三个字符串相匹配的子串,将返回该子串的位置。最后一个参数是大小写敏感选项。


  InStr()函数的返回值传递给FndPos,如果在源文档中发现了所要查找的字符串,这个值将大于0,否则将返回一个0值。在紧接着的IF语句中,首先替换SourceText变量,然后是通过FndPos   SearchTermLen语句修改Cnt变量,这是必须的, 因为下一次的"查找和替换"要从新的位置开始。另一方面,在Else部分,Cnt变量加一,说名查找和替换要从下一个字符开始。紧接着的几个语句用来通知用户查找结果,它们非常容易理解,也非常容易实现。可以直接跳过它们。


  最后,ReplaceFun()函数进行实际的替换工作,它从源字符串的左边开始,挑选出所有的字符,直到发现所搜索的字符串位置处为止。紧接着,StringTBReplace被添加到结果的后面,它将代替所匹配的源字符串。最后,所有的保留的源字符(排除所要更换的子字符串)被添加到这个结果中去,并作为结果返回。


五、结论


  有很多方法来实现这一功能,但我认为我所使用的方法是最简单也是最直接的,通过例子程序,你可以在应用程序中实现自己的"查找替换"功能。

TOP

发新话题