View Full Version : Source Database در کوئری اکسس
Masoud.eh
پنج شنبه 01 شهریور 1403, 14:00 عصر
سلام خدمت اساتید
دوستان چجوری میشه آدرس Source Database در کوئری اکسس را بصورت متغیر وارد کرد (مثلا CurrentProject.Path) منظور اینه که در صورت جابجایی فایل اکسس از پوشه ای به پوشه دیگر نیازی به
آدرس دهی مجدد نباشد.(دو فایل اکسس، که جدول ها از فرم ها جداست)155986
Masoud.eh
جمعه 02 شهریور 1403, 09:05 صبح
اساتید گرامی
کمک می کنید مشکل حل بشه
ممنونم
Masoud.eh
جمعه 02 شهریور 1403, 18:52 عصر
دوستان این موضوع خیلی واسم مهمه
ممنون میشم اگه راه حل داره، بفرمایید.
atf1379
جمعه 02 شهریور 1403, 20:05 عصر
دوستان این موضوع خیلی واسم مهمه
ممنون میشم اگه راه حل داره، بفرمایید.
سلام
مروری داشته باش به مطالب ارائه شده در این تاپیک (https://barnamenevis.org/showthread.php?572279-%D8%AD%D9%81%D8%A7%D8%B8%D8%AA-%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D8%A7%DA%A9%D8%B3%D8%B3-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D8%A7%D8%B2-%D8%B9%D9%85%D9%84%DA%AF%D8%B1-Insert-From-Access) و از کدهای نمونه های پست 24 و 30 در برنامه خودتون استفاده کن!
Masoud.eh
شنبه 03 شهریور 1403, 21:07 عصر
سلام
ممنونم بابت پاسختون
ولی تاپیک و پست های که فرمودین مشکل رو برطرف نکرد
دوست عزیز موردی که بنده عرض کردم دو تا فایل اکسس (فایل جدول ها و فایل کوئری و فرم ها) که توی یک پوشه هستن، فراخوان رکوردهام بوسیله کوئری از فایل جدول هاست.
حال توی Source Database (عکس پست اول) کوئری حتما باید آدرس دقیق فایل جدول ها رو داد که با جابجا کردن پوشه و تغییر آدرس، کوئری را مجدد باید آدرس دهی و فیلدها را وارد کرد.
میخوام اگر راهی هست که بصورت CurrentProject.Path آدرس دهی بشه.
ممنون میشم اگر راهی داره کمک کنید مشکل برطرف بشه.
mazoolagh
یک شنبه 04 شهریور 1403, 10:19 صبح
سلام و روز خوش
آدرسی که در source database مشخص میکنین خودش بصورت دیفالت relative هست؛
یعنی نسبت به آدرس دیتابیس خودتون محاسبه میشه.
بنابراین نیازی نیست با currentproject.path ادرس رو پیدا کنین
و بعد دنبال راهی بگردین که چجوری اون رو در این فیلد پیاده کنین.
1- اگر دیتابیس اکسترنال شما (مثلا abc.accdb) در همین فولدر دیتابیسی هست که کوئری رو در اون ساختین؛
کافی هست بنویسین : abc.accdb
2- اگر در یک فولدر دیگه (مثلا xyz) درون همین فولدر هست :
xyz\abc.accdb
3- اگر در یک فولدر دیگه در parent فولدر فعلی هست:
..\xyz\abc.accdb
و به همین ترتیب ...
mazoolagh
یک شنبه 04 شهریور 1403, 10:22 صبح
سلام
مروری داشته باش به مطالب ارائه شده در این تاپیک (https://barnamenevis.org/showthread.php?572279-%D8%AD%D9%81%D8%A7%D8%B8%D8%AA-%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D8%A7%DA%A9%D8%B3%D8%B3-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D8%A7%D8%B2-%D8%B9%D9%85%D9%84%DA%AF%D8%B1-Insert-From-Access) و از کدهای نمونه های پست 24 و 30 در برنامه خودتون استفاده کن!
سلام و روز خوش
فکر کنم به تاپیک اشتباه رفرنس دادین!
Masoud.eh
یک شنبه 04 شهریور 1403, 11:01 صبح
سلام و روز شما هم خوش
راه حلی که فرمودین اجرا کردم ولی نتیجه نداشت.
نمونه دیتابیس رو پیوست میکنم ممنون میشم اصلاحش کنید.
155992
atf1379
یک شنبه 04 شهریور 1403, 13:14 عصر
سلام و روز خوش
فکر کنم به تاپیک اشتباه رفرنس دادین!
سلام
روز شما هم خوش
لینک تاپیک مربوطه رو بخاطر اینکه فکر کردم ایشون شاید مشکل کنترل جابجائی بانک اطلاعاتی دارند قرار دادم
eb_1345
یک شنبه 04 شهریور 1403, 13:40 عصر
سلام و روز شما هم خوش
راه حلی که فرمودین اجرا کردم ولی نتیجه نداشت.
نمونه دیتابیس رو پیوست میکنم ممنون میشم اصلاحش کنید.
155992
سلام
با اجازه جناب استاد mazoolagh
عبارت اسکیوال رو بصورت زیر استفاده کن!
strSQL = "SELECT tbl.ID ,tbl.MM,tbl.NN ,tbl.CM,tbl.CN FROM [;DATABASE=" & DLookup("Path", "tblAppInfo") & ";PWD=""].tbl"
اگر فایل BackEnd (فایلی که جداول در آن قرار دارد) دارای پسورد بود میتوانی کلمه پسورد رو در جلوی PWD وارد کنی
Masoud.eh
یک شنبه 04 شهریور 1403, 13:55 عصر
دوست عزیز، عبارت اسکیوال رو باید در محیط vba وارد کرد
ولی من میخوام خود کوئری رو مستقیما استفاده کنم.
نمیدونم منظورمو رسوندم یا ن
eb_1345
دوشنبه 05 شهریور 1403, 07:45 صبح
دوست عزیز، عبارت اسکیوال رو باید در محیط vba وارد کرد
ولی من میخوام خود کوئری رو مستقیما استفاده کنم.
نمیدونم منظورمو رسوندم یا ن
دوست بزرگوار در کوئری درج آدرس دیتابیس اکسترنال بصورت متغیر عملی نیست . شما در دو حالت قادر خواهی بود اطلاعات جداول بانک اطلاعاتی برنامه ات را در کوئری نمایش بدهی:
1- از طریق لینک نمودن جداول بانک اطلاعاتی به درون برنامه
2- از طریق برقراری ارتباط با جداول بانک اطلاعاتی با ایجاد کانکشن استرینگ
بدیهیست در حالت اول بدون هیچ مشکلی وبا ایجاد یک کوئری اطلاعات فیلدهای جدول یا جداول لینک شده را نمایش داده میشودکه ظاهرا این راه مد نظر شما نیست
و اما در حالت دوم در هر حال ناگزیر هستی که از بخش vba کمک بگیری .
برای درج اطلاعات جدول یا جداول فایل بانک اطلاعاتی (Back End) در کوئری فایل Front End با استفاده از آدرس متغییر نیاز به ایجاد کوئری از طریق کدهای vba خواهی داشت.
eb_1345
دوشنبه 05 شهریور 1403, 08:07 صبح
ضمنا فراموش نکن در این روش که تا این حد اصرار به پیاده کردنش داری دسترسی به اطلاعات جداول بانک اطلاعاتی برنامه ات برای دیگران سهل و آسان خواهد بود حتی اگر بر روی بانک اطلاعاتی پسورد گذاشته باشی
mazoolagh
دوشنبه 05 شهریور 1403, 16:11 عصر
سلام و روز شما هم خوش
راه حلی که فرمودین اجرا کردم ولی نتیجه نداشت.
نمونه دیتابیس رو پیوست میکنم ممنون میشم اصلاحش کنید.
155992
سلام دوباره
مطلبی که گفتم درست بود،
ولی باید بیشتر و بهتر توضیح میدادم.
وقتی external database رو در کوئری آدرس میدین، این آدرس relative هست،
ولی نسبت به default database folder هست (این رو باید توضیح میدادم).
در این مسئله ای که شما دارین میتونین (و بهتره) آدرس مطلق نیارین،
و فقط به اسم دیتابیس اشاره کنین یا آدرس رو نسبت به آدرس برنامه مشخص کنین.
با مثال توضیح میدم داستان و روش کار بیشتر روشن بشه.
ساختار زیر رو در نظر بگیرین:
├───external_folder
│ db_e.accdb
│
└───program
│ 589315.accdb
│ db.accdb
│
└───child_folder
db_i.accdb
یک برنامه داریم (589315.accdb) که در فولدر program هست،
یک دیتابیس داریم که در کنار خودش هست (db.accdb)،
یک دیتابیس دیگه (db_i.accdb) در یک فولدر فرزند program به اسم child_folder ،
و یک دیتابیس دیگه (db_e.accdb) بیرون از فولدر برنامه در یک فولدر به اسم external_folder
این ساختار هر جایی میتونه باشه (هر درایوی و درون هر فولدری).
در پست های بعدی توضیح میدم که چجوری کوئری رو ها رو برای این چند حالت بنویسیم
بدون این که مسیر کامل رو در خود کوئری بیاریم.
mazoolagh
دوشنبه 05 شهریور 1403, 16:20 عصر
اینجا برای سادگی هر سه دیتابیس خارجی ما یکسان هست و فقط یک جدول داره: categories
1- کوئری ext_db_in_same_folder برای خوندن از db.accdb:
SELECT *
FROM CATEGORIES
IN 'db.accdb'
2- کوئری ext_db_in_child_folder برای خواندن از db_i.accdb
SELECT *
FROM CATEGORIES
IN 'child_folder\db_i.accdb'
3- کوئری ext_db_in_other_folder برای خواندن از db_e.accdb
SELECT *
FROM CATEGORIES
IN '..\external_folder\db_e.accdb'
تا اینجا همون مطالب پست 6 بود - با توضیح بیشتر
mazoolagh
دوشنبه 05 شهریور 1403, 16:32 عصر
و اما نکته مهم:
وقتی شما آدرس نسبی میدین،
اکسس آدرس رو نسبت default directory که براش مشخص شده محاسبه میکنه.
شما در بخش options به این دسترسی دارین و میتونین تغییرش بدین:
155995
ولی کار درستی نیست!
چون:
1- یک پارامتر عمومی هست و از اون به بعد برای همه فایلهای اکسس اعمال میشه.
2- قرار نیست به صورت دستی کاری انجام بدیم و برنامه خودکار باید تغییرات رو اعمال و بعد به مقدار اصلی خودش برگردونه.
mazoolagh
دوشنبه 05 شهریور 1403, 16:39 عصر
پس یک روتین پابلیک مینویسیم که این فولدر دیفالت رو به آدرسی که مورد نظر ما هست تغییر بده:
Public Sub SetDefaultFolderToCurruntPath()
TempVars("default_database_directory") = Application.GetOption("default database directory")
Application.SetOption "default database directory", CurrentProject.Path
End Sub
و البته قبلش اون رو در یک tempvar نگه میداریم که در پایان کار برش گردونیم.
در اینجا من فولدر دیفالت رو به فولدر خود برنامه سِت کردم - شما میتونین به هر آدرسی که مورد نظرتون هست تغییر بدین.
و یک روتین دیگه مینویسیم که فولدر دیفالت رو به مقدار اصلی خودش برمیگردونه:
Public Sub ResetDefaultFolder()
If IsNull(TempVars("default_database_directory")) Then Exit Sub
Application.SetOption "default database directory", TempVars("default_database_directory")
End Sub
mazoolagh
دوشنبه 05 شهریور 1403, 16:46 عصر
همه اینها رو در یک برنامه نمونه پیوست کردم.
قبل از اجرای فرم، کوئری ها اجرا نمیشن (مگر این که default database directory شما دقیقا همین فولدر برنامه باشه!)
ولی وقتی کوئری ها رو از طریق فرم باز میکنین،
چون در رخداد form open فولدر دیفالت تنظیم شده،
مشکلی در اجرا نیست:
Private Sub Form_Open(Cancel As Integer)
SetDefaultFolderToCurruntPath
End Sub
و بالطبع با بستن فرم هم همه چیز به جای خودش باید برگرده:
Private Sub Form_Close()
ResetDefaultFolder
End Sub
mazoolagh
دوشنبه 05 شهریور 1403, 16:57 عصر
یک نکته ای هست که جناب بهرامی بدرستی اشاره کردن،
و اینکه external database در کوئری باید واقعا از روی نیاز و برای کاربردهای کاملا موقتی باشه
که امکان کانکشن زدن یا ساخت linked-table نباشه.
من خودم هیچوقت تابحال استفاده نکردم،
و تا همین 2-3 سال پیش هم نمیدونستم همچین امکانی هست (اینجا یاد گرفتم)،
ولی تاپیک میبایست به نتیجه میرسید.
atf1379
دوشنبه 05 شهریور 1403, 18:03 عصر
سلام جناب آقای mazoolagh!
وقت شما بخیر
اگر بانک اطلاعاتی دارای پسورد باشد آدرس فایل رو به چه صورتی باید وارد کرد؟
ممنون
eb_1345
دوشنبه 05 شهریور 1403, 18:36 عصر
سلام جناب آقای mazoolagh عزیز!
احسنت !
آموزش مفیدی در خصوص خواسته دوستمون ارائه فرمودین!
درود بر شما!
mazoolagh
سه شنبه 06 شهریور 1403, 18:25 عصر
سلام جناب آقای mazoolagh!
وقت شما بخیر
اگر بانک اطلاعاتی دارای پسورد باشد آدرس فایل رو به چه صورتی باید وارد کرد؟
ممنون
سلام و روز خوش
نمیدونم!
و تست هم نکردم.
شما در همون عبارت IN پسورد و ... رو هم بذارین و تست کنین - باید کار کنه؛
چون ما اینجا فقط بخش آدرس رو سر و کار داشتیم و چیز دیگه ای رو تغییر ندادیم.
کلا یک کانکشن استرینگ هست -
ممکنه بجای آدرس فایل اکسس آدرس فایل اکسل یا متنی یا ... یا کانکشن به sql server و ... باشه.
اونهایی که file-based هستن با این روش باید کار کنن.
mazoolagh
سه شنبه 06 شهریور 1403, 18:39 عصر
سلام جناب آقای mazoolagh عزیز!
احسنت !
آموزش مفیدی در خصوص خواسته دوستمون ارائه فرمودین!
درود بر شما!
سلام جناب آقای بهرامی گرامی
روز شما خوش
آموزش که نمیشه گفت،
یک پست مبهم گذاشته بودم که باید رفع ابهام میشد.
----------
کلا نه در jet نه در ace نمیشه بخش FROM رو پارامتری کرد.
اینه که نهایتا مجبور به استفاده از vba هستیم (شما هم در پست 12 اشاره کردین):
حالا یا در ساخت کاکشن استرینگ،
یا در ویرایش querydef،
یا مثل اینجا ویرایش یک پارامتر سیستم،
و ...
================
پی نوشت:
این مساله یک راه حل کلاسیک و عمومی تر هم داره،
که معمولا خارج از محیط اکسس انجام میشه (اینم راهنماییش).
ولی اگر آدرس ها داخل برنامه ساخته میشه (مثل اینجا که گویا از یک جدول خونده میشه و متغییر هست)،
از داخل برنامه هم قابل انجام هست و البته دیگه لازم نیست پارامترهای اکسس رو دست ببریم،
ولی باز هم vba نیاز هست (همون چند خط).
Masoud.eh
سه شنبه 06 شهریور 1403, 23:55 عصر
سلام
دوستان و اساتید گرامی
واقعا ممنونم بابت راهنمایتون
mohammadsaleh
پنج شنبه 15 شهریور 1403, 18:47 عصر
سلام
دوستان و اساتید گرامی
واقعا ممنونم بابت راهنمایتون
این هم یک نمونه ساده
eb_1345
پنج شنبه 15 شهریور 1403, 21:12 عصر
این هم یک نمونه ساده
سلام
در نمونه جنابعالی هم چنانچه دیتابیس دارای پسورد باشد در کوئری درج میشود و بلحاظ اینکه کوئری ها از طریق دیتابیس دیگر قابل ایمپورت شدن هستن با این روش براحتی میتوان به پسورد دیتابیس پی برد(هرچند کوئری هم در دیتابیس مخفی شده باشد)
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.