تا بحال تاپیکی در باره این دو
و کاربردشون
و تفاوتهاشون
و این که کی از کدوم یکی بهتره استفاده کنیم،
اینجا ندیدم - حتی در حد یک توضیح ساده.
سعی میکنم بتدریج همون چند خط رو اینجا قلمی کنم.
تا بحال تاپیکی در باره این دو
و کاربردشون
و تفاوتهاشون
و این که کی از کدوم یکی بهتره استفاده کنیم،
اینجا ندیدم - حتی در حد یک توضیح ساده.
سعی میکنم بتدریج همون چند خط رو اینجا قلمی کنم.
با UDT شروع میکنیم که ساده تر هست.
UDT چیزی نیست به جز ترکیبی از چند نوع دیتا (DATA TYPE) دیگه که یک اسم بهش میدیم:
Type Category
ID As Long
Name As String
Description As String
End Type
در تعریف UDT چند نکته هست که باید دقت کنین:
- حتما باید در آغاز ماجول تعریف بشه - قبل از هر SUB یا FUNCTION
- به صورت دیفالت PUBLIC هست یعنی در کل برنامه در دسترس هست - مگر اینکه مشخص کنین PRIVATE بودنش رو.
- اگر در فرم تعریف بشه باید حتما PRIVATE باشه!
اینجا یک پرسشی ممکنه پیش بیاد که:
ما در اکسس که جدول و رکوردست و ... داریم،
پس چه نیازی به UDT هست؟
بخشی از پاسخ این هست که UDT در واقع یک مفهوم و امکان کدنویسی و مستقل از اکسس هست.
در واقع VBA یک محصول مستقل (STANDALONE) مثل VB نیست،
بلکه مایکروسافت این رو بعنوان یک زبان داخلی برای امکان تعامل و ارتباط بین نرم افزارهای خودش
از دل VB ساخت و توسعه داد.
VBA در تمام نرم افزارهای OFFICE هست و خواهد بود،
ولی در هر کدام از آنها با آبجکتهای همون سروکار داره
و برای کار با دیگر آبجکتها باید رفرنس به کتابخونه مناسب بدین.
مثلا در اکسس چیزهایی مثل TABLE, QUERY, RECORDSET, FORM, REPORT ... از پیش تعریف شده هست،
در اکسل CELL, WORKBOOK, WORKSHEET, ...
در ورد DOCUMENT, PARAGRAPH, FONT, ...
البته VBA منحصر به محصولات مایکروسافت نیست،
مثلا در AUTOCAD هم از زمانی که روی ویندوز آمد بود (در کنار AUTOLISP که از زمان DOS هم بود)
و هنوز هم هست (البته چند سالی هست که دیگه همراه خودش نصب نمیشه و باید کتابخانه اش رو جداگانه دانلود کرد)
خب،
از بحث اصلی دور نشیم.
پس دیدیم که چرا در VBA اکسس، UDT هم با وجود داشتن ساختارها و امکانات آماده مشابه هست.
متداولترین کاربرد UDT در اکسس زمانی هست که نیاز داریم یک فانکشن بیشتر از یک مقدار برگردونه.
قبلا نمونه برای این داشتیم این هست که توضیح بیشتری نیاز نداره.
وب سرويس (barnamenevis.org) پست 13 رو ببینین
کاربرد دیگه UDT در کار با روتینهای DLLها و پاس کردن (و گرفتن) مقادیر به (از) اونها هست.
برای این هم نمونه داریم:
راهنمائی در خصوص رنگ فرم (barnamenevis.org) پست شماره 7 رو ببینین
کلاس (Class) یک مفهوم عمومی برنامه نویس شی گرا هست (object oriented)
وگرچه از نظر داشتن propertyهای متفاوت مشابه UDT هست،
ولی چون میشه از کد هم در اون استفاده کرد (sub و function) ، تواناییهاش و کاربردهاش به مراتب گسترده تر و بیشتر هست،
و به همون نسبت هم نوشتن کلاس دانش بیشتری نسبت به UDT نیاز داره.
سعی میکنم مطلب رو همزمان با نوشتن یک کلاس نمونه کاربردی توضیح بدم (بتدریج).
با سلام و عرض ادب متقابل
و تشکر از لطف جنابعالی و دیگر دوستان
بحث کلاس رو ادامه میدیم:
================
در VBA نیاز هست که کلاس حتما در یک ماجول جدا و اختصاصی تعریف بشه (class module)،
به یکی از دو روش میتونیم کلاس ماجول بسازیم:
1- از منوی create و انتخاب class module
10.png
2- در محیط vba editor
در پنجره project explorer روی اسم برنامه راست کلیک و insert class module :
11.png
بر خلاف ماجول های عادی که اسم اون مهم نیست،
یک کلاس اسمش رو از اسم ماجولش میگیره و همینجور که میبینین جداگانه هم نگهداری میشه:
12.png
13.png
همینجور که دیده میشه قرار هست یک کلاس به اسم TimeSpan بسازیم.
TimeSpan در واقع نوعی از دیتا (در واقع ابجکت) هست که برای نمایش نگهداری بازه های زمانی به کار میره (با تاریخ اشتباه نگیرین)
و معمولا شامل روز، ساعت، دقیقه و ثانیه است که بنا به نیاز ممکنه میلی ثانیه یا کمتر از اون هم براش تعریف بشه،
یا فقط تا دقیقه باشه.
مطالعه بیشتر در مورد TimeSpan Struct
یک کاربرد timespan در جمع ساعت های کاری هست،
به عنوان مثال جمع کارکرد یک کارمند در ماه.
در این کلاس نمونه فرض رو براین گذاشتیم که دقت زمانی تا میلی ثانیه نیاز هست
پس نیاز داریم برای این کلاس چیزی تعریف کنیم که نشون دهنده روز، ساعت، دقیقه، ثانیه، و میلی ثانیه باشه.
این چیز رو بهش میگن property و این پراپرتی میتونه یک دیتا استاندارد vba یا خودش یک ابجکت دیگه باشه،
که روش کار با دومی کمی تفاوت داره.
برای هر پراپرتی میتونیم پروسیجرهایی (در قالب مشخص و فیکس) بنویسیم
که بشه برای اون پراپرتی مقدار تعیین کرد و یا مقدارش رو خوند.
برای خوندن پروسیجر get ، و برای نوشتن اگر یک مقدار ساده باشه let ،و اگر یک ابجکت باشه set ،
و خود پراپرتی هم میتونه private یا public باشه (بسته به نیاز و کاربرد).
در اولین گام از تعریف پراپرتی های گفته شده شروع میکنیم:
'======= Class: TimeSpan =======
Option Compare Database
Option Explicit
'======= Declarations =======
Private xDAYS As Long
Private xHOURS As Long
Private xMINUTES As Long
Private xSECONDS As Long
Private xMILLISECONDS As Long
'======= Properties =======
Public Property Get Days() As Long
Days = xDAYS
End Property
Public Property Let Days(ByVal value As Long)
xDAYS = value
End Property
'================
Public Property Get Hours() As Long
Hours = xHOURS
End Property
Public Property Let Hours(ByVal value As Long)
xHOURS = value
End Property
'================
Public Property Get Minutes() As Long
Minutes = xMINUTES
End Property
Public Property Let Minutes(ByVal value As Long)
xMINUTES = value
End Property
'================
Public Property Get Seconds() As Long
Seconds = xSECONDS
End Property
Public Property Let Seconds(ByVal value As Long)
xSECONDS = value
End Property
و به تدریج کلاس رو تکمیل میکنیم.
سلام
وقت بخیر
ان شاءالله دوستان علاقمند به یادگیری زبان برنامه نویسی VBA از کنار این آموزش های مفیدی که اساتید عزیز بدون هیچ چشمداشتی برای تهیه اون زحمت می کشن بی تفاوت رد نشن و در یادگیری و بکارگیری اونها کوشا باشن
با اجازه استاد من یه مثال ساده از type نوشتم :
Type sp
x As Integer
y As String
z As Boolean
End Type
Function sl(a As Integer, b As Integer, c As String) As sp
sl.x = a - b
If a > b Then
sl.z = True
sl.y = c & ": is true"
ElseIf a < b Then
sl.z = False
sl.y = c & ": is false"
Else
sl.z = zero
sl.y = c & ":is zero"
End If
End Function
w=sl(5,3,"result").x '2
v=sl(5,3,"result").y 'result: is true
u= sl(5,3,"result").z 'True
با اجازه برداشت شخصی من :
let و get برای گرفتن یا مقداردهی اعضای خصوصی وغیرقابل دسترسی کلاس توسط یه عضو عمومی یا پالیکه .
اگه عضو خصوصی در دسترس باشه میشه توابع نوشته شده داخل کلاس رو که از اون عضو خصوصی استفاده میکنه دستکاری یا حذفش کرد و یا مقادیر غیر مجاز داد وساختار کلاس رو بهم ریخت بنابراین توسط let و get داده رو به اون عضو میدیم یا میگیرم و اون عضو پشت پرده کارشو انجام میده . در مثال زیر یه محدودیت ورود اعداد بزرگتر از 5 رو به عضو خصوصی دادیم که در حالت عمومی و مستقیم نمیشد این محدودیت رو بوجود اورد .(اشتباهاتم رو لطفا تصحیح فرمائید )
Public Property Let Hours(ByVal value As Long)
if value>5 then
xHOURS = value
else
msgbox "inter greader than 5"
end if
End Property
آخرین ویرایش به وسیله moustafa : پنج شنبه 15 شهریور 1403 در 10:48 صبح
خب،
تا اینجا برای کلاس فقط چند پراپرتی ضروری رو تعریف کردیم.
برای تکمیل پروسیجرهای خود پراپرتی ها (و بعدا متدها) چند constant هم تعریف میکنیم،
که کدنویسی محاسبات رو برای ما راحتتر میکنه.
Const HoursPerDay As Long = 24
Const MinutesPerHour As Long = 60
Const SecondsPerMinute As Long = 60
Const MillisecondsPerSecond As Long = 1000
Const MinutesPerDay As Long = HoursPerDay * MinutesPerHour ' 1,440
Const SecondsPerHour As Long = SecondsPerMinute * MinutesPerHour ' 3600
Const SecondsPerDay As Long = SecondsPerHour * HoursPerDay ' 86,400
Const MillisecondsPerMinute As Long = MillisecondsPerSecond * SecondsPerMinute ' 60,000
Const MillisecondsPerHour As Long = MillisecondsPerMinute * MinutesPerHour ' 3,600,000
Const MillisecondsPerDay As Long = MillisecondsPerHour * HoursPerDay ' 86,400,000
Const MaxMilliseconds As Long = (2 ^ 31) - 1 ' + 2,147,483,647
Const MinMilliseconds As Long = -MaxMilliseconds
Const MaxSeconds As Long = MaxMilliseconds \ MillisecondsPerSecond ' 2,147,483
Const MinSeconds As Long = -MaxSeconds
Const MaxMinutes As Long = MaxMilliseconds \ MillisecondsPerMinute ' 35,791
Const MinMinutes As Long = -MaxMinutes
Const MaxHours As Long = MaxMilliseconds \ MillisecondsPerHour ' 596
Const MinHours As Long = -MaxHours
Const MaxDays As Long = MaxMilliseconds \ MillisecondsPerDay ' 24
Const MinDays As Long = -MaxDays
مشابه همین const ها رو میتونین در سورس #C این کلاس برای دات نت هم ببینین،
من اسامی رو از همونجا برداشتم (کم و بیش)،
ولی دیتاتایپ ها رو long درنظر گرفتم (32 بیت) بابت گارانتی اجرا در پلتفرم های 32 بیت.
با توجه به آموزشی بودن مبحث اهمیتی نداره (فعلا)
ولی بعدا در موردش توضیح میدهم.
آخرین ویرایش به وسیله mazoolagh : یک شنبه 18 شهریور 1403 در 18:50 عصر
برای محاسبات مبنا رو باید بر روی کوچکترین مقدار زمان (در اینجا میلی ثانیه) بگذاریم،
به این صورت که مقدار یک timespan نهایتا برحسب میلی ثانیه خواهد بود.
این constهای پست 17 بر همین اساس و با توجه با بیشترین مقدار یک 32bit integer محاسبه شدن.
و البته timespan تاریخ نیست بلکه یک بازه زمانی هست و به همین خاطر میتونه مثبت یا منفی باشه.
همچنین چند پراپرتی دیگه هم اضافه میکنیم:
Public Property Get TotalDays() As Double ' read only
TotalDays = TotalMilliseconds / MillisecondsPerDay
End Property
Public Property Get TotalHours() As Double ' read only
TotalHours = TotalMilliseconds / MillisecondsPerHour
End Property
Public Property Get TotalMinutes() As Double ' read only
TotalMinutes = TotalMilliseconds / MillisecondsPerMinute
End Property
Public Property Get TotalSeconds() As Double ' read only
TotalSeconds = TotalMilliseconds / MillisecondsPerSecond
End Property
Public Property Get TotalMilliseconds() As Long ' read only
TotalMilliseconds = xTOTAL_MILLISECONDS
End Property
اینها پروسیجر let ندارن پس read only میشن،
و خب مشخصا مقدار timespan رو بر اساس یک واحد مشخص میکنن.
مثلا 1 روز و 12 ساعت معادل 1.5 روز میشه،
یا 66 دقیقه معادل 1.1 ساعت و ...
برای همین دیگه integer نیستن (به جز TotalMilliseconds که کوچکترین واحد هست)
بعدا در متدهایی که مینویسیم اینها رو در نظر میگیریم.
تا اینجا کد کلاس TimeSpan به این شکل شده:
'======= Class: TimeSpan =======
Option Compare Database
Option Explicit
'======= Constants =======
Const HoursPerDay As Long = 24
Const MinutesPerHour As Long = 60
Const SecondsPerMinute As Long = 60
Const MillisecondsPerSecond As Long = 1000
Const MinutesPerDay As Long = HoursPerDay * MinutesPerHour ' 1,440
Const SecondsPerHour As Long = SecondsPerMinute * MinutesPerHour ' 3600
Const SecondsPerDay As Long = SecondsPerHour * HoursPerDay ' 86,400
Const MillisecondsPerMinute As Long = MillisecondsPerSecond * SecondsPerMinute ' 60,000
Const MillisecondsPerHour As Long = MillisecondsPerMinute * MinutesPerHour ' 3,600,000
Const MillisecondsPerDay As Long = MillisecondsPerHour * HoursPerDay ' 86,400,000
Const MaxMilliseconds As Long = (2 ^ 31) - 1 ' + 2,147,483,647
Const MinMilliseconds As Long = -MaxMilliseconds
Const MaxSeconds As Long = MaxMilliseconds \ MillisecondsPerSecond ' 2,147,483
Const MinSeconds As Long = -MaxSeconds
Const MaxMinutes As Long = MaxMilliseconds \ MillisecondsPerMinute ' 35,791
Const MinMinutes As Long = -MaxMinutes
Const MaxHours As Long = MaxMilliseconds \ MillisecondsPerHour ' 596
Const MinHours As Long = -MaxHours
Const MaxDays As Long = MaxMilliseconds \ MillisecondsPerDay ' 24
Const MinDays As Long = -MaxDays
'======= Declarations =======
Private xDAYS As Long
Private xHOURS As Long
Private xMINUTES As Long
Private xSECONDS As Long
Private xMILLISECONDS As Long
Private xTOTAL_MILLISECONDS As Long
'======= Properties =======
Public Property Get Days() As Long
Days = xDAYS
End Property
Public Property Let Days(ByVal value As Long)
xDAYS = value
End Property
Public Property Get Hours() As Long
Hours = xHOURS
End Property
Public Property Let Hours(ByVal value As Long)
xHOURS = value
End Property
Public Property Get Minutes() As Long
Minutes = xMINUTES
End Property
Public Property Let Minutes(ByVal value As Long)
xMINUTES = value
End Property
Public Property Get Seconds() As Long
Seconds = xSECONDS
End Property
Public Property Let Seconds(ByVal value As Long)
xSECONDS = value
End Property
Public Property Get Milliseconds() As Long
Milliseconds = xMILLISECONDS
End Property
Public Property Let Milliseconds(ByVal value As Long)
xMILLISECONDS = value
End Property
Public Property Get TotalDays() As Double ' read only
TotalDays = TotalMilliseconds / MillisecondsPerDay
End Property
Public Property Get TotalHours() As Double ' read only
TotalHours = TotalMilliseconds / MillisecondsPerHour
End Property
Public Property Get TotalMinutes() As Double ' read only
TotalMinutes = TotalMilliseconds / MillisecondsPerMinute
End Property
Public Property Get TotalSeconds() As Double ' read only
TotalSeconds = TotalMilliseconds / MillisecondsPerSecond
End Property
Public Property Get TotalMilliseconds() As Long ' read only
TotalMilliseconds = xTOTAL_MILLISECONDS
End Property
آخرین ویرایش به وسیله mazoolagh : یک شنبه 18 شهریور 1403 در 20:06 عصر
هر کلاس (در VBA) دو رخداد اصلی داره:
Class_Initialize و Class_Terminate
که از اسمهاشون مشخصه کی اجرا میشن.
همیشه باید وقتی یک چیزی رو از نوع object میسازیم اون رو با set مقدار دهی کنیم.
و همیشه باید در پایان کار به nothing سِت بشن.
کلاس هم برای ما یک ابجکت میسازه،
وقتی بنویسیم dim ts as timespan هنوز ts نامشخص هست تا زمانیکه set ts=new timespan
که در اینجا Class_Initialize اجرا میشه.
و زمانی که بنویسیم set ts=nothing رخداد Class_Terminate تریگر میشه.
معمولا از Class_Initialize برای مقداردهی اولیه متغییرها و پراپرتی ها و .. استفاده میشه (در صورت نیاز).
همچنین اگر در یک کلاس از ابجکتهای دیگه استفاده کرده باشیم (مثلا یک پراپرتی از نوع recordset داشته باشیم)،
باید در این دو رخداد این ابجکتها رو set new و set nothing کنیم.
در اینجا متغییرها و پراپرتی های ما هیچکدوم ابجکت نیستن،
ولی از Class_Initialize برای مقداردهی اولیه استفاده میکنیم و به Class_Terminate هم نیاز نداریم:
Private Sub Class_Initialize()
xDAYS = 0
xHOURS = 0
xMINUTES = 0
xSECONDS = 0
xMILLISECONDS = 0
xTOTAL_MILLISECONDS = 0
End Sub
البته مقادیر عددی با تعریف اولیه خودکار مقدارشون 0 هست،
ولی اینجا کاربرد این رخداد رو خواستیم نشون بدیم.
حالا شروع میکنیم به نوشتن روتین های مورد نیاز.
یک روتین نیاز داریم که از روی مقدار timespan بر حسب میلی ثانیه (که گفتیم پایه همه محاسبات هست)
همه بخشهای زمانی رو محاسبه کنه:
Private Sub Calc_TimeParts()
Dim x As Long
x = Abs(TotalMilliseconds)
xDAYS = x \ MillisecondsPerDay
x = x Mod MillisecondsPerDay
xHOURS = x \ MillisecondsPerHour
x = x Mod MillisecondsPerHour
xMINUTES = x \ MillisecondsPerMinute
x = x Mod MillisecondsPerMinute
xSECONDS = x \ MillisecondsPerSecond
xMILLISECONDS = x Mod MillisecondsPerSecond
End Sub
یک تابع دیگه نیاز داریم که از روی بخشهای زمانی ارزش timespan رو بر حسب میلی ثانیه حساب کنه:
Private Sub Calc_TotalMilliSeconds()
Dim x As Variant
x = _
CDec(Milliseconds) + _
CDec(Seconds * MillisecondsPerSecond) + _
CDec(Minutes * MillisecondsPerMinute) + _
CDec(Hours * MillisecondsPerHour) + _
CDec(Days * MillisecondsPerDay)
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010
Else
xTOTAL_MILLISECONDS = x
End If
End Sub
در اینجا ابتدا محاسبات رو بر اساس یک متغییر دسیمال انجام میدیم،
و بعد از اینکه مطمئن شدیم در محدوده مجاز long هست اون رو در xTOTAL_MILLISECONDS میریزیم،
وگرنه یک خطای کاستوم میسازیم.
روتین Raise_Error یکی دیگه از روتینهایی هست که باید بنویسیم
و کارش ساخت یک خطای کاستوم با شماره و متنی هست که براش مشخص میکنیم.
اگر در یک ماجول عملیاتی با کلاس انجام بدیم که به خطا برخورد کنه،
میتونیم در error handler اون روتین از این خطای کاستوم که از کلاس میاد استفاده کنیم (درست مثل خطاهای خود اکسس)
وگرنه که خود اکسس پیام میده (همونی که ما براش مشخص کردیم).
مرحله بعدی درست کردن اسکلت روتین Raise_Error هست
که در پست شماره 23 بهش اشاره شد.
این روتین به ما کمک میکنه که کدهای دیگه ما کوچیک و جمع و جور و نگهداری برنامه ساده تر باشه:
Private Sub Raise_Error( _
ByVal Error_Number As Integer, _
Optional ByVal Source As String = "", _
Optional ByVal value As Variant = Nothing)
Dim Description As String
Select Case Error_Number
Case ...
Description = ...
Source = ...
Case ...
Description = ...
Source = ...
...
...
End Select
Err.Raise _
Number:=vbObjectError + Error_Number, _
Source:="TimeSpan." & Source, _
Description:=Description, _
HelpFile:="TimeSpan"
End Sub
الان برمیگردیم سر پروسیجرهای Let برای پراپرتی ها و کدها رو برای validation تکمیل میکنیم:
Public Property Let Days(ByVal value As Long)
If value < 0 Or value > MaxDays Then
Raise_Error 1001, "Days", value
Else
xDAYS = value
Calc_TotalMilliSeconds
End If
End Property
Public Property Let Hours(ByVal value As Long)
If value < 0 Or value >= HoursPerDay Then
Raise_Error 1002, "Hours", value
Else
xHOURS = value
Calc_TotalMilliSeconds
End If
End Property
Public Property Let Minutes(ByVal value As Long)
If value < 0 Or value >= MinutesPerHour Then
Raise_Error 1003, "Minutes", value
Else
xMINUTES = value
Calc_TotalMilliSeconds
End If
End Property
Public Property Let Seconds(ByVal value As Long)
If value < 0 Or value >= SecondsPerMinute Then
Raise_Error 1004, "Seconds", value
Else
xSECONDS = value
Calc_TotalMilliSeconds
End If
End Property
Public Property Let Milliseconds(ByVal value As Long)
If value < 0 Or value >= MillisecondsPerSecond Then
Raise_Error 1005, "MilliSeconds", value
Else
xMILLISECONDS = value
Calc_TotalMilliSeconds
End If
End Property
حالا که بخش پراپرتی ها رو تکمیل کردیم میریم سر وقت متد هایی که نیاز داریم.
هر method یک روتین هست که میتونه یک sub یا function باشه،
تا زمانی که نیازی نیست مقداری برگرده و عملیات روی خود ابجکت انجام میشه از sub استفاده میکنیم.
از متد ساده ای به Zero شروع میکنیم که فقط مقدار ابجکت رو صفر میکنه:
Public Sub Zero()
xDAYS = 0
xHOURS = 0
xMINUTES = 0
xSECONDS = 0
xMILLISECONDS = 0
xTOTAL_MILLISECONDS = 0
End Sub
و یک متد ساده دیگه که ارزش ابجکت رو تغییر علامت میده (مثبت به منفی و برعکس):
Public Sub Negate()
xTOTAL_MILLISECONDS = -xTOTAL_MILLISECONDS
End Sub
و یک متد From که از روی اجزای زمان timespan رو مقدار دهی کنه:
Public Sub From( _
Optional day As Long = 0, _
Optional hour As Long = 0, _
Optional minute As Long = 0, _
Optional second As Long = 0, _
Optional millisecond As Long = 0)
Days = day
Hours = hour
Minutes = minute
Seconds = second
Milliseconds = millisecond
End Sub
21.png
متد که از روی بخش زمان یک date ، ابجکت رو مقدار دهی میکنه:
Public Sub FromTimeofDate(d As Date)
From _
hour:=DatePart("h", d), _
minute:=DatePart("n", d), _
second:=DatePart("s", d)
End Sub
متدهایی برای مقداردهی کل ابجکت (و نه یک پراپرتی) از روی یک اندازه از زمان:
Public Sub FromDays(ByVal value As Double)
If value < MinDays Or value > MaxDays Then
Raise_Error 1011, "FromDays", value
Else
xTOTAL_MILLISECONDS = value * MillisecondsPerDay
Calc_TimeParts
End If
End Sub
Public Sub FromHours(ByVal value As Double)
If value < MinHours Or value > MaxHours Then
Raise_Error 1012, "FromHours", value
Else
xTOTAL_MILLISECONDS = value * MillisecondsPerHour
Calc_TimeParts
End If
End Sub
Public Sub FromMinutes(ByVal value As Double)
If value < MinMinutes Or value > MaxMinutes Then
Raise_Error 1013, "FromMinutes", value
Else
xTOTAL_MILLISECONDS = value * MillisecondsPerMinute
Calc_TimeParts
End If
End Sub
Public Sub FromSeconds(ByVal value As Double)
If value < MinSeconds Or value > MaxSeconds Then
Raise_Error 1014, "FromSeconds", value
Else
xTOTAL_MILLISECONDS = value * MillisecondsPerSecond
Calc_TimeParts
End If
End Sub
Public Sub FromMilliSeconds(ByVal value As Long)
If value < MinMilliseconds Or value > MaxMilliseconds Then
Raise_Error 1015, "FromMilliSeconds", value
Else
xTOTAL_MILLISECONDS = value
Calc_TimeParts
End If
End Sub
به نوع مقادیر دقت کنین که
همه double هستن (چون باید بتون اعشار قبول کنن مثل 3.78 روز)
بجز میلی ثانیه - که کوچکترین واحد هست.
متدهایی برای اضافه (کم) کردن یک مقدار زمانی به (از) ابجکت:
Public Sub AddDays(ByVal day As Double)
Dim x As Variant
x = _
CDec(xTOTAL_MILLISECONDS) + _
CDec(day * MillisecondsPerDay)
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010, "AddDays"
Else
xTOTAL_MILLISECONDS = xTOTAL_MILLISECONDS + day * MillisecondsPerDay
Calc_TimeParts
End If
End Sub
Public Sub AddHours(hour As Double)
Dim x As Variant
x = _
CDec(xTOTAL_MILLISECONDS) + _
CDec(hour * MillisecondsPerHour)
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010, "AddHours"
Else
xTOTAL_MILLISECONDS = xTOTAL_MILLISECONDS + hour * MillisecondsPerHour
Calc_TimeParts
End If
End Sub
Public Sub AddMinutes(minute As Double)
Dim x As Variant
x = _
CDec(xTOTAL_MILLISECONDS) + _
CDec(minute * MillisecondsPerMinute)
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010, "AddMinutes"
Else
xTOTAL_MILLISECONDS = xTOTAL_MILLISECONDS + minute * MillisecondsPerMinute
Calc_TimeParts
End If
End Sub
Public Sub AddSeconds(second As Double)
Dim x As Variant
x = _
CDec(xTOTAL_MILLISECONDS) + _
CDec(second * MillisecondsPerSecond)
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010, "AddSeconds"
Else
xTOTAL_MILLISECONDS = xTOTAL_MILLISECONDS + second * MillisecondsPerSecond
Calc_TimeParts
End If
End Sub
Public Sub AddMilliSeconds(millisecond As Long)
Dim x As Variant
x = _
CDec(xTOTAL_MILLISECONDS) + _
CDec(millisecond)
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010, "AddMilliSeconds"
Else
xTOTAL_MILLISECONDS = xTOTAL_MILLISECONDS + millisecond
Calc_TimeParts
End If
End Sub
متدهای ضرب و تقسیم:
Public Sub Multiply(factor As Double)
Dim x As Variant
x = CDec(xTOTAL_MILLISECONDS) * factor
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010, "Multiply"
Else
xTOTAL_MILLISECONDS = xTOTAL_MILLISECONDS * factor
Calc_TimeParts
End If
End Sub
Public Sub Divide(factor As Double)
Dim x As Variant
x = CDec(xTOTAL_MILLISECONDS) / factor
If x < MinMilliseconds Or x > MaxMilliseconds Then
Raise_Error 1010, "Divide"
Else
xTOTAL_MILLISECONDS = xTOTAL_MILLISECONDS / factor
Calc_TimeParts
End If
End Sub
متد ToString :
Public Enum ToStringOptions
Full = 0 ' Day HH:MM:SS.mmm
Day_HH = 1
Day_HHMM = 2
Day_HHMMSS = 3
HH = 4
HHMM = 5
HHMMSS = 6
HHMMSSmmm = 7
End Enum
Public Function ToString(Optional output As ToStringOptions = Full) As String
Dim sign As String
If xTOTAL_MILLISECONDS < 0 Then
sign = "-"
Else
sign = ""
End If
Select Case output
Case 0 ' Full
ToString = sign & _
Days & _
format(Hours, " 00") & ":" & _
format(Minutes, "00") & ":" & _
format(Seconds, "00") & "." & _
format(Milliseconds, "000")
Case 1 ' Day _HH
ToString = sign & _
Days & _
format(Hours, " 00")
Case 2 ' Day HH:MM
ToString = sign & _
Days & _
format(Hours, " 00") & ":" & _
format(Minutes, "00")
Case 3 ' Day HH:MM:SS
ToString = sign & _
Days & _
format(Hours, " 00") & ":" & _
format(Minutes, "00") & ":" & _
format(Seconds, "00")
Case 4 ' HH
ToString = sign & _
format(Hours, "00")
Case 5 ' HH:MM
ToString = sign & _
format(Hours, "00") & ":" & _
format(Minutes, "00")
Case 6 ' HH:MM:SS
ToString = sign & _
format(Hours, "00") & ":" & _
format(Minutes, "00") & ":" & _
format(Seconds, "00")
Case 7 ' HH:MM:SS.mmm
ToString = sign & _
format(Hours, "00") & ":" & _
format(Minutes, "00") & ":" & _
format(Seconds, "00") & "." & _
format(Milliseconds, "000")
End Select
End Function
این بخش اول آموزش کلاس در VBA بود.
تا اینجا اگر اشکالی دیده میشه،
یا مطلبی از چشم دور مونده ممنون میشم مطرح کنین .
همچنین مطلب تکمیلی اگر دارین لطف کنین اینجا بگذارین یا لینک بدین.