Virtual Developer Workshop: Containerized Development with Docker
Although Visual Basic is not one of my favorite languages, I like its simplicity and rich set of libraries. Many times when developing an application that deals with an enormous amount of textual data, you need a functionality that makes the job of correcting misspelt words easier. Microsoft Word, for example, when running a "Spell Check" gives you an opportunity to correct a wrongly typed word (through suggestions). It also facilitates a "Search and Replace" tool that can be used for user-defined word replacments. Here in this article, I am not going to give you details about implementing a dictionary; rather, I focus on how this feature (find and replace) can be implemented in a VB application.
While I explain the code, I assume that you have worked in Visual Basic and are familiar with various in-built controls and library functions (I have used a few of them) that are available from within the Visual Studio IDE. I have tried to keep the code as simple as possible, and you will be able to understand the logic in a while. If you want to know more about some library functions (such as its syntax, params, and so forth) visit MSDN online.
Create a Standard EXE VB project. Rename the default form as frmMainForm. Add a menu to the default form with the following details (the & sign is used for accelerator key and the name preceded with word mnu depicts menu-item's internal name (used in code)),
&Edit ...&Find and Replace mnuFindandreplace E&xit mnuExit
Add a TextBox control to this form and rename it as txtClientArea. Stretch and adjust it with mouse so that it covers entire client-area of the form. Set this TextBox's MultiLine property to True from the Properties window.
Add another form to this project (from Project > Add Form). Rename this form as frmFindReplace and set its BorderStyle property to 4 - FixedToolWindow from the Properties window. Now, add two TextBox controls and rename them as txtSearchTerm and txtReplaceWithString respectively. Add a checkbox control and rename it as chkCaseSense. Finally, add a CommandButton to the form and rename it as cmdReplace.
In the frmMainForm, you will write the following code:
Private Sub mnuExit_Click() End End Sub Private Sub mnuFindandreplace_Click() frmFindReplace.FindnReplace txtClientArea End Sub
It is apparent from the above code that when the user clicks on the "Exit" menu item we want to terminate the application and when he selects the "Find and Replace" submenu item from the "Edit" menu, you want to activate the frmFindReplace form by the means of calling public interface of frmFindReplace; in other words, FindnReplace(). This public interface allows the search algorithm to be generic. With this interface, you provide your TextBox as an argument (in which the search is to be performed). By replacing the name txtClientArea with your own TextBox's name, you can invoke the same search-replace functionality for as many TextBoxes (as well as many times) as desired, without repeating the search code. The main code of "Search and Replace" is, however, placed under the frmFindReplace form only. The code for this module follows.
' 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