خوب توي اين قسمت ميخواهيم توانايي جستجو را به برنامه مون اضافه كنيم
خوب الگوريتم اين جستجو چيزي شبيه خطوط زير است
- گرفتن اطلاعات از كاربر يعني عبارت جستجو شونده
- صدا زدن تابع و يا توابعي كه اين عمل جستجو را انجام ميدهد
- انتخاب قسمت پيدا شده يا نمايش پيدا نشدن عبارت جستجو شده
خوب براي گرفتن اطلاعات از كاربر ما دو گزينه داريم
- استفاده از inputbox
- ايجاد فرم ثانويه
در صورت استفاده از inputbox ما يكسري از توانايي هايمون رو براي طراحي از دست ميدهيم چون اين فرم درخواست آماده است پس بعضي از گزينه ها را مثل checkbox نميتونيم بروي آن ظاهر نماييم
لذا ما از روش دوم استفاده ميكنيم
براي اين كار از منوي project گزينه Add form را انتخاب ميكنيم خواص زير رو به ترتيب برا اين فرم ست ميكنيم :
کد:
BorderStyle = 3 'Fixed Dialog
Caption = "Find"
ClientHeight = 945
ClientLeft = 45
ClientTop = 435
ClientWidth = 5580
KeyPreview = -1 'True
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 945
ScaleWidth = 5580
ShowInTaskbar = 0 'False
Visible = 0 'False
خوب حالا يك كامبو باكس به نام txtFind اضافه ميكنيم با اين خصوصيات ( تمامي اشياء زير به فرم جديد اضافه ميشوند)
کد:
Height = 315
Left = 1440
TabIndex = 1
Top = 60
Width = 3975
خوب سه commandButton درست ميكنيم با اين خصوصيات
اولي به اسم BtnNext با خصوصيات
کد:
Caption = "Find &next"
Enabled = 0 'False
Height = 375
Left = 1440
TabIndex = 4
Top = 480
Width = 1215
و بعدي به نام BtnCancel با خصوصيات
کد:
Caption = "&Cancel"
Height = 375
Left = 2760
TabIndex = 3
Top = 480
Width = 1215
و بعدي به نام BtnFind با خصوصيات
کد:
Caption = "&Find"
Height = 375
Left = 120
TabIndex = 2
Top = 480
Width = 1215
و همچنين يك CheckBox با نام ChkCase و خصوصيات
کد:
Caption = "Case &match"
Height = 255
Left = 4200
TabIndex = 5
Top = 480
Width = 1815
و يك Label با نام Label1 و خصوصيات
کد:
Caption = "Find What:"
Height = 255
Left = 120
TabIndex = 0
Top = 120
Width = 1095
خوب frmfind ما كامل شد و تمامي اشيا مورد نظرمون بهش اضافه شد.خوب حالا با زدن دكمه save از نوار ابزار استاندارد اين فرم رو ذخيره ميكنيم .
خوب فرم ما همچين شكلي ميشود
خوب ما براي ارتباط متغيير ها مورد مصرف در يك فرم به فرم ديگر احتياج به يك مكان عمومي داريم براي اين كار از Module استفاده مي كنيم . از منوي Project گزينه Add Module را ميزنيم و به نام My_func و آن را ذخيره ميكنيم
براي ذخيره نمودن روي My_Fun در پنجره Project Explorer كليك راست كرده و گزينه save را انتخاب ميكنيم و بعد ان را با نام My_Func.Bas ذخيره منماييم
تا اينجا ما يك فرم جديد ساختيم كه يك شيء edit داره و چند دكمه كه هر كدوم براي كاري در نظر گرفته شده اند
نكته :به هر شيء كه ما توش توانايي تايپ داشته باشيم شئ edit گفته ميشه
در فرم frmNotes:
يك منو با نام mnuFind و "Caption = "&Find را در منوي edit بعد از منوي paste توليد ميكنيم
همچنين روي tbrStandard توي فرم frmnotes كليك راست كرده و گزينه properties را ميزنيم و در تب بار buttons بعد از دكمه paste يك دكمه جديد به نام Find قرار مي دهيم
براي اينكه ايكن آن را ست كنيم بايد ابتدا گزينه هاي كه imagelist در ارتباط هستند را از اين ليست جدا كرده و بعد ايكن مورد نظر را به ان اضافه كنيم و دوباره اشيائ مربوط را ه ان وصل كرده و سپس مقدار دهيم كنيم .
براي جدا سازي بروي tbrStandard كليك راست كرده و properties ان را ميگيرم و بعد سه گزينه پشت سرهم Imagelist ، disbleImagelist و HotImageList را به None تغيير داده و همين عمليات را بروي tbrFont انجام ميدهيم
بعد عكس مورد نظر را به Imagelist اضافه ميكنيم يعني find.ico و دوباره ارتباط ها را فعال مينماييم و مقادير را براي دكمه هاي اشياء
tbrStandard و tbrFont ست منماييم
روي همين بار دبل كليك كرده و درون كد هاش عبارت زير را بعد كد مربوط به دكمه paste اضافه ميكنيم
کد:
....
Case 7 'paste
mnuPaste_Click
Case 8 'Find
mnuFind_Click
End Select
خوب حالا روي منو ها فرم frmNotes رفته و گزينه find را انتخاب ميكنيم و كد زير را بهش اضافه ميكينم
کد:
'show frmfind
frmFind.Show
حالا اگر برنامه را اجرا كنيم و ازمنوي edit گزينه find را انتخاب كنيم بزنيم و حالا فرم اول يعني frmNotes را بنديم هنوز برنامه فعال مي ماند .چون هنوز يه فرم ما فعال است
براي رفع اين مشكل كد Form_Unloadفرم frmfind را به اين كد تغيير ميدهيم
کد:
Private Sub Form_Unload(Cancel As Integer)
If TextStatus And TextChanged Then
Dim res As VbMsgBoxResult
res = MsgBox("Text has changed, Do you want to save changes?", vbYesNoCancel + vbExclamation)
If res = vbCancel Then Cancel = True
If res = vbYes Then mnuSave_Click
End If
' exit program and all forms
End
End Sub
خوب در بيشتر موارد ما احتياج داريم كه كدي در ابتدا برنامه اجرا بشه و يك سري متغير هاي اوليه را مقدار دهي كنه
براي اين كار پيشنهاد من به شما توليد يك زير برنامه است كه اين كار را انجام ميده و هنگامي كه اولين فورم صدا زده شد ايت زير برنامه صدا زده بشه
براي اين كار روي جاي خالي از frmnotes دبل كليك ميكنيم و توي combo box زير برنامه ها گزينه load را انتخاب ميكنيم
حالا اسم تابعي كه ميخوايم صدا بزنيم رو به كدش اضافه ميكنيم زيربرنامه مون ميشه
کد:
Private Sub Form_Load()
' call this sub for set inital value
Initial
End Sub
اين زير برنامه بايد كجا باشه بهترين جا توي مدل My_funcf به اين صورت
کد:
' this sub use as intial vrible
Sub Initial()
FindStr ""=
FindLoc = 0
End Sub
راستي براي پيدا كردن يه عبارت و سرچ دوباره اون ما احتياج داريم محل كنوني گزينه سرچ شده مقدار سرچ شده را داشته باشيم لذا اين دوتا متغيير را در ابتداي مدول My_func تعربف ميكنيم ( زيرا بايد اين مقادير بايد براي هر دو تا فرم قابل رويت باشند بصورت عمومي تعريف شده اند)
کد:
' inital global varible
Public FindStr As String
Public FindLoc As Long
اگر برنامه را اجرا كنيد و فرم frmfind را صدا بزنيد و بعد برنامه اول را ببنديد ميبنيد كه مشكل مطرح شده در بالا حل شد
تا اينجا ما كدهاي لازم جهت سرچ را در فرم frmnotes ايجاد نمودايم
اما كدهاي فرم frmFind
ساده ترين كد كد مربوط به دكمه cancel است با زدن اين دكمه فرم دوم بايد از حالت نمايش خارج بشودپس كد مربوط ان ميشود
کد:
Private Sub BtnCancel_Click()
' if cancel button click hide this form
Me.Hide
End Sub
با تايپ عبارت و بعد زدن دكمه find يا Enter بايد اين عبارت به عبارتهاي قبلي Combo اضافه شود:
کد:
Dim dumm
' check if user enter some thing
If txtFind = "" Then Exit Sub
' add this search to combo box list for next user use
txtFind.AddItem txtFind.Text
براي اينكه دكمه enter نيز شبيه دكمه find عمل نمايد ميتوانيم از كد ذيل استفاده نماييم
کد:
Private Sub txtFind_KeyUp(KeyCode As Integer, Shift As Integer)
' check if user press enter for serached or not
If KeyCode = 13 Then BtnFind_Click
End Sub
خوب بعد از اضافه شدن اين عبارت به combo حالا بايد تابع صدا زده شود
تابع زير تايع سرچ ميباشد كه تمامي خطوط توضيح داده شده اند
کد:
' this function search Through richtext box we use in main form
' varible use is
' Findstring point to string to find
' start point to location of searched string we want to serch after that
' obj point to reached text that we want to found string in it
' matchBool point to varible that point Sensitivy of match case or not
Function SearchStr(FindString As String, Start As Long, obj As RichTextBox, MatchBool As Boolean) As Long
Dim dumm, Dummstr As String, DummFind As String
' set returned valur to false
' so we can exit function if any things is wrong
SearchStr = False
' check variable
If FindString = "" Then Exit Function
If obj.Text = "" Then Exit Function
' get obj text .so if matchbool is false so we can turend it to ucase
Dummstr = obj.Text
' get search text .so if matchbool is false so we can turend it to ucase
' and find all match without Sensitivy
DummFind = FindString
' turn find all or not
If Not MatchBool Then
Dummstr = UCase(Dummstr)
DummFind = UCase(DummFind)
End If
' find string
dumm = InStr(Start + 1, Dummstr, DummFind)
' if returned value is 0 then nothing found and exit sub
If dumm = 0 Then Exit Function
' set returned value to where match start
SearchStr = dumm
End Function
اين تابع در مدول My_func اضافه ميشود تا همه فرم ها به ان دسترسي داشته باشند.
در صورتي كه عبارت مورد نظر پيدا گرديد محل قرار گيري عبارت از اولين كاركتر توسط تايع برگشت داده ميشود و در صورتي كه عبارت مورد نظر پيدا نشود عبارت false .
در ضمن ورودي هاي ان عبارت است از
عبارت جستجو شونده ( مقدار يا تكست txtfind)
محل شروع جستجو ( هنگامي كه جستجو دوباره انتخاب شود )( براي اوليت سرچ برابر 0 است )
ريچ تكس باكس كه جستجو در تكست ان انجام ميشود( كه همان txtNotes)
و گزينه اي كه حساسيت به كلمه هاي يزرگ و كوچك را مشخص مينمايد ( كه در واقعه مقدار چك باكس match case است )
خوب پس كد دكمه جستجو ميشود
کد:
Private Sub BtnFind_Click()
Dim dumm
' check if user enter some thing
If txtFind = "" Then Exit Sub
' add this search to combo box list for next user use
txtFind.AddItem txtFind.Text
' call to find that string
dumm = SearchStr(txtFind.Text, 0, frmNotes.txtNotes, ChkCase.Value)
' if return is fasle show message
If dumm = False Then
' show message
MsgBox "Nothing Found.", vbOKOnly, "Search Resualt..."
' set last find varible to 0
FindLoc = 0
' disable btnnext button
BtnNext.Enabled = False
' exit this sub
Exit Sub
End If
' set last find varible to where found txtfind
FindLoc = dumm
' set findstr var for use in next find button
FindStr = txtFind
' select the word find
frmNotes.txtNotes.SelStart = FindLoc - 1
frmNotes.txtNotes.SelLength = Len(FindStr)
' enable next button
BtnNext.Enabled = True
' set focuse to main form so we can see what select
frmNotes.SetFocus
End Sub
در اين كد ابتدا چك ميشود كه عبارتي برا يجستجو وارده شده است اگر اين طور است اين مقدار را به ليست Combobox اضافه كن و با مقدار صفر و شئ txtNotes و مقدار جك باكس بفرست .اگر مقدار برگشتي نادرست است پيغام عدم پافت شدن عبارت مربوطه را نشان بده و اخرين محل جستجو رابرابر با 0 و دكمه پيدا كردن بعدي را غير فعال كن ) و گرنه عبارت جستجو شونده و محل ان را ذخيره و اين عبارت را انتخاب كنسپس دكمه ستجو بعدي را فعال كرده و اختيارات را به فرم frmNotes برگدان .
كد دكمه پيدا كردن بعدي هم شبيه اين كد است
کد:
Private Sub BtnNext_Click()
Dim dumm
' check if user change string or not
If FindStr = "" Then Exit Sub
' call to find that string
dumm = SearchStr(FindStr, FindLoc, frmNotes.txtNotes, ChkCase.Value)
' if return is fasle show message
If dumm = False Then
' show message
MsgBox "No more item Found.", vbOKOnly, "Search Resualt..."
' set last find varible to 0
FindLoc = 0
' disable btnnext button
BtnNext.Enabled = False
' exit this sub
frmNotes.SetFocus
Exit Sub
End If
' set last find varible to where found txtfind
FindLoc = dumm
' select the word find
frmNotes.txtNotes.SelStart = FindLoc - 1
frmNotes.txtNotes.SelLength = Len(FindStr)
' set focuse to main form so we can see what select
frmNotes.SetFocus
End Sub
تنها تفارت آن با كد قبلي چك كردن مقدار سرچ ( يعني قبلا سرچ شده) و محل آغاز سرچ است كه برابر محل قبلي است كه عبارت سرچ شده است در ان پيدا شده بود.
حال اگر برنامه را اجرا نماييم و بعد از سرچ اوليه و قبل از زدن جستجوي بعدي كلمه سرچ شونده را عوض كنيم چون مقدار findStr تغيير نكرده است برنامه با مقادير قبلي سرچ را انجام ميدهد. براي حل اين مشكل از كد زير استفاده ميكنيم
کد:
Private Sub txtFind_Change()
' if txtfind changed then findstr set to nothing and disable btnnext button
' if we did not do that wen user click btnnext find last serached word not
' this is entered
FindStr = ""
BtnNext.Enabled = False
End Sub
هنگامي كه دكمه close فرم frmFind را بزنيم و بعد دوباره عمليات سرچ را انجام دهيم مقادير قبلي سرچ خالي شده اند زيرا اين فرم دوباره نمايش داده شده است و تمامي متغييرهاي لوكال ان از اول ست ميشود مثل ليست اعضا combobox لذا ما هنگامي كه برنامه ميخواهد اين فرم را ان لود نمايد فقط فرم را مخفي مينماييم لذا هيچ متغييري دوباره تعريف نميشود :
کد:
Private Sub Form_Unload(Cancel As Integer)
'hide me
Me.Hide
' set cancle true so we can last search variable
Cancel = True
End Sub
اين كد را به فرم frmFind اضافه ميكنيم .
تنها موردي كه ديده ميشود اين است اگر بعداز انتخاب شدن گزينه اي توسط فرم سرچ اين فرم را دوباره فعال كنيد عبارت سلكت شده از حالت سكلت شده خارج ميشود براي حل اين مشكل بعد از كليك رست روي txtNotes و بعد انتخاب Properties تيك گزينه HideSelection را برميداريم
خوب سورس كلي و ورد اون رو هم اتچ كردم.
اميدوارم كمك تون بكنه :lol: