PDA

View Full Version : ساخت فرم جستجو



pedram_ns
جمعه 23 دی 1390, 16:28 عصر
با سلام
یک فرم برای جستجو ساختم که چند فیلد داره و با تمام فیلد های موجود عمل سرچ رو انجام میده


booklist.RowSource = "select * from books where name like '%shimi%'"

چه ایرادی در این کد وجود داره که هیچ مقداری رو بر نمیگردونه؟
اگه بخوام یک کلمه قارسی سرچ بشه آیا باید تغییر خاصی در کد بدم یا با انگلیسی فرقی نداره؟

لطفا در مورد این مشکلات راهنمایی بفرمایید

در ضمن

می دونم که این نوع جستجو خیلی جالب نیست چون مثلا اگر عنوان کتاب سه کلمه ای باشه و کاربر کلمه دوم رو وارد کنه با این دستور like هیچ موردی رو پیدا نمیکنه.

یه تابع می خوام که بتونم با اون اول همه کلمات درون تکس باکس رو تفکیک کنم و بعد بر اساس هر کدوم از این کلمات با دستور like و Or جستجو رو انجام بدم.

ممنون میشم راهنمایی بفرمایید.

aromega65
جمعه 23 دی 1390, 16:50 عصر
سلام
نمونه بزار درستش کنم
راهش استفاده از یه کدی شبیه به اینه
booklist.RowSource = "select * from books where name like * & form!form1!text1 & *"

Abbas Amiri
جمعه 23 دی 1390, 17:19 عصر
با تائید مطالب فوق لازم به ذکر است که اگر در Access Options در قسمت Query Design گزینه(SQL Server Compatible Syntax (Ansi 92 تیک خورده باشد دستور پست 1 صحیح خواهد بود.وکوئریها از قواعد سیکیوال سرور پیروی خواهند کرد( البته نه 100%)

pedram_ns
جمعه 23 دی 1390, 22:19 عصر
با تشکر
ولی مشکل من با این کد هم حل نشد نمونه رو گذاشتم اگه لطف کنید و کمک کنید ممنون میشم.
در فرم searchbook این مشکل برای جستجو هست.

در ضمن ممنون میشم در مورد اون مطلبی که در مورد تفکیک کلمات وارد شده در فیلد جستجو و جستجو بر اساس هر کلمه هم راهنمایی کنید

در ضمن وقتی من کد دوستمون رو نوشتم مدام این ارور رو میده در حالی که اون کد رو پاک کردم باز هم این ارور میاد

syntax error (missing operation) in query experession 'name like *shimi*'

Abbas Amiri
جمعه 23 دی 1390, 23:31 عصر
در روال باتن سرچ علامت % را به ستاره تبدیل کنید و با تایپ کلمه شیمی عمل خواهد کرد

Row source مربوط به لیست باکس را به صورت زیر تصحیح کنید


SELECT bookid, name, author, publisher, publishdate, cost FROM books WHERE name like '*shimi*';

pedram_ns
شنبه 24 دی 1390, 09:33 صبح
خیلی ممنون.

در مورد سئوال دوم و تفکیک کلمات کسی نظری نداره؟ کسی یه نمونه سرچ پیشرفته نداره؟

در مورد اون ارور چی؟ هنوز هم این ارور رو دارم از چیه و چطور از بین میره؟

باز هم تشکر

aromega65
شنبه 24 دی 1390, 18:39 عصر
سلام امیدوارم مشکلت با توضیحات دوستمون حل شده باشه
در مورد جستجو براساس کلمه به کلمه فکر کنم بشه کدهایی نوشت ولی اگه دوستان نظر بهتری دارن یا روشی برای این کار دارن لطفا بزارن

pedram_ns
شنبه 24 دی 1390, 19:39 عصر
بله مشکل من حل شد و سپاس گزاری هم کردم.

در مورد این تفکیک کلمات و جستجو بر اساس هر کلمه باید بگم که مسئله مهمیه که شاید در نظر اول به چشم نیاد ولی برای یک پروژه حرفه ای باید رعایت بشه(چون خودم با یک موردش برخورد داشتم)
مثلا در همین نمونه خودم، اگر کتابی با عنوان "ریاضی مهندسی پیشرفته" در دیتابیس باشه در صورتی در جستجو، این کتاب پیدا میشه که کاربر یکی از کلمات "ریاضی" ، "مهندسی" و " پیشرفته" رو وارد کنه(یا ترکیبشون به همون صورتی که در دیتابیس هست). ولی اگر کاربر عبارت "ریاضی پیشرفته" رو وارد کنه این کتاب پیدا نمیشه.
در مورد کلمه "غیرآهنی" که دو کلمه به هم چسبیده است اگر کاربر عبارت "غیر آهنی" که دو کلمه از هم جدا هست رو وارد کنه باز هم این کتاب پیدا نمیشه در صورتی که کاربر عبارت درستی زده و انتظار پاسخ داره.

برای حل این مشکل باید کلمات وارد شده توسط کاربر رو با توجه به فاصله بین اونها از هم تفکیک کرد و سپس یک کوری نوشت که هر سه کلمه رو با دستور Like و AND جستجو کنه در این صورت مشکلات بالا رفع میشه و یک جستجو حرفه ای تر داریم.

لطفا دوستانی که در این زمینه میتونن کمکی کنن راهنمایی بفرمایند.

Abbas Amiri
شنبه 24 دی 1390, 19:50 عصر
با روش زیر حروف وکلمات در هرکجای فیلد که باشند درلیست قرار میگیرند.


""select * from books where name like '*" & form!form1!text1 & "*'"

aromega65
شنبه 24 دی 1390, 22:18 عصر
جواب آقای امیری درسته ولی بازم مشکل مطرح شده رو رفع نمیکنه

Abbas Amiri
شنبه 24 دی 1390, 22:27 عصر
موضوعی که شما بیان کردیدکاملا عملی است . به این صورت که تمام حروف تایپ شده در یک حلقه چک شده وبا یک ستاره با حروف قبلی و بعدی یک رشته را تشکیل دهد وتمام اینها باهم OR شوند.

aromega65
شنبه 24 دی 1390, 22:43 عصر
جناب امیری میتونید در این خصوص یه نمونه بزارید
چون من دقیقا از کدی که شما نمونشو گذاشته بودید در برنامه ام استفاده می کنم
خیلی برام مهمه که همچین قابلیتی داشته باشه

Abbas Amiri
شنبه 24 دی 1390, 23:09 عصر
کد زیر را جایگزین کنید:


Private Sub searchbtn_Click()
Dim k As Integer
Dim s As String, sFilter As String
If Len(titletxt) > 0 Then
For k = 1 To Len(titletxt)
sFilter = sFilter & " name like '*" & Left(titletxt, k) & "*" & Right(titletxt, Len(titletxt) - k) & "*' OR "
Next
sFilter = Left(sFilter, Len(sFilter) - 4)
Else
sFilter = "(1)"
End If
booklist.RowSource = "select bookid,name,author,publisher,publishdate,cost from books where " & sFilter
End Sub

aromega65
شنبه 24 دی 1390, 23:16 عصر
آقای امیری خیلی ممنون که وقت گذاشتید
فکر میکنید بشه بصورت پابلیک این کد رو تعریف کرد و تو کوری ها ازش استفاده کرد
چون به این صورت تو برنامه من کاربرد زیادی نمیتونه داشته باشه
بازم ممنونم

Abbas Amiri
شنبه 24 دی 1390, 23:17 عصر
می توانید این کد را در روال Change مربوط به titletxt بگذارید فقط بجای titletxt مقدار titletxt.Text را قرار دهید ،تا بافشردن هرحرف نتیجه را ببینید.

aromega65
شنبه 24 دی 1390, 23:21 عصر
داده های بانک من در سیکوال خیلی بالاست (قریب یک میلیون رکورد) فکر میکنید میتونه خوب جواب بده

Abbas Amiri
شنبه 24 دی 1390, 23:23 عصر
تابع مورد نظر ومثال :


Private Sub titletxt_Change()
booklist.RowSource = "select bookid,name,author,publisher,publishdate,cost from books where " & WideSearch(titletxt.Text)
End Sub

Public Function WideSearch(sSearch As String) As String
Dim k As Integer
Dim s As String, sFilter As String
s = sSearch
If Len(s) > 0 Then
For k = 1 To Len(s)
sFilter = sFilter & " name like '*" & Left(s, k) & "*" & Right(s, Len(s) - k) & "*' OR "
Next
sFilter = Left(sFilter, Len(sFilter) - 4)
Else
sFilter = "(1)"
End If
WideSearch = sFilter
End Function

aromega65
شنبه 24 دی 1390, 23:34 عصر
ممنونم امتحان میکنم رو سرور امیدوارم که هدف رو تامین کنه
بازم از اینکه وقت گذاشتی ممنونم
آی دی من تو یاهو همین نام کاربریمه
البته اگه مایل بودید

Abbas Amiri
شنبه 24 دی 1390, 23:43 عصر
بعلت حجم بالای اطلاعات در روال Change قرار ندهید و مهمتر اینکه بهتراست فیلدهای مورد جستجورا درجدولتان Index کنید

RESMAILY
یک شنبه 25 دی 1390, 07:29 صبح
به نام خدا
با سلام. نمی دانم ولی پیشنهاد است. می شود عبارت را دو یا چند شرطی کنید با عملگر or؟ مثلا

WHERE name like '*ریاضی*' or name like '*مهندسی*'

pedram_ns
یک شنبه 25 دی 1390, 14:15 عصر
با سلام و تشکر

این چند روزه از کمکهای آقای امیری فوق العاده استفاده کردم ولی در این مورد باید بگم من این کد رو تست کردم و جواب میده ولی مشکلی که داره اینه که اگه من در دیتابیسم کتاب "استخراج معدن" رو داشته باشم اگر کاربر کلمه "اخراج" رو هم وارد کنه این کتاب پیدا میشه چون تمام حروف استخراج رو در خودش داره ولی این یه جواب صحیح برای جستجوی انجام شده نیست. :متفکر:

به نظر من همونطور که دوستمون در تاپیک قبل هم گفت بهتره که با دستور Split و با توجه به فاصله بین کلمات، کلمات رو از هم تفکیک کنیم و بعد کوری رو بر اساس جستجوی هر کلمه انجام بدیم اینطوری به نظرم بهتر باشه.

فقط چون خیلی وارد نیست از آقای امیری می خوام لطفا روی این کار کنن تا ما هم استفاده کنیم.

پیشاپیش تشکر میکنم

Abbas Amiri
یک شنبه 25 دی 1390, 19:26 عصر
کد جداساز رشته به واسطه Space در ذیل خواهد آمد :


Private Function GetPartOfString(strSearch As String, Delemiter As String, Optional Nth As Integer = 1) As String
Dim workTb() As String, k As Integer
workTb = Split(strSearch, Delemiter)
k = UBound(workTb)
If k < Nth - 1 Then Exit Function
GetPartOfString = workTb(Nth - 1)
End Function

Public Function WideSearch(fldName As String, ByVal sSearch As String, Optional Operand As String = "AND") As String
Dim k As Integer
Dim s As String, sFilter As String
If Len(sSearch) > 0 Then
Do
k = k + 1
s = GetPartOfString(sSearch, " ", k)
If s <> "" Then
sFilter = sFilter & fldName & " LIKE '*" & s & "*' " & Operand & " "
End If
Loop While s <> ""
sFilter = Left(sFilter, Len(sFilter) - 4)
Else
sFilter = "(1)"
End If
WideSearch = sFilter
End Function

Abbas Amiri
یک شنبه 25 دی 1390, 19:55 عصر
پست بالا تصحیح شد برای استفاده ازآن مانند زیر عمل کنید : این تابع بصورت Default جملات را AND میکند ودر صورت نیاز می توانید باارسال پارامتر سوم بصورت "OR" آنها رابا هم OR کنید


booklist.RowSource = "select bookid,name,author,publisher,publishdate,cost from books where " & WideSearch("name", titletxt)

pedram_ns
یک شنبه 25 دی 1390, 23:24 عصر
با تشکر ویژه از آقای امیری
کار میکنه و همونطور که خودتون نوشتید دستور and به نظرم بهتر از or باشه.
فقط دو تا مسئله :
اگر قبل از ورود یک کلمه در فیلد جستجو یه اسپیس زده بشه ارور زیر رو میده


sFilter = Left(sFilter, Len(sFilter) - 4)

اگر هم فیلد رو خالی بذارم و سرچ رو انجام بدم به کوری جستجو ارور میده

چطور میشه این دو ارور رو حذف کرد؟(توقعمون رفت بالا یکم :لبخند:) منظورم اینه که این مسئله در جستجو تاثیر نذاره چون مثلا من غیر از نام کتاب بر اساس نام نویسنده هم جستجو میکنم و میخوام اگه کاربر نام نویسنده رو ننوشت جستجو بدون این ایتم و فقط بر اساس نام کتاب به درستی انجام بشه.(و بر عکس)

باز هم ممنون

Abbas Amiri
یک شنبه 25 دی 1390, 23:53 عصر
در فایل زیر تصحیح شد

pedram_ns
دوشنبه 26 دی 1390, 09:23 صبح
فوق العاده بود متشکرم