PDA

View Full Version : نحوه استفاده از متغیر داخل کوئری



sajjad_kochekian
چهارشنبه 14 بهمن 1388, 23:04 عصر
سلام
می خواستم بدونم چه جوری می تونم داخل یک کوئری از متغر های سراسری ام استفاده کنم؟
:متفکر:

mazoolagh
شنبه 17 بهمن 1388, 12:04 عصر
منظورتون از متغیر سراسری متغیری هست که public تعریف شده؟
بطور مستقیم که نمیشه. شما فقط میتونین کوئری پارامتریک تعریف کنین و با کد مقدار متغیر رو بهش پاس کنین.

sajjad_kochekian
شنبه 17 بهمن 1388, 15:48 عصر
منظورتون از متغیر سراسری متغیری هست که public تعریف شده؟
بطور مستقیم که نمیشه. شما فقط میتونین کوئری پارامتریک تعریف کنین و با کد مقدار متغیر رو بهش پاس کنین.

بله من متغیر سراسری تعریف کردم.
چه جوری کوئری پارامتریک تعریف کنیم؟
چه جوری مقدار بفرستیم؟
اگه من رو راهنمایی کنید خیلی ممنون می شم

mazoolagh
یک شنبه 18 بهمن 1388, 14:10 عصر
نعریف پارامتر برای یک کوئری خیلی ساده است. کافی هست که دور اسم پارامتر رو براکت بگذارین : []
مسلما اسم پارامتر نباید با فیلدها یکسان باشه. مثلا اگر بخواین فیلد TARIKH رو بین مقادیر DATE1 و DATE2 بگیرین کافی هست در تعریف کوئری به شکل زیر عمل کنین:


SELECT *
FROM BOOKS
WHERE TARIKH BETWEEN [DATE1] AND [DATE2]
ORDER BY TARIKH


هر موقع این کوئری اجرا بشه (چه بصورت مستقیم یا وقتی که سورس یک فرم یا ریپورت باشه) مقادیر DATE1 و DATE2 رو میپرسه.

حالا اگر بخواین با کد پارامتر رو به کوئری پاس کنین باید شبیه زیر عمل کنین:



DIM QDEF AS QUERYDEF
SET QDEF=CURRENTDB.QUERYDEFS("Q1")
QDEF.PARAMETERS("DATE1")=880101
QDEF.PARAMETERS("DATE2")=880631


اینها فقط بعنوان آموزش بود اما در کل این روش رو پیشنهاد نمیکنم. شما همیشه میتونین در فرمها و گزارشها از OPENARGS و WHERE CONDITION استفاده کنین که بدون دردسر و کارآمدتر هست.

sajjad_kochekian
یک شنبه 18 بهمن 1388, 18:04 عصر
من درست منظور شما رو متوجه نشدم
من زیاد حرفه ای نیستم و با کوئری زیاد کار نکردم
اگه میشه روی نمونه ای که گذاشتم انجام بدید
می خوام مقدار کومبو باکس را داخل متغیر سراسری بذارم و بعد با اون کوئری را اجرا کنم

nabeel
یک شنبه 18 بهمن 1388, 21:36 عصر
سلام


بطور مستقیم که نمیشه. شما فقط میتونین کوئری پارامتریک تعریف کنین و با کد مقدار متغیر رو بهش پاس کنین.

این کار از همون طریق خواسته شده هم امکان پذیر هستش .

Dim XParameter As Integer
Function RetParameter() As Integer
RetParameter = XParameter
End Function

Private Sub cmdCommand_Click()
XParameter = InputBox("Please Enter A Value")

DoCmd.OpenQuery "SampleQuery"

'Or :
DoCmd.OpenReport "SampleReport"
End Sub



در مثال فوق شما در داخل پزس و جوی خودتون و یا در هر جای دیگه تنها باید تابع RetParameter رو فراخوانی کنید
( به همون صورتی که دیگر توابع استاندارد خود اکسس رو مورد استفاده قرار میدید )

ذکر یک نکته لازمه که تابع و بخش معرفی متغیر باید در داخل یک ماژول پیاده سازی بشن


چه جوری کوئری پارامتریک تعریف کنیم؟

واژه پارامتریک در داخل اکسس یک واژه عمومیه که بیانگر امکان تغییر در نتایج خروجی بر مبنای ورودی متغیر هستش
پاسخ ارسالی از سوی دوستمون mazoolagh این امکان رو در اختیار شما میتونه قرار بده که علاوه بر تعیین متغیر , امکان تغییر کلی خود پرس و جو رو هم داشته باشه . ( با توجه به اینکه بر اساس Query Definition عمل شده )

ولیکن یک کاستی کوچیک در کد ارسالی دوستمون وجود داره

QDEF.PARAMETERS("DATE1")=880101
QDEF.PARAMETERS("DATE2")=880631

سوی دوم نباید به عنوان یک ثابت در نظر گرفته بشه در غیر اونصورت این کد نمیتونه به صورت کامل معرف حالت پارامتریک باشه
البته همون طوری که این دوست عزیزمون گفتن , این مثال ساده بوده و تنها جهت آشنایی شما ارائه شده .
شما جهت تکمیل نیاز دارید یا سوی دوم رو برابر با یک کنترل قرار بدید و یا به طریقی ورودی رو به صورت پویا به اون وارد کنید

موفق باشید

mazoolagh
دوشنبه 19 بهمن 1388, 12:29 عصر
باید بگم TRICK مطرح شده توسط جناب نبیل در مورد استفاده از تابعی که آرگومان خودش رو عینا برمیگردونه واقعا جالب بود (جدای از این موضوع که OVERHEAD داره)

nabeel
دوشنبه 19 بهمن 1388, 18:18 عصر
سلام mazoolagh

ضمن تشکر از نظر شما


جدای از این موضوع که OVERHEAD داره

متاسفانه بنده عملکردی که منجر به OVERHEAD شده باشه توی کد نمیبینم , لطفاً در صورتی که وجود داره اعلام بفرمایید تا توضیح بدم

مطمئناً شما میدونید که واژه Overhead در مواقعی به کار میره که ممکنه در اینجا جایگاهی نداشته باشه

البته اگر منظورتون Overhead در اطلاعات مقیم در حافظه هستش و مدیریت اونها , با توجه به اینکه در هر بار فراخوانی مقدار متغیر , بازسازی میشه , نقیصه ای در این خصوص وجود نداره ( اینکه کاربران دیگه این کدها رو به چه صورتی مینویسن , نمیدونم ولی مطئمناً بنده و شما رو با مشکل مواجه نمیکنه )

گو اینکه در Execution Overhead این کد تا حدودی کارایی بالاتری نسبت به Query Definition داره

مجدداً از اینکه در این گفتگو شرکت کردید ممنونم

موفق باشید

mazoolagh
سه شنبه 20 بهمن 1388, 12:45 عصر
سلام مجدد
منظور از overhead این هست که بازای هر رکورد فانکشن باید اجرا بشه در صورتیکه واقعا نیاز نیست.
البته همونطور که خودتون هم اشاره کردین از بکارگیری روشهایی اینجا مطرح شد تا حد امکان باید خودداری بشه.
در کل چنین نیازهایی وقتی مطرح میشن که طراحی اشکال داشته باشه.

nabeel
سه شنبه 20 بهمن 1388, 23:37 عصر
سلام


منظور از overhead این هست که بازای هر رکورد فانکشن باید اجرا بشه در صورتیکه واقعا نیاز نیست

این جمله به نظر بنده ممکنه درست نباشه و با آموخته های عملی ، تئوری و تجربیم در تناقضه
( ممکنه بنده اشتباه کرده باشم )

شما در هر رکورد تابع رو اجرا نمی کنید ، چه 1 رکورد و چه N رکورد ، تابع فقط یک بار اجرا میشه ( در حالت Select Query )
دقت کنید شما تابع رو در بخش Criteria دارید اضافه میکنید و اون رو به عنوان یک فیلد در شبکه پرس و جو در نظر نمیگیرید ، در صورتی که بدین گونه باشه ( یعنی به عنوان فیلد در نظر بگیرید ) , در هر رکورد تابع نیز اجرا میشه ، چرا که ماهیت کار این رو ایجاب میکنه , حالا شما میخواید از هر تکنیکی استفاده کنید فرقی نمیکنه
در انواع دیگه کوئری ها هم ، اگر با توجه به نوع تابع مورد استفاده ، این کار انجام بشه با نگاهی به ماهیت کار ممکنه نیاز بوده و چاره ای وجود نداشته باشه
تنها دسته توابع Domain Aggregate با توجه به نوع عملکردشون در داخل پرس و جو ها ، برای هر رکورد و حرکت و پیمایش در بین رکوردها ، میتونن منجر به فراخوانی مکرر بشن که همین امر اونها رو در جرگه کند ترین توابع داخلی Access قرار داده ( در هر حالتی این توابع دارای چرخه اجرایی هستند و تا حد ممکن هم باید از اونها استفاده نشه ، مگر اینکه ناگزیر بوده باشید )

تابع مورد بحث ما ( ( RetParameter به طور کامل از این نقیصه به دوره ، چرا که کار خاصی انجام نمیده ، تنها داره مقدار یک متغیر رو میخونه ( یعنی یکی از سریعترین کارهایی که در مقوله برنامه نویسی امکان پذیره )
در اون محاسبه ای انجام نمیشه که بخوایم بگیم اجرای اون زمان بره ، تنها از یک مساوی ساده تشکیل شده
فرخوانیها در سطح ماژول بسیار سریعه
البته اگر بخوایم این مورد رو دارای پتانسیل سربار بدونیم ، خوب تمام حالتهای متصور دیگه هم ، چه روش شما و چه انجام عملیات از طریق DAO ، ADO و یا ODBC ، دارای سربار کاری مضاعف هستند ( بیشتر و نه کمتر از حالت مورد اشاره )

در برخی سربارها تنها این امکان وجود داره که اونها رو اندکی کاهش بدیم و لیکن در نهایت قابل حذف نیستند

قانون تعادل انرژی در همه چیز وجود داره ، از جمله در کد نویسی


البته همونطور که خودتون هم اشاره کردین از بکارگیری روشهایی اینجا مطرح شد تا حد امکان باید خودداری بشه.

کجا !؟ واقعاً یادم نیست کجا این رو ممکنه مطرح کرده باشم ( اینجا نبوده ) ، اگر هم در جایی دیگه بوده ؛ مطمئناً در مورد اون مشکل خاص نظر دادم و قابل بسط دادن در همه جا نیست ( توضیحات تکمیلی رو در بالا دادم – گو اینکه ممنون میشم در صورت امکان در خصوص محلش , راهنمایی لازم رو داشته باشید )


در کل چنین نیازهایی وقتی مطرح میشن که طراحی اشکال داشته باشه.

شاید بشه گفت که نه ، اینجور مواردی در مواقعی که بخواید بانک قابلیت انعطاف بیشتری داشته باشه مورد استفاده قرار میگیره ( از جمله همون روش Query Definiftion مورد استفاده شما )
در واقع به نوعی به عنوان راهکاری مطمئن جهت جلوگیری از محدودیتهای آتی میتونه مد نظر قرار بگیره
جمله فوق قطعیت نداره و یا شاید نشه به طور مطلق صفت اشکال رو به طراحی انتساب داد
یک الگوی طراحی خاص در جایی ممکنه اشتباه بوده باشه و لیکن همون الگو با توجه به ماهیت کار در جایی دیگه هم درست بوده باشه و یا حتی شاید تنها ترین راه حل ممکنه
البته منظورم بانک اطلاعاتی این دوستمون نیست ، شاید مشکل ایشون با همون اصلاح بانک مرتفع بشه ولیکن با توجه به اینکه برخی مباحث مطرح شده تنها در سیستمهایی با طراحیهای پیشرو مورد استفاده قرار میگیرن ، بر همین اساس احتمال اینکه نقیصه ای در طراحی وجود داشته باشه ( نقیصه ای که با تغییر دو تا فیلد و تغییراتی از این دست قابل رفع باشه ) ، کم رنگ و کم رنگتر میشه

با توجه به احتمال عدم نیاز به بسط موضوع , در صورتی که مساله باید بازتر مطرح بشه اعلام بفرمایید

موفق باشید

mazoolagh
چهارشنبه 21 بهمن 1388, 14:02 عصر
سلام ، در مورد کفایت مذاکرات و عدم نیاز به بسط موضوع با شما موافقم.
همچنین در مورد نکاتی که در پست آخر مطرح کردین