کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

به اشتراک گذاری اطلاعات کسب شده در اکسس از سایت آفیس و سایت های تخصصی خارجی
کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

کلینیک فوق تخصصی اکسس ( کاربرد vba در اکسس )

به اشتراک گذاری اطلاعات کسب شده در اکسس از سایت آفیس و سایت های تخصصی خارجی

اکسپورت آبجکت ذخیره شده به فایل Txt


برای اکسپورت از متد Docmd.TransferText استفاده می کنیم 


DoCmd.TransferText acExportDelim,"Standard Output   "External Report", "C:\Txtfiles\April.doc,"


مثال بالا جدول External Report  از دیتابیس اکسس که با نام Standard Output با Docmd.RunSavedImporExport ذخیره شده است را به فایل April  اکسپورت میکند با جداکننده.


البته مثل تصویر بالا حتما Import یا Export را بصورت قرار دادی مشخص کنید تا اشتباه نگیرید 



acExportDelim2Export Delimited
acExportFixed3Export Fixed Width
acExportHTML8Export HTML
acExportMerge4Export Microsot Word Merge
acImportDelim0Import Delimited
acImportFixed1Import Fixed Width
acImportHTML7Import HTML
acLinkDelim5Link Delimited
acLinkFixed6Link Fixed Width
acLinkHTML9Link HTML

                                                                        
              

حذف فیلتر/اعمال فیلتر



برای حذف فیلترهای اعمال شده در جدول ، کوئری یا مجموعه ای از رکوردها در فرم یا سابفرم از متد زیر استفاده می شود.



DoCmd.ShowAllRecords





برای فیلتر کردن فرضا مجموعه ای از رکوردها در سابفرم یا کانتینیوس فرم از متد زیر استفاده خواهیم کرد . در کل برای رکوردهای جدول کوئری فرم فعال و فوکس شده . زمان لود شدن آبجکت بصورت اتومات اعمال میشوند بنابراین پراپرتی FilterOnLoad را برابر True قرار دهید.      


کد زیر آبجکت فعال را فیلتر می کند تا اینکه فقط رکوردهایی را نمایش دهد که با NWTB شروع شوند .

_  " Docmd.SetFilter , "[Product Code] Like
"""*NTWB"

از Docmd.ApplyFilter هم میتوان بهره برد.

اعتبارسنجی تاریخ شمسی


Function CheckValidShamsiDate(Dt) As Boolean 

اگر فرمت بدین شکل باشد و / در فیلد ذخیره شود و سال هم چهار رقمی باشد               0000/00/00

 

((Y=Val(Mid(Dt,1,4

((M=val(Mid(Dt,6,2

((D=Val(Mid(Dt,9,2


If Y<1 And Y>2500 Then

CheckValidShamsiDate=False

End if


Select Case M 

     Case 1 To 6 

        If D>31 And D<1 Then 

         CheckValidShamsiDate=False

       End if 

      Case 7 To 11

      If D>30 And D<1 Then 

        CheckValidShamsiDate=False

      End if

     Case 12 

     If KabisehShamsi(Y)=True Then

    If D>30 And D<1 Then CheckValidShamsiDate=False  

Else if KabisehShamsi(Y)=False 

    If D>29 Abd D<1 Then CheckValidShamsiDate=False  

        End if

End Select


تابع بالا را میتوان در رویداد Exit تکست باکس نوشت که اگر False شد Cancel برابر True شود. چک کردن سال کبیسه ی شمسی هم مفصل در جای دیگر بحث شده.

بلنک رکورد یا لاین خالی در گزارش ( حقه )



برامون پیش اومده که وقتی فاکتور صادر می کنیم میخواهیم  یه چیزی شبیه فاکتور باشه یا مثل اکسل ردیف ها را تا آخر در پرینت ببینیم ... فرض کنید شما تو فاکتورتون ۳ آیتم داریم ولی خط و خطوط باید تا پائین صفحه ی گزارش رسم بشه اگر نخواهید کنترل ها را بصورت Grow استفاده کنید ( منظور اگر شرح بیشتر شد از عرض کنترل اون کنترل  تعریض یا اکسپند میشه تا محتویاتش رو راحت ببینیم )  می تونید امتحان کنید که در ارتفاع دیتیل در گزارش چقدر لاین جا می گیره به نسبتش یه کوئری ایجاد می کنید با آیدی از فرضا 1 تا ۴۰ و فیلدی  که تماما خالیه بعد زمان باز شدن گزارش می گید که اون منبع گزارشتون با کوئری ساخته شده تجمیع بشه Union و بعد در شرط کوئری که ساختید و در یونیون استفاده می کنید می نویسید که  آیدی  هایی رو لیست کنه که کانت منبع گزارش ( با استفاده از تابع Dcount )  


فرض مثال جدول  فاکتور شامل فیلدهای زیر باشد 

FactorNo PartNo Desc Qty UnitPrice Totals 

ایجاد جدول بصورت  بنام BlankFactor شامل فیلدهای 

BlankId BlnkDesc 

در یونیون حتما باید تعداد فیلدهای جدول یکی باشن اسامی فیلدها مهم نیست فقط دیتا تایپشون مغایرت نداشته باشه !!!


Select * From tblFactor 

                      Union All

در سلکت زیر چون بایدتعداد فیلدها با تعداد فیلدهای سلکت بالائی یکی شود به تعداد باقیمانده از دابل کوتیشن استفاده کردیم 

 "","","","","",Select BlankDesc

Where BlankId>Dcount("*","tblFactor,"FactorID=" & tblFactor.FactorNo  


در مثال فوق اگر شماره ی فاکتور را از باکسی در فرم بگیرد باید در شرط جای tblFactor.FactorNo آدرس کنترل در فرم یا سابفرم اعمال شود در اینجا شماره فاکتور ، دیتا تایپ  نامبر گرفته شده که سرعت بالاتری در سرچ نسبت به دیتا تایپ تکست دارد 


Forms!Form1!txtFactorNo

پراپرتی نمایش بلنک رکورد در گزارش


Report.NextRecord Property


Property NextRecord مشخص می کند که آیا سکشن مربوطه باید به رکورد بعدی پیش برود یا خیر که بصورت Boolean هست و در رویداد OnFormat قرار داده می شود .


پراپرتی مهم و کم کاربرد است 


فرض کنید هر ۱۰ خط یا Line را در گزارش ( پرینت پرویو ) می خواهید جدا کنید ( توضیح واضح تر بعد از هر رکورد یک جای خالی باقی بگذارد یعنی به رکورد بعدی پیش نرود و بعد از آن لاین خالی دوباره رکوردها نمایش یابند ) یک کانتر در رویداد OnPrint دیتیل آن درست می کنید که اگر اون کانتر Mod ده برابر صفر شد NextRecord ترو شود PrintSection را هم می توانید ترو کنید ... برای ریست شدن کانتر از رویداد Format سکشن Header استفاده کنید که کانتر را صفر کند.


  البته در مورد بالا باید یک نشانگر قرار دهید که اگر آن نشانگر برابر False شد آن سکشن رکوردها را طبق کانتر نمایش دهد و در صورتیکه به ۱۰ رسید به رکورد بعدی نرود و جای خالی بیاندازد یا بعبارتی  رکورد بعد از لاین ۱۰ در خط بعد از آن جای خالی قرار گیرند. (   وقتی امتحان کنید لاین  بعدی که نباید رکورد بعد از ده قرار گیرد همان  تکرار رکورد ۱۰ است )

ایجاد کوئری در اکسس QueryDef


شی QueryDef یک تعریف ذخیره شده ای از کوئری در موتور دیتابیس اکسس هست که ازآن برای ساخت کوئری استفاده خواهد کرد . ( و حتی مقداردهی پارامتر ) 


Dim Qry As QueryDef

Set Qry=CurrentDb.CreateQueryDefs("Select * From

("Table1 Where Id>=14

استفاده از پارامتر 

Dim qdf As QueryDef

("Set qdf = dbs.QueryDefs("myActionQuery

                            Set the value of the QueryDef's parameter'

تنظیم مقدار یا مقداردهی پارامتر

_ =qdf.Parameters("Organization").Value

"Microsoft"

کامندهای اجرائی در اکسس RunCommand

....Docmd.Runcommand acCmd


acCmdZoom100

acCmdUndo

acCmdSelectRecord

acCmdSelectAll

acCmdSaveRecord

acCmdRowHeight

acCmdRemoveAllFilters

acCmdRefresh

acCmdRedo

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

acCmdRecordsGoToFirst

acCmdRecordsGoToLast

acCmdRecordsGoToNew

acCmdRecordsGoToNext

acCmdQueryTotals

acCmdPrintPreview

acCmdPrint

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

acCmdCopy

acCmdCut

acCmdPaste

acCmdDelete

acCmdLayoutView

acCmdFind    باکس Search Find 

acCmdExportText

acCmdExportAccess

acCmdDesignView

acCmdDeleteRecord

acCmdDeleteRows

acCmdDataEntry

acCmdControlMarginsNarrow

acCmdCloseDatabase

acCmdCloseWindow

acCmdCloseAll

acCmdClearAll

acCmdChangeToComboBox

   در دیزاین فقط میشود کنترلی را تغییر داد پس تلاش نکنید در ویو استفاده کنید 

acCmdAppMaximize

acCmdAppMinimize

acCmdAppMove

acCmdAppRestore

ساخت شورتکات منو در اکسس ۲۰۱۶



شورتکات : 

سه تا کامند باتن در کامندباربصورت MsoPopup برای پرینت ، رفرش و بستن فرم ContactList




اسم ماکروی بالا mcrAddShortcutMenu را در قسمت پراپرتی ShortCutMenu تایپ می شود با AddMenu در Add-In ریبون قابل مشاهده هست.



کامند باتن در CommandBar و ساب منو بهمراه کامند ها



بصورت زیر نمایان خواهد شد. برای ایجاد ساب منو در تصویر بالا  از AddMenu استفاده شده و یک ماکروی با نام SubMenuCommands با فرمان ساب ماکرو داخلش ساخته شده و در MacroName اظهارشده .



 در باکس ادیت  SubMacro می توان  از کلیدهایی برای انجام کارهائی استفاده کرد یا عملکرد آنها را غیر فعال کرد  فرضا     p^ منظور Ctrl+p هست  فرضا شما می خواهید فرمان انجام نشود در نتیجه در خط بعدی CancelEvent را می توانید انتخاب و ماکرو را با عنوان AutoKeys ( فقط به این نام ) ذخیره کنید.


در سطح پیشرفته تر یعنی استفاده از Commandar.Controls Properties باید حتما از رفرنس Microsoft Object Library انتخاب شود تا بتوانید از  پراپرتیهای آن استفاده نمائید.


https://docs.microsoft.com/en-us/office/vba/api/office.commandbar.controls


سطح دسترسی User Level

نمونه ای از سطح دسترسی 



()Private Sub Form_Load
Dim sPermit As String
Dim iAccess As Integer
Dim Ctl As Access.Control
("Me.txtUser = Environ("username
If IsNothing(Me.txtUser) The
"sPermit = "ReadOnly
Else
"sPermit = "ReadOnly
Select Case sPermit
(sPermit = GetPermission(Me.txtUser
End If
iAccess = 3
"Case "Edit
iAccess = 2
"Case "Admin
Me.txtLevel = iAccess
Case Else
iAccess = 1
End Sub
End Select


()Private Sub Form_Load
If Forms!frmMenu!txtLevel < 11 Then
Me.AllowEdits = False
Else
Me.AllowEdits = True
End If
End Sub
(Private Function GetPermission(sUser As String
_ & "'= If (IsNothing(DLookup("Permissions", "tblStaff", "Login
Forms!frmmenu!txtUser & "'"))) Then
"GetPermission = "ReadOnly
Else
_ & "'=GetPermission = DLookup("Permissions","tblStaff","Login
"'" & Forms!frmmenu!txtUser
End if
End Function


نمونه ی تصویری



جستجو ( DlookUp )در جدول یا کوئری

مثال زیر از متغیر intSearch برای گرفتن مقدار ( عددی ) استفاده می کند که بعنوان integer یعنی حدود ۵ رقم نهایتا تعریف میشود اگر عدد بزرگتر باشد از Long استفاده کنید 

نکته : در پنجره ی immediate window وقتی میخواهید عددی را در عدد دیگری ضرب کنید چون پیش فرض integer می گیرد پیغام Overflow را نمایش می دهد که باید آنرا به Long تبدیل یا Convert کنید فرضا      200 *(Clng(1356 ?


Dim intSearch As Integer
Dim varX As Variant
intSearch = 1
_ ,"varX = DLookup("[CompanyName]", "Shippers
("[ShipperID] = " & intSearch]"

در مورد بالا نام کمپانی را از جدول/ کوئری Shippers درصورتیکه مقدار ShipperID آن برابر متغیر اظهارشده بود( یعنی یک ) بازیابی میکند اگر Null باشد ارور Null را بر می گرداند پس صحیح است که بعد ازآن به نمونه روش ذیل عمل کنیم

If IsNull(Varx) =False Or Varx<>"" Then
End if

اگر شرط مورد جستجو عدد نبود یعنی تکست یا به قولی متنی باید شرط بصورت زیر تغییر یعنی تک کوتیشن به اول و آخر عبارت اضافه میشود " ' عبارت ' "

"'=Dlookup("CompanyName","Query1","FamilyName
"'" & Me.TxtSearch &
در مثال فوق اسم شرکت از کوئری یک را بازیابی می کند زمانیکه مقدار txtSearch که تکست هست با فیلد FamilyName برابر باشد. اگر txtSearch در سابفرم باشد باید به آن ارجاع داد فرضا فرم اصلی را MainForm و اسم سابفرمی که txtSearch در آن وجود دارد Sub1 درنظر بگیرید .

& "'=FamilyName"
"'" & Forms!MainForm!Sub1.Form!TxtSearch

بعد از Sub1 از Form استفاده کردیم چرا ؟ چون سابفرم خودش از دو لایه تشکیل شده لایه ی اول پراپرتی های مربوط به خود سابفرم است مثل LinkMaster یا LinkChild و شامل کنترهای مربوط به فرم نیست و بعدی مربوط به فرم که شامل سکشن ها منظور دیتیل و هدر و کنترل هاست
  • Byte — For integers that range from 0 to 255. Storage requirement is a single byte.

  • Integer — For integers that range from -32,768 to +32,767. Storage requirement is two bytes.

  • Long Integer — For integers that range from -2,147,483,648 to +2,147,483,647. Storage requirement is four bytes.

انتخاب آبجکت

مثال زیر فرم را انتخاب می کند 


DoCmd.SelectObject acForm, "Customers", True


تغییر نام آبجکت ( فرم ، جدول ، کوئری )


Docmd.Rename NewName,ObjectType,OldName


از متد Rename برای تغییر نام شئ دیتابیس مشخص شده مثل جدول یا کوئری بهره ببرید


Use the Rename method to rename a specified database object.


اگر ObjectType و آرگومان OldName خالی بمانند ( پس با توجه به این گفته هر دو Optional یا انتخابی هستند و می توانند خالی رها شوند - پیش فرض acDefault است یعنی هر چی که انتخاب شده بود ) اکسس آبجکت یا شئ انتخاب شده در پنجره دیتابیس ( سمت چپ که لیست فرم و جداول و ... است ) را تغییر نام می دهد. برای انتخاب شئ می توانید از متد SelectObject استفاده بنمائید با بهره گیری از آرگومان InDataBaseWindow و تنظیم آن به Yes ( True )

If you leave the ObjectType and OldName arguments blank (the default constant, acDefault, is assumed for ObjectType), Access renames the object selected in the Database window. To select an object in the Database window, you can use the SelectObject method with the InDatabaseWindow argument set to Yes (True).


Docmd.SelectObject  ObjectTypeObjectNameInNavigationPane


دو تا آرگومان آخر انتخابی هستند و می توانند خالی بمانند آرگومان آخر برای شی باز است اگر False تنظیم شود. پیش فرض InnavigationPane ( در  پنل راهبری که همان پنجره دیتابیس است ) نیز False است


DoCmd.Rename "Old Employees Table", acTable, "Employees"


Run-time error '7874':
Microsoft Access cant find the object 'Test'
مایکروسافت اکسس نمی تواند آبجکت اشاره شده را پیدا کند
یا تغییر نام دادید یا اصلا جدول یا کوئری یا فرم یا گزارش
در دیتابیس موجود نیستند.