بدلیل اینکه اعضاء یک مجموعه با صفر شروع می شوند باید همیشه کدی که لوپ زده میشود از صفر شروع شده و به پراپرتی Count منهای یک ختم شود.اگر تمایل داشته باشید که بین اعضاء یک مجموعه لوپ بزنید بدون بررسی پراپرتی Count می توانید از کامند یا دستور FOR EACH .... NEXT استفاده کنید.
Fields یک کالکشن یا مجموعه ای از ذخایر فیلدهاست
For i=0 To Rs.Fields.Count-1
For Each Fld In Rs.Fields
پراپرتی Count هیچوقت به Null تنظیم نمیشود اگر مقدارش صفر باشد یعنی هیچ شی ای در مجموعه وجود ندارد.
برای ارجاع به شی Field در یک کالکشن توسط عدد ترتیبی آن یا با استفاده از خاصیت نام آن ( Name ) می توانید هر کدام از فرم های نوشتاری زیر را بکار ببرید.
Fields(0)
Fields("name")
Fields![name]
استفاده از خاصیت Name از کالکشن Fields ، همانطور که گفته شد نامبر کالکشن از صفر شروع میشود و با اعداد ترتیبی یعنی پشت سر هم 2 1 0 و .... در زیر نام شی فیلد از کالکشن فیلدز که عدد آن صفر است و منظور فیلد اول است نمایش داده میشود
Msgbox Rs.Fields(0).Name
کد زیر : نمایش نام فیلد صفر جدول 1 از کالکشن Tabledefs ( که مجموعه ایست برای ذخیره Tabledef یا مشخصات جداول ) از دیتابیس جاری
Msgbox currentdb.TableDefs("Table1").Fields(0).Name
varReturn = Syscmd(acsysInitMeter,[ProgressBarName],[TotalCount])
varReturn = SysCmd(acsysUpdateMeter,[ProgressBarName], [CurrentCount])
varReturn = SysCmd(acsysClearStatus)
acsyscmdaction
Recordset.Move
اگر Move را برای انتقال به رکورد قبل از First Record استفاده کنید به شروع فایل میرود . چنانچه رکوردست حاوی رکوردنباشد و خاصیت BOF آن True باشد استفاده از این متد برای برگشت به عقب باعث ارور میشود.
اگر Move را برای بعد از Last Record استفاده کنید نشانگر به انتهای فایل منتقل میشود چنانچه شامل هیچ رکوردی نباشد و EOF هم TRUE باشد قطعا خطا دریافت می کنید.
اگر هر کدام از خاصیت هایBOF یا EOF به TRUE تنظیم شده باشند و تلاش کنید از متد MOVE بدون Bookmark معتبر استفاده کنید خطا اتفاق خواهد افتاد
زمان ساخت یا باز کردن شی RecordSet هر کدام از رکوردها یک بوک مارک یونیک دارند و می توانید بوک مارک را برای رکورد جاری با اختصاص دادن مقدار بوک مارک به یک متغیر ذخیره کنید برای ارجاع سریع به آن رکورد در هر زمان بعد از انتقال به رکورد دیگر , خاصیت بوک مارک شی رکوردست را به مقدار آن متغیر تنظیم نمائید.
Forms!Orders.RecordsetClone.MoveLast
MsgBox "My form contains " _
& Forms!Orders.RecordsetClone.RecordCount _
& " records.", vbInformation, "Record Count"
البته اول از MoveFirst استفاده کنید بعد MoveLast و در اینجا از پراپرتی RecordCount برای شمارش استفاده شده بکار ببر ید چنانچه بکار بردن Dcount سخت تر یا دیر بازده است.
در مثال بالا به آخرین رکورد در مجموعه رکوردها که در فرم Orders است رفته و پیامی که حاوی تعداد رکوردها است را نمایش می دهد توسط باکس یا پنجره Msgbox
Dim rs as Dao.Recordset
Set rs=Me.RecordsetClone
With rs
.MoveFirst
.MoveLast
Msgbox .RecordCount
End With
Using a RecordsetClone is an easy way to manipulate records on a subform
استفاده از RecordsetClone یک راه آسان برای جمع آوری رکوردها در سابفرم است دوستان .
می توانید از قالب Dcount استفاده نمائید.
Me.Text1 = DCount("[Pick a field]", Me.RecordSource)
You can use the SelTop property to specify or determine which row (record) is topmost in the current selection rectangle in a table, query, or form datasheet, or which selected record is topmost in a continuous
form
با استفاده از خاصیت SelTop می توان بالاترین ردیف ( رکورد جاری ) را در یک مجموعه انتخابی مشخص کرد.این خاصیت عددی بین 1 و شماره رکوردها در Datasheet یا continuous form را بر می گرداند.
پراپرتی های SelTop و SelLeft موقعیت گوشه چپ بالایی مستطیل انتخابی را مشخص میکند.
پراپرتی های SelHeight و SelWidth موقعیت گوشه سمت راست پایینی مستطیل انتخابی را مشخص میکند.
بیشتر زمانی استفاده میشود که بخواهند چند ردیف را انتخاب کنند و یک Query روی آنها اجرا نمایند.
The SelHeight property returns a Long Integer value between 0 and the number of records in the datasheet or continuous form. The setting of this property specifies or returns the number of selected rows in the selection rectangle or the number of selected records in the continuous form.
پراپرتی SelHeight یک عدد صحیح از نوع لانگ بین صفر و تعداد رکوردها در فرم دیتاشیت یا کانتینیوس را برمی گرداند.تنظیم این خاصیت تعداد ردیف های انتخاب شده در مستطیل انتخابی یا تعداد رکوردهاب انتخاب شده در فرم کانتینیوس را برمی گرداند
RECORDSET.MOVE :
موقعیت نشانگر رکورد جاری را انتقال می دهد
تلاش به انتقال به یک نقطه قبل از اولین رکورد به انتقال به رکورد قبل از اولین رکورد منجر میشود که BOF است .تلاش به انتقال به قبل از آخرین رکورد باعث میشود نشانگر رکورد به رکورد بعد از آخرین رکورد انتقال یابد که EOF است. در غیر از این مورد اگر متد MOVE برای انتقال به قبل از BOF یا EOF استفاده شود ارور ایجاد می کند.تست کنید در فرم Bound شده یعنی در پراپرتی رکورد سورس نام جدولی باشد.
Private Sub cmd1_click()
Dim rs as Dao.Recordset
Set rs=me.recordset
Rs.MoveLast
Res.MoveNext
End Sub
مثال از SelTop و SelHeight :
اگر از بالا به پائین ردیف سوم و چهارم را انتخاب کنید SelTop را 3 و SelHeight را 2 دریافت می کنیم اما اگر از پائین به بالا انتخاب کنید عدد SelTop 4 و SelHeight همان 2 است
زمانیکه روی یک باتن کلیک کنید انتخاب از بین میرود و SelHeight هم صفر میشود پس اگر بخواهید آنرا داشته باشید باید ذخیره کنید می توانید در رویداد EXIT سابفرم آنرا در متغیری ذخیره کنید . فرضا Selh=Me.SelHeight .... اگر اینکار را انجام ندهید انتخاب Clear می شود و SelTop به رکورد انتخاب شده جاری که رکورد پائین است تنظیم میشود ( زمانیکه انتخاب پائین به بالا باشد )
یادداشت : SelTop. و SelHeight. در یک فرم کانتینیوس کاربرد دارد در حالت Form View زمانیکه با Record Selector رکوردی را انتخاب می کنید.
دیتاشیتی که فوکس گرفته ... تعداد ردیف های انتخاب شده با SelHeight ... تعداد ستون های انتخاب شده با SelWidth .... بالاترین ردیف در مجموعه انتخاب شده با استفاده از SelTop و بستگی دارد که از بالا به پائین یا از پائین به بالا انتخاب می کنید. ( توضیحات ذیل )
' Datasheet that has the focus
Set frm = Screen.ActiveDatasheet
' Number of rows selected.
lngNumRows = frm.SelHeight
' Number of columns selected.
lngNumColumns = frm.SelWidth
' Topmost row selected.
lngTopRow = frm.SelTop
دو عمل زیر در Recordset ، اولی رفتن به اولین رکورد و دومی انتقال نشانگر رکورد به اولین رکورد انتخاب شده
Rs.MoveFirst
' Move to the first selected record.
Rs.Move mlngSelTop - 1
'
You can use the SelTop property to specify or determine which row (record) is topmost in the current selection rectangle in a table, query, or form datasheet, or which selected record is topmost in a continuous form
Private Sub YourTabbedControlName_Change() Select Case YourTabbedControlName Case 0 'First Page FirstPageButton.SetFocus Case 1 'Second page SecondPageButton.SetFocus Case 2 'Third page ThirdPageButton.SetFocus End Select End Sub
در رویداد Change تب کنترل که به نام YourTabbedControlName است انتخاب هایی صورت گرفته با Select Case ( در زمان رفتن به فرم یا تب خاصی تعدادی از رویدادها اتومات اجرا میشوند مثل رویداد Change و Click) طبق کد بالا چنانچه در پیج ها جابجاشویم حین این جابجایی فوکس به کنترل خاصی در آن پیج منتقل میشود وقتی به پیج یک می رویم یا بعبارتی پیج یک را انتخاب می کنیم کنترل نوع باتن به اسم FirstPageButton فوکس می گیرد.
Msgbox TabControl1.Pages.Count
با عبارت بالا تعداد پیج های موجود در تب کنترل 1 نمایش داده میشود
TabControl1.Pages(0).Caption = "First Page"
با عبارت بالا خاصیت کپشن پیج با ایندکس صفر در کنترل TabControl1 به First Page تنظیم شده
CurrentDb.TableDefs("Cost Down TableX9").Fields("Select").Properties("DisplayControl") = acCheckBox
در کد بالا به زبان ساده آدرس نویسی شده از کالکشن و متد و پراپرتی استفاده شده و مشخص کرده که پراپرتی DisplayControl فیلد Select در جدول TableX9 را از نوع CheckBox قرار بده
دوستان عزیز لطفا نظر سنجی فراموش نشود.
TableDefs.CreatePropert Methods
CreateProperty(Name, Type, Value, DDL)
دوستان عزیز لطفا اگر مطلبی کمکتون میکنه یا براتون مفیده لطفا لایک و نظر بدهید در نظرسنجی هم شرکت کنید.
مثال زیر ماژولی است که می توانید در استاندارد ماژول برنامتون اضافه کنید البته اگر بار دوم اجرا بشود چون ساخته شده ارور ران می شود ( اجرا ). یک فیلد از نوع Yes/No ایجاد میکند و خاصیت نمایش کنترل را بصورت چک باکس تنظیم میکند.برای انجام و ایجاد باید دیتابیس را به دیتابیس جاری تنظیم نمایید با
Set dbs=CurrentDb
اگر دیتا بیس دیگری باشد باید از OpenDataBase استفاده بنمائید.سپس جدول دیتابیس جاری را به tdf تنظیم کرده و در آخر ایجاد فیلدبا نامی که پارامتر دوم فانکشن یعنی StrFieldName مشخص کرده.بعد از ایجاد کردن فیلد مورد نظرتون پراپرتی فیلد را تنظیم نموده
Public Sub CreateYesNoField(strTableName As String, _ strFieldName As String) Dim dbs As DAO.Database Dim tdf As DAO.TableDef Dim fld As DAO.Field Dim prop As DAO.Property
Set dbs = CurrentDb
(Set tdf= dbs.TableDefs(strTableNameSet fld = tdf.CreateField(strFieldName,dbBooleanساختن و اضافه کردن فیلد :tdf.Fields.Append fld
Set prop=dbs.CreateProperty("DisplayControl
dbInteger, acCheckBox)
اضاف کردن پراپرتی به مجموعه پراپرتی های شی :
fld.Properties.Append prop
پاک کردن از حافظه موقت :Set prop = Nothing Set fld = Nothing Set tdf = Nothing Set dbs = Nothing End Sub
تغییر پراپرتی کپشن یک فیلد از جدول مشخص شده با استفاده از کالکشن TableDefs ، حدس بزنید و زیر این یادداشت نظر بدهید
A TableDefs collection contains all stored TableDef objects in a database (Microsoft Access workspaces only)
مجموعه TableDefs حاوی تمام اشیا TableDef ذخیره شده در یک دیتا بیس است.
اگر فیلد مورد نظر پراپرتی کپشن نداشته باشد اکسس اروری را ران می کند و چنانچه این قابلیت اضافه شدن را داشته باشد با CreateProperty میشود این خاصیت را به آن فیلد اضافه کرد مثلا فیلد تاریخ کپشن نمی تواند داشته باشد پس سعی در اضافه کردن نداشته باشید
A Form object is a member of the Forms collection, which is a collection of all currently open forms. Within the Forms collection, individual forms are indexed beginning with zero. You can refer to an individual Form object in the Forms collection either by referring to the form by name, or by referring to its index within the collection.
شی form عضوی از کالکشن یا مجموعه forms است که محل جمع آوری تمام فرم هایی است که بازشده اند ، داخل این مجموعه forms فرم های تکی وجود دارند که ایندکس گذاری شده اند و با صفر شروع می شوند.شی فرم تکی در مجموعه forms یا با ارجاع به فرم از طریق اسم یا ایندکسشون انجام می پذیرد.
If you want to refer to a specific form in the Forms collection, it's better to refer to the form by name because a form's collection index may change. If the form name includes a space, the name must be surrounded by brackets ([ ]).
نکته خیلی مهم :
اگر می خواهید به فرم خاصی در مجموعه forms ارجاع بدهید بهتر است توسط نامش باشد چرا که ایندکس آن می تواند تغییر پیدا کند.اگر اسم فرم شامل Space باشد ( فضای خالی بین اسم باشد ) اسم فرم می بایست توسط براکت احاطه شده باشد.
Each Form object has a Controls collection, which contains all controls on the form. You can refer to a control on a form either by implicitly or explicitly referring to the Controls collection. Your code will be faster if you refer to the Controls collection implicitly.
هر شی آبجکت یک مجموعه کنترل هایی دارد که محتوی تمام کنترل ها در فرم است. شما می توانید به یک کنترل در فرم یا بطور ضمنی یا صریح ارجاع بدهید.کد شما سریعتر عمل خواهد کرد اگر بصورت ضمنی به مجموعه کنترل ها ارجاع دهید.
Forms!OrderForm.ctlSubForm.Form!Controls.NewData
فرم Order که سابفرم ctlSubform دارد و کنترل NewData در آن است که به این کنترل ارجاع داده شده.
AllForms!formname | AllForms!OrderForm |
AllForms![form name] | AllForms![Order Form] |
AllForms("formname") | AllForms("OrderForm") |
AllForms(index) | AllForms(0) |
تشریح یکی از خاصیت های مربوطه ( RecordSoutce ) :
The next example changes a form's record source to a single record in the Customers table, depending on the company name selected in the cmboCompanyName combo box control. The combo box is filled by an SQL statement that returns the customer ID (in the bound column) and the company name. The CustomerID has a Text data type.
مثال پائین منبع رکورد فرم در جدول Custom را به رکورد منفرد تغییر میدهد طبق نام شرکت که در کنترل کمبو باکس cmbocompanyname انتخاب شود.کنترل کمبو توسط زبان اس کیو ال پر شده و آیدی مشتری نام شرکت را بر می گرداند.دیتا تایپ آیدی مشتری از نوع تکست است.
Sub cmboCompanyName_AfterUpdate()
Dim strNewRecord As String
strNewRecord = "SELECT * FROM Customer Where CustomerID='" & Me!cmboCompanyName.Value & "'"
Me.RecordSource = strNewRecord
End Sub
خاصیت آیتم از آبجکت AllForms در اکسس :
The Item property returns a specific member of a collection either by position or by index. Read-only AccessObject.
You can use the SetFocus method to move the focus to a subform, which is a type of control. You can also move the focus to a control on a subform by using the SetFocus method twice, moving the focus first to the subform and then to the control on the subform.
شما می توانید برای انتقال فوکس به سابفرم که نوعی از کنترل هست از روش SetFocus استفاده نمائید همچنین می توانید فوکس را به یک کنترل در سابفرم با بکارگیری دوبار از این متد ببرید. انتقال فوکس اول به سابفرم و سپس به کنترل موجود در آن.
ا ول باز کردن فرآیند
دوم اجرای اپلیکیشن
سوم منتظر برای اعلام اتمام فرآیند
چهارم بستن پنجره
Option Compare Database
Option ExplicitPublic Declare Function OpenProcess Lib "kernel32" _(ByVal dwDesiredAccess As Long, _ByVal dwProcessId As Long) As LongByVal bInheritHandle As Long, _(ByVal hProcess As Long, lpExitCode As Long) As LongPublic Declare Function GetExitCodeProcess Lib "kernel32" _Public Const PROCESS_QUERY_INFORMATION = &H400Public Declare Function CloseHandle Lib "kernel32" _(ByVal hObject As Long) As LongDim hProcess As LongPublic Const STATUS_PENDING = &H103&Public Function checkShell(Optional procID As Long)Dim processID As LonghProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, processID)Dim exitCode As Long'processID = procIDprocessID = Shell("c:\windows\notepad.exe")DoMsgBox "The shelled process " & processID & " has ended."Call GetExitCodeProcess(hProcess, exitCode)DoEventsCall CloseHandle(hProcess)Loop While exitCode = STATUS_PENDINGEnd Function
Once your application has located a file object, the next step is often to act on it in some way. For instance, your application might want to launch another application that allows the user to modify a data file. If the file of interest is an executable, your application might want to simply launch it
اقدام بعدی بعد از قرار گرفتن فایل اغلب برای عمل کردن روی آن است مثلا اپلیکیشن شما می تواند درخواست لانچ یا پرتاب کردن اپلیکیشن دیگری را داده و به کاربر اجازه اصلاح داده های آن سند که در اپلیکیشنش باز شده را بدهد ( Word یک اپلیکیشن است و سند آن با پسوند Doc و Docx در آن باز میشود جهت ویرایش یا اضافه کردن ) . اگر فایل مورد نظر شما اجرایی باشد اپلیکیش شما به راحتی آنرا پرتاب میکند ( باز )
عملی را روی فایل خاصی انجام میدهد.
مثل Edit ، Open یا Explore ، Print و جنس آن از نوع String است.
طبق روش زیر برای ویندوز ۶۴ بیت قبل از فانکشن PtrSafe قرار گرفته بغیر از hWnd که نمایانگر پنجره است و nShowCmd که نمایانگر نمایش پنجره در وضعیت هایی است و از نوع عددی ( Long ) هستند بقیه پارامترها از نوع String می باشند.
#If VBA7 Then
Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#Else
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#End If
lpFile specifies a document file, lpParameters should be NULL.
اگر lpFile سندی را مشخص کند lpParameters نمی تواند Null باشد.
The flags that specify how an application is to be displayed when it is opened. If lpFile specifies a document file,
nShow مشخص میکند چگونه یک اپلیکیشن زمانیکه باز میشود نمایش داده شود اگر lpFile یک فایلی مثل Word را مشخص نماید.
If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the failure.
اگر تابع درست انجام شود یک مقداری بزرگتر از ۳۲ را برمی گرداند می توانید با Msgbox در اکسس ببینید و اگر Fail دهد یا درست انجام نشود مقداری که علت انجام نشدنش باشد را نشان می دهد فرضا اگر دسترسی به فایل نداشته باشیم.
مثال بالا که از سایت گرفته شده نمایانگر این است که اگر دسترسی به فایلی امکانپذیر نبود بعلت محدودیت از طرف ادمین جعبه پیامی را باز کرده و به شما اعلام می نماید. ( GetDeskTopWindow یک هندل است که می بایست تابع آنرا در Module اضافه کنید در اینترنت تابع مورد نظر موجود است حتما از CloseHandle استفاده کنید.
Constant | Value | Description |
vbHide | 0 | Window is hidden and focus is passed to the hidden window. |
vbNormalFocus | 1 | Window has focus and is restored to its original size and position. |
vbMinimizedFocus | 2 | Window is displayed as an icon with focus. |
vbMaximizedFocus | 3 | Window is maximized with focus. |
vbNormalNoFocus | 4 | Window is restored to its most recent size and position. The currently active window remains active. |
vbMinimizedNoFocus | 6 | Window is displayed as an icon. The currently active window remains active. |
اکسس یونیکد فارسی را پشتیبانی نمی کند فرضا اگر اسم فایلی با اعداد فارسی ذخیره شده باشد زمانیکه آنرا بعنوان داده به یک فیلد از جدولی Extract می کنید جای کاراکترها علامت سوال زده میشود ( امتحان کنید موضوع اکسترکت کردن با آبجکت Scripting.FileSystemObject است ) در نتیجه مجبورید مراحلی را بروید تا به همان صورتی که در اکسپلورر می بینید در جدول هم مشاهده کنید. ( اول استفاده از تابعAscW : اگر Asc خالی باشد برای گرفتن اسکی کد و اگر با W باشد گرفتن یونیکد کاراکتر مشخص شده سپس قر اردادن آن در $Hex )
برای روش تبدیل Hex به Decimal لینک زیر را مطالعه کنید ( آنچه را نمی دانید سایت های خارجی برایتان به نمایش خواهند گذاشت پس مطالعه و تحقیق کنید )
how-to-convert-hex-to-decimal-in-access
به ترتیب از سمت چپ پوزیشن ، دسیمال ، نام و نمایش ( اپیرنس)
در VBE یا Visual Basic Editor می توانید با تابع ( Chrw(1776 یا $Chrعدد ۰ را مشاهده کنید.
اگر شما می خواید اعداد فارسی رو نمایش بدین، بهتره کد اسکی عدد رو با کد یونیکد اون جایگزین کنید یعنی:
text = text.Replace("0", ChrW(&H6F0)) ' ۰
text = text.Replace("1", ChrW(&H6F1)) ' ۱
text = text.Replace("2", ChrW(&H6F2)) ' ۲
text = text.Replace("3", ChrW(&H6F3)) ' ۳
text = text.Replace("4", ChrW(&H6F4)) ' ۴
text = text.Replace("5", ChrW(&H6F5)) ' ۵
text = text.Replace("6", ChrW(&H6F6)) ' ۶
text = text.Replace("7", ChrW(&H6F7)) ' ۷
text = text.Replace("8", ChrW(&H6F8)) ' ۸
text = text.Replace("9", ChrW(&H6F9)) ' ۹
(۷DF)۱۶
۷DF = (7 * 162) + (13 * 161) + (15 * 160) ۷DF = (7 * 256) + (13 * 16) + (15 * 1) ۷DF = 1792 + 208 + 15 ۷DF = 2015
(0^6F0=(6*16^2)+(15*16^1)+(0*16
(6F0=(6*256)+(15*16)+(0*1
6F0=1536+240
6F0=1776
ChrW(1776)=۰
("Set fso = CreateObject("scripting.filesystemobject
(Set fldr = fso.GetFolder(path
For Each f In fldr.FILES
"fso.movefile "d:\ips\" & folder & "\" & f.name, "d:\ips\" & folder & "\" & folder & "_" & t & ".jpg
کنترل باتن ام دار از M1 تا M4 و کنترل اس دار از S1 تا S10 ( در سمت راست تصویر و فیروزه ای رنگ )
جدول MENU و SUB
نحوه ی عمل :
1-تعریف متغیری بنام MnuPressed از نوع Boolean در اول رویه برای اینکه اگر همان باتن با پیشوند M فشرده شد ( تعریف متغیر Mnu در اول رویه برای ذخیره باتن با پیشوند M فشرده شده ) برابر شود با Not MnuPressed در غیر اینصورت True شود.
2-ذخیره عدد انتهای باتن با پیشوند M در متغیری
3-اگر Type در جدول Menu برابر Side شده متغیر دیگر تعریف شده را برابر 1 قرار می دهیم چرا که باید باتن ها با پیشوند S در کنار باتن فشرده شده قرار گیرد.
4-تعریف متغیری با نام مثلا SubCount برای شمارش تعداد Sub ها با توجه به منو که در جدول Sub ثبت شده و در جلورانی باتن های M استفاده میشود
5-زدن لوپ در M ها با استفاده از For....Next در لوپ پراپرتی Top کنترل باتن های M دار برابر میشوند با پراپرتی TAG آنها ( که قبلا در لود فرم مقدار داده شده و سپس کپشن ها میشوند نام باتن های M دار .... اگر متغیر لوپی فرضا i بزرگتر از مقدار متغیری بود که عدد آخر باتن M دار فشرده شده را ذخیره می کرد بود آنگاه پراپرتی Top آنها براب می شوند با پراپرتی Top + ارتفاع کنترل فشرده شده * متغیری که تعداد ساب منو در جدول Sub را نگهداری میکند یا فرضا همان SubCount که باعث جلو رفتن باتن های بعد میشود. در این لوپ اگر MnuPressed برابر False شد یا مقدار متغیری که Side را در خودش نگه می داشت یک شد باز هم پراپرتی Top کنترل های M دار با پراپرتی Tag خودشان برابر می شوند.
6-لوپ بعدی میشود ازکوچکترین عدد آخر باتن S دار تا بزرگترین آن ( در اینجا طبق تصویر از 1 تا 10 ) در این لوپ اگر متغیر لوپی کوچکتر مساوی شمارش ساب ها بود طبق کنترل M دار فشرده شده پراپرتی Visible یک شود و در غیر اینصورت صفر ... حال میرسیم به جایی که اگر تایپ در جدول Side بود پراپرتی Top و Left چه مقداری بگیرند ... اگر متغیری که Type را در خودش نگه میدارد برابر یک شد یعنی باتن های S دار می بایست در کنار باتن M دار فشرده شده قرار گیرند لذا پراپرتی Top می شود پراپرتی Top باتن M دار فشرده شده + ارتفاع آن در متغیر لوپی - دوباره ارتفاع آن و پراپرتی Left باتن های S دار هم میشوند پراپرتی Left کنترل M دار ( فشرده شده ) + عرض آن + 50 در غیر اینصورت باید کنترل های S دار در زیر کنترل M دار فشرده شده قرار گیرند + ارتفاع کنترل M دار و پراپرتی Left کنترل های S دار برابر کنترل M دار فشرده شده می شود. در پایان لوپ باید اینرا هم در نظر گرفت اگر MnuPressed=Flase شد پراپرتی Top کنترل های S دار برابر پراپرتی Tag آنها شوند ( که در رویداد لود فرم ذخیره میشوند ) و پراپرتی Left آنها نیز میشود پراپرتی Left یکی از کنترل های S دار که می توان متغیری را در اول رویه تعریف کرد و مقدار را در آن ذخیره نمود.
متغیرهای تعریف شده در اول رویه ( در هر لحظه و یا جابجایی از کنترلی تغییر می کنند و ثابت نیستند که فقط در یک رویداد خاص استفاده شوند
Private MnuPressed As Boolean
متغیری که در تمام رویه فرم جاری استفاده میشود و پراپرتی لفت یکی از کنترل های اس دار را نگهداری میکند Private SubLeft
متغیری که نام باتن ام دار فشرده شده که در انتهای تابع نوشته شده را ذخیره می کند و در لحظه تغییر میکند Private MNU
متغیرهای تعیرف شده در تابع متاثر از کلیک باتن های M دار فقط در تابع استفاده می شوند و مثل متغیر های بالا تغییر نمی کنند
متغیر لوپی به تعداد باتن های ام دار Dim I
متغیر لوپی به تعداد باتن های اس دار Dim j
متغیر نگهداری تایپ در جدول منو (Dim W (Type
متغیر نگهداری شمارش باتن های اس دار طبق کنترل ام دار فشرده شده از جدول ساب Dim SubCount
در فرم یک در بالای فرم در نمای دیزاین ۳ لیبل طراحی شده از M0 تا M2 بعنوان منو ، هفت لیبل دیگر بطور زیرهم بعنوان ساب از S0 تا S7 ایجاد شده و کنار آنها دوباره هفت لیبل دیگر بعنوان ساب ساب از SS0 تا SS7 قرارداده شده ، در انتهای لیبل های بعنوان ساب ( S0 تا S7 ) دوباره 7 لیبل از Z0 تاZ7 ایجاد شده برای قرار دادن فلشها در کپشن آنها پس جمعا ( 1X3+3X7 )
ترتیب فیلدها ازراست به چپ است اینجا برعکس افتاده
Mnu | Title |
---|---|
M0 | ایران |
M1 | اکسس |
M2 | پروفسور |
Mnu | Sub | Title | Type |
---|---|---|---|
M0 | S0 | Access | |
M1 | S0 | VBA | |
M1 | S1 | Menu | |
M2 | S0 | AccessVba | |
M2 | S1 | . | |
M2 | S2 | BlogSky | DropDown |
M2 | S3 | . | |
M2 | S4 | Com |
Mnu | Sub | SubSub | Title |
---|---|---|---|
M0 | S0 | SS0 | MNU0SUB0SUB0 |
M0 | S0 | SS1 | MNU0SUB0SUB1 |
M0 | S0 | SS2 | MNU0SUB0SUB2 |
M0 | S0 | SS3 | MNU0SUB0SUB3 |
M0 | S0 | SS4 | MNU0SUB0SUB4 |
M1 | S1 | SS0 | MNU1SUB1SUB0 |
M1 | S1 | SS1 | MNU1SUB1SUB1 |
M2 | S0 | SS0 | MNU2SUB0SUB0 |
M2 | S0 | SS1 | MNU2SUB0SUB1 |
M2 | S0 | SS2 | MNU2SUB0SUB2 |
M2 | S0 | SS3 | MNU2SUB0SUB3 |
M2 | S0 | SS4 | MNU2SUB0SUB4 |
M2 | S0 | SS5 | MNU2SUB0SUB5 |
M2 | S0 | SS6 | MNU2SUB0SUB6 |
M2 | S1 | SS0 | MNU2SUB1SUB0 |
M2 | S2 | SS0 | MNU2SUB2SUB0 |
M2 | S2 | SS1 | MNU2SUB2SUB1 |
M2 | S3 | SS0 | MNU2SUB3SUB0 |
M2 | S3 | SS1 | MNU2SUB3SUB1 |
M2 | S3 | SS2 | MNU2SUB3SUB2 |
M2 | S3 | SS3 | MNU2SUB3SUB3 |
استفاده از یونیکد برای فلش ها :
(Chrw(9658
(Chrw(9650
(Chrw(9660
از دوتابع MnuClk و SubClk استفاده شده که تابع اول برای زمانیست که روی لیبل های بالایی ( بعنوان منو ) رویداد کلیک باصطلاح فایر شود و لیبل های پایینی مشاهده شوند یا نشوند ( ذخیره 1 در پراپرتی Tag کنترل منو زمانیکه که لیبل فشرده شد ) و دومی برای انجام رویداد کلیک لیبل هایی که در پایین لیبل های بالایی قرار می گیرند ، برای تغییر رنگ لیبل های ساب هم از تابع SubMouseMove استفاده شده.
شرح تابع SubClk ، تابعی که زمان فشرده شدن یکی از هفت لیبل های بانام S0 تا S7 باید وظیفه ای را انجام دهد یا باز کردن فرم و گزارش خاصی و یا هر عمل دیگری و یا خودش زیر منوهایی در دل خودش داردکه باید در زیر یا کنار آن Visible شوند :
نکته : زمان فشرده شدن لیبل های بالایی ( M0 تا M2 ) باید نام لیبل فشرده شده ( تابع MnuClk ) را در متغیری ذخیره کرد چرا ؟ بخاطر اینکه باید در عبارت پایینی که توضیح داده شده استفاده کرد ( یعنی باید در جدول Sub و منوی فشرده شده طبق فیلد Mnu پیدا کند که فیلد Type حاوی رشته ی DropDown است یا خیر!!! )
در شروع تابع می بایست در نظر گرفت اگر سابی فشرده شد که طبق منوی فشرده شده در فیلد Type آن DropDown بود به چه نحو عمل شود که زمان لوپ زدن در SS0 تا SS7 بفهمانیم باید لیبل های ساب زیر ساب فشرده شده به پائین تر منتقل شده تا لیبل های SS0 تا SS7 جای خالی آنها قرار گیرند برای اینکار از تابع DlookUp استفاده می کنیم
PP متغیریست که عدد انتهای لیبل ساب فشرده شده ( با پیشوند S ) را در خود ذخیره میکند و در پائین بردن لیبل های ساب بعد از لیبل ساب فشرده شده بما کمک خواهد کرد.
("","PP=Replace(C.Name,"S
تابع زیرطبق گفته بالا چک میکند که فیلد Type در جدول Sub طبق منوی فشرده شده و برابر بودنش با فیلد Mnu معادل DropDown است یا Null متغیر Mn در اول رویه تعریف شده و در تابع MnuClk مقدار میگیرد چون برای LookUp به نام منو نیاز داریم
" if DlookUp("Type","Sub","Mnu='" & Mn & "'")="DropDown Then
متغیر Drop نوع Boolean یا میتواند عددی باشد Integer
Drop=True
End If
در بعد از لوپ می بایست در یک متغیر لیبل فشرده شده را ذخیره کرد و در قبل از لوپ نوشت تا درصورتیکه لیبل فشرده شده مخالف مقدار آن متغیر بود Z برابر یک شود
در اینجا می توانید از دو متغیر SubCount و SubSubCount استفاده کنید
( "'" & SubCount=Dcount("Sub","Sub","Mnu='" & C.Name
از SubSubCount برای شمارش تعداد لیبل هایی ( SS0 تا SS 7 طبق جدول SubSub و لیبلی که [ بعنوان منو ] کلیک و در Mn ذخیره شده ) که باید ویزیبل شوند استفاده میشود حال نحوه ی استفاده چطور است ؟
توضیح :
در لوپی که در SS ها زده میشود ( با استفاده از For ... Next ) از 0 تا 7 باید گفته شود اگر Drop برابر Yes شود لیبل های سابی که بزرگتر از کنترل ساب فشرده شده بود به بعد از تعداد SubSub های شمرده شده در جدول SubSub برود بطور مثال اگر منوی 2 پنج Sub ( شروع از S0 تا S4 ) داشت زمان فشرده شدن لیبل با نام S2 ( از منوی با نام M2 ) بقیه ی آنها یعنی S3 و S4 به تعداد کانت فیلد SubSub در همین جدول پائین برود باضافه ی ارتفاع کنترل فشرده شده . درضمن باید بفکر این هم باشید که اگر همان کنترل S2 که عمل کرده دوباره فشرده شود کنترل های S3 و S4 به همان موقعیت قبل برگردد و پراپرتی Visible کنترل ها ی SS0 تا SS7 نیز برابر صفر شود ، پس باید متغیری نوشت از نوع Static یا در Tempvars ذخیره کرد
در اینجا باید DlookUp بنویسید که پراپرتی ویزیبل SS ها طبق جدول SubSub مخالف عددی غیر از صفر شوند تا قابل مشاهده شوند
If Drop=Yes Then
باید روی لیبل های بعد از لیبل فشرده شده اعمال شود بخاطر همین باضافه یک کردیم
PP=PP+1
اگر لیبل فشرده شده ( در اینجا فرضا عدد PP دو است و باضافه ی یک شده ) کمتر از SubCount که 5 است شد و برای یکبار هم فشرده شد (""= Z) پراپرتی Top کنترل 3 میشود مقدار پراپرتی Top کنترل 3 باضافه ارتفاع کنترل فشرده شده در تعداد SS ها که در زیر S2 باید قرار گیرند
if PP<SubCount And Z=1 Then
Controls("S" & PP).Top=Controls("S" & PP).Top+c.Height*SubSubCount
حال در اینجا باید ذکر کرد طبق If بالا Z=1 شد یعنی لیبل S2 دوباره فشرده شد لیبل های S3 و S4 به موقعیت اول برگردند فرضا از پراپرتی Tag این لیبل ها استفاده کنید و در تابع MnuClk در لوپ زده شده اعلام کنید که Tag کل لیبل های S بشود مقدار پراپرتی Top آنها. در ضمن پراپرتی ویزیبل لیبل با پیشوند SS باید صفر شود.
End If
و در اینجا لفت ها را تعیین میکنید
در غیر اینصورت اگر Drop برابر Yes نبود مقدار Top و Left لیبل های SS تنطیم میشود که در پهلوی لیبل S دار قرار گیرند
پیشوند لیبل منو M
پیشوند لیبل ساب که در زیر لیبل منو قرار میگیرد S
پیشوند لیبل سابی که در کنارلیبل ساب یا زیر آن قرار می گیرد SS
پیشوند لیبلی که در کپشن آن فلش های بالا پایین و راست قرار می گیرد Z
دو جدول ساخته شد یکی شامل دو فیلد Mnu و Title برای رکورد کردن نامگذاری منوها و عنوان آنها ، در شکل زیر لیبل از سمت راست به چپ با نام های M0 تا M2 می باشند.
جدول Sub با فیلدهای Mnu ، Sub ، Title که نام های منو ساب منو و عنوان ساب منو در آن رکورد میشوند، نامگذاری لیبل های زیر منو طبق تصویر از S0 تا S7 است.
دستور کار :
1-تعریف متغیر M در بالاترین رویه برای ذخیره کنترل فشرده شده
2-تعریف متغیر MnuBkColor در بالاترین رویه برای ذخیره کردن BackColor کنترل لیبل منو که System Menu Bar تنظیم شده
3-زمان لود شدن فرم مقدار متغیر MnuBkColor برابر با پراپرتی BackColor یکی از لیبل ها شود فرضا M0.BackColor
در هرکدام از رویدادهای کلیک لیبل های شکل یک بعنوان منو یک تابع نوشته شده به ترتیب زیر :
1-در تابع اگر کنترل فشرده شده مخالف M و M نال نبود سپس پراپرتی BackColor مقداری که در M ذخیره شده بشود
2-تنظیم پراپرتی BackColor کنترل فشرده شده به (RGB(160,200,160
3-برابر کردن M با کنترل فشرده شده
4-بخاطر اینکه زمان فشرده شده روی منو اگر قبلا فشرده نشده پراپرتی Tag آن تغییر یابد ( برای نمایش یا ویزیبل شدن sub ها و یا ویزیبل نشدنشان ) نوشت اگر پراپرتی Tag کنترل فشرده شده برابر "" شود به 1 تغییریابد در غیر اینصورت دوباره Tag یک شود
5-لوپ در کنترل های Sub با For.....Next از 0 تا 7 مثل For i=0 To 7
6-در اینجا مقادیر پراپرتی Tag کنترل فشرده شد ( منو ) کاربرد دارد که اگر یک باشدمی بایست لیبل های Sub طبق جدول نامشان ویزیبل شوند وبقیه که در لود فرم نوشتیم کلا Visible=No همان No باشند
_ & " Me.Controls("s" & i).Visible = IIf(DLookup("Sub", "Sub", "mnu='" & c.Name & "' and
(Sub='" & Controls("s" & i).Name & "'") <> "", True, False"
_& " Me.Controls("s" & i).Caption = Nz(DLookup("Title", "Sub", "mnu='" & c.Name & "' and
"'" & Sub="'" & Controls("s" & i).Name
Me.Controls("s" & i).Left = c.Left
(Me.Controls("s" & i).BackColor = RGB(160, 200, 160
در غیر اینصورت پراپرتی Visible کل لیبل های Sub به No تنظیم شوند که هاید شوند و پراپرتی BackColor کنترل فشرده شده ( منو ) نیز به MnuBkColor تنظیم شود
کالر لیبل های سابی ( منظور لیبل های عمودی ) که به آبی تغییر پیدا می کنند از رویداد MouseMove آنها استفاده شده و در اینجا هم نیاز به ذخیره کردن نام ساب در یک متغیر است برای مقایسه کردن و تغییر رنگ به جدید و برگرداندن به رنگ قبلی
دور لیبل های بالا بعنوان منو با کنترل لاین که در نوار Design فرم است کشیده شده