نمایش نتایج 1 تا 35 از 35

نام تاپیک: در باره Class و User Defined Type (UDT)

  1. #1
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    در باره Class و User Defined Type (UDT)

    تا بحال تاپیکی در باره این دو
    و کاربردشون
    و تفاوتهاشون
    و این که کی از کدوم یکی بهتره استفاده کنیم،
    اینجا ندیدم - حتی در حد یک توضیح ساده.

    سعی میکنم بتدریج همون چند خط رو اینجا قلمی کنم.

  2. #2
    کاربر دائمی آواتار eb_1345
    تاریخ عضویت
    مرداد 1398
    محل زندگی
    تهران
    پست
    890

    نقل قول: در باره Class و User Defined Type (UDT)

    نقل قول نوشته شده توسط mazoolagh مشاهده تاپیک
    تا بحال تاپیکی در باره این دو
    و کاربردشون
    و تفاوتهاشون
    و این که کی از کدوم یکی بهتره استفاده کنیم،
    اینجا ندیدم - حتی در حد یک توضیح ساده.

    سعی میکنم بتدریج همون چند خط رو اینجا قلمی کنم.

  3. #3
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    با UDT شروع میکنیم که ساده تر هست.

    UDT چیزی نیست به جز ترکیبی از چند نوع دیتا (DATA TYPE) دیگه که یک اسم بهش میدیم:

    Type Category
    ID As Long
    Name As String
    Description As String
    End Type


    در تعریف UDT چند نکته هست که باید دقت کنین:
    • حتما باید در آغاز ماجول تعریف بشه - قبل از هر SUB یا FUNCTION
    • به صورت دیفالت PUBLIC هست یعنی در کل برنامه در دسترس هست - مگر اینکه مشخص کنین PRIVATE بودنش رو.
    • اگر در فرم تعریف بشه باید حتما PRIVATE باشه!

  4. #4
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    بعد از تعریف UDT ، مثل هر DATA TYPE دیگه در IntelliSense دیده میشه:

    1.png

    2.png

  5. #5
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    اینجا یک پرسشی ممکنه پیش بیاد که:
    ما در اکسس که جدول و رکوردست و ... داریم،
    پس چه نیازی به 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 هم با وجود داشتن ساختارها و امکانات آماده مشابه هست.

  6. #6
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    متداولترین کاربرد UDT در اکسس زمانی هست که نیاز داریم یک فانکشن بیشتر از یک مقدار برگردونه.
    قبلا نمونه برای این داشتیم این هست که توضیح بیشتری نیاز نداره.

    وب سرويس (barnamenevis.org) پست 13 رو ببینین

  7. #7
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    کاربرد دیگه UDT در کار با روتینهای DLLها و پاس کردن (و گرفتن) مقادیر به (از) اونها هست.

    برای این هم نمونه داریم:

    راهنمائی در خصوص رنگ فرم (barnamenevis.org) پست شماره 7 رو ببینین

  8. #8
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    کلاس (Class) یک مفهوم عمومی برنامه نویس شی گرا هست (object oriented)
    وگرچه از نظر داشتن propertyهای متفاوت مشابه UDT هست،
    ولی چون میشه از کد هم در اون استفاده کرد (sub و function) ، تواناییهاش و کاربردهاش به مراتب گسترده تر و بیشتر هست،
    و به همون نسبت هم نوشتن کلاس دانش بیشتری نسبت به UDT نیاز داره.

    سعی میکنم مطلب رو همزمان با نوشتن یک کلاس نمونه کاربردی توضیح بدم (بتدریج).

  9. #9
    کاربر دائمی
    تاریخ عضویت
    آذر 1384
    محل زندگی
    هر کجا هستم باشم آسمان مال من است پنجره -فکر- هوا- عشق- زمین مال من است.
    پست
    904

    نقل قول: در باره Class و User Defined Type (UDT)

    نقل قول نوشته شده توسط mazoolagh مشاهده تاپیک
    تا بحال تاپیکی در باره این دو
    و کاربردشون
    و تفاوتهاشون
    و این که کی از کدوم یکی بهتره استفاده کنیم،
    اینجا ندیدم - حتی در حد یک توضیح ساده.

    سعی میکنم بتدریج همون چند خط رو اینجا قلمی کنم.
    سلام ودرود وسپاس بی نهایت

  10. #10
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    نقل قول نوشته شده توسط moustafa مشاهده تاپیک
    سلام ودرود وسپاس بی نهایت
    با سلام و عرض ادب متقابل
    و تشکر از لطف جنابعالی و دیگر دوستان
    بحث کلاس رو ادامه میدیم:
    ================

    در VBA نیاز هست که کلاس حتما در یک ماجول جدا و اختصاصی تعریف بشه (class module)،
    به یکی از دو روش میتونیم کلاس ماجول بسازیم:

    1- از منوی create و انتخاب class module
    10.png

    2- در محیط vba editor
    در پنجره project explorer روی اسم برنامه راست کلیک و insert class module :
    11.png

    بر خلاف ماجول های عادی که اسم اون مهم نیست،
    یک کلاس اسمش رو از اسم ماجولش میگیره و همینجور که میبینین جداگانه هم نگهداری میشه:
    12.png
    13.png

    همینجور که دیده میشه قرار هست یک کلاس به اسم TimeSpan بسازیم.

  11. #11
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    TimeSpan در واقع نوعی از دیتا (در واقع ابجکت) هست که برای نمایش نگهداری بازه های زمانی به کار میره (با تاریخ اشتباه نگیرین)
    و معمولا شامل روز، ساعت، دقیقه و ثانیه است که بنا به نیاز ممکنه میلی ثانیه یا کمتر از اون هم براش تعریف بشه،
    یا فقط تا دقیقه باشه.

    مطالعه بیشتر در مورد TimeSpan Struct

    یک کاربرد timespan در جمع ساعت های کاری هست،
    به عنوان مثال جمع کارکرد یک کارمند در ماه.

    در این کلاس نمونه فرض رو براین گذاشتیم که دقت زمانی تا میلی ثانیه نیاز هست
    پس نیاز داریم برای این کلاس چیزی تعریف کنیم که نشون دهنده روز، ساعت، دقیقه، ثانیه، و میلی ثانیه باشه.

    این چیز رو بهش میگن property و این پراپرتی میتونه یک دیتا استاندارد vba یا خودش یک ابجکت دیگه باشه،
    که روش کار با دومی کمی تفاوت داره.

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

    برای خوندن پروسیجر get ، و برای نوشتن اگر یک مقدار ساده باشه let ،و اگر یک ابجکت باشه set ،
    و خود پراپرتی هم میتونه private یا public باشه (بسته به نیاز و کاربرد).

  12. #12
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    در اولین گام از تعریف پراپرتی های گفته شده شروع میکنیم:

    '=======  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


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

  13. #13

    نقل قول: در باره Class و User Defined Type (UDT)

    سلام
    وقت بخیر
    ان شاءالله دوستان علاقمند به یادگیری زبان برنامه نویسی VBA از کنار این آموزش های مفیدی که اساتید عزیز بدون هیچ چشمداشتی برای تهیه اون زحمت می کشن بی تفاوت رد نشن و در یادگیری و بکارگیری اونها کوشا باشن

  14. #14
    کاربر دائمی
    تاریخ عضویت
    آذر 1384
    محل زندگی
    هر کجا هستم باشم آسمان مال من است پنجره -فکر- هوا- عشق- زمین مال من است.
    پست
    904

    نقل قول: در باره Class و User Defined Type (UDT)

    با اجازه استاد من یه مثال ساده از 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

  15. #15
    کاربر دائمی
    تاریخ عضویت
    آذر 1384
    محل زندگی
    هر کجا هستم باشم آسمان مال من است پنجره -فکر- هوا- عشق- زمین مال من است.
    پست
    904

    نقل قول: در باره Class و User Defined Type (UDT)

    با اجازه برداشت شخصی من :
    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 صبح

  16. #16
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    نقل قول نوشته شده توسط moustafa مشاهده تاپیک
    با اجازه برداشت شخصی من :
    let و get برای گرفتن یا مقداردهی اعضای خصوصی وغیرقابل دسترسی کلاس توسط یه عضو عمومی یا پالیکه .
    اگه عضو خصوصی در دسترس باشه میشه توابع نوشته شده داخل کلاس رو که از اون عضو خصوصی استفاده میکنه دستکاری یا حذفش کرد و یا مقادیر غیر مجاز داد وساختار کلاس رو بهم ریخت بنابراین توسط let و get داده رو به اون عضو میدیم یا میگیرم و اون عضو پشت پرده کارشو انجام میده . در مثال زیر یه محدودیت ورود اعداد بزرگتر از 5 رو به عضو خصوصی دادیم که در حالت عمومی و مستقیم نمیشد این محدودیت رو بوجود اورد .(اشتباهاتم رو لطفا تصحیح فرمائید )
    خواهش میکنم،
    با اجازتون این رو در پایان کار این کلاس نمونه برمیگردم و توضیح میدم،
    تا پیوستگی مطالب از دست نره.

  17. #17
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    خب،
    تا اینجا برای کلاس فقط چند پراپرتی ضروری رو تعریف کردیم.
    برای تکمیل پروسیجرهای خود پراپرتی ها (و بعدا متدها) چند 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 عصر

  18. #18
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    برای محاسبات مبنا رو باید بر روی کوچکترین مقدار زمان (در اینجا میلی ثانیه) بگذاریم،
    به این صورت که مقدار یک timespan نهایتا برحسب میلی ثانیه خواهد بود.

    این constهای پست 17 بر همین اساس و با توجه با بیشترین مقدار یک 32bit integer محاسبه شدن.

    و البته timespan تاریخ نیست بلکه یک بازه زمانی هست و به همین خاطر میتونه مثبت یا منفی باشه.

  19. #19
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    همچنین چند پراپرتی دیگه هم اضافه میکنیم:
    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 که کوچکترین واحد هست)

    بعدا در متدهایی که مینویسیم اینها رو در نظر میگیریم.

  20. #20
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    تا اینجا کد کلاس 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 عصر

  21. #21
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    هر کلاس (در 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 هست،
    ولی اینجا کاربرد این رخداد رو خواستیم نشون بدیم.

  22. #22
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

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

    یک روتین نیاز داریم که از روی مقدار 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

  23. #23
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    یک تابع دیگه نیاز داریم که از روی بخشهای زمانی ارزش 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 اون روتین از این خطای کاستوم که از کلاس میاد استفاده کنیم (درست مثل خطاهای خود اکسس)
    وگرنه که خود اکسس پیام میده (همونی که ما براش مشخص کردیم).

  24. #24
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    مرحله بعدی درست کردن اسکلت روتین 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

  25. #25
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    الان برمیگردیم سر پروسیجرهای 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

  26. #26
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    حالا که بخش پراپرتی ها رو تکمیل کردیم میریم سر وقت متد هایی که نیاز داریم.

    هر 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

  27. #27
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    و یک متد 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

  28. #28
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    متد که از روی بخش زمان یک date ، ابجکت رو مقدار دهی میکنه:
    Public Sub FromTimeofDate(d As Date)
    From _
    hour:=DatePart("h", d), _
    minute:=DatePart("n", d), _
    second:=DatePart("s", d)
    End Sub

  29. #29
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    متدهایی برای مقداردهی کل ابجکت (و نه یک پراپرتی) از روی یک اندازه از زمان:
    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 روز)
    بجز میلی ثانیه - که کوچکترین واحد هست.

  30. #30
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    متدهایی برای اضافه (کم) کردن یک مقدار زمانی به (از) ابجکت:
    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

  31. #31
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    متدهای ضرب و تقسیم:

    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

  32. #32
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    متد 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

  33. #33
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

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

    همچنین مطلب تکمیلی اگر دارین لطف کنین اینجا بگذارین یا لینک بدین.

  34. #34
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    نقل قول نوشته شده توسط moustafa مشاهده تاپیک
    من یه مثال ساده از 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
    مثال خوبی هست.
    وقتی تایپ یک تابع رو UDT میگذاریم، معمولا به بیشتر از از پراپرتی اون نیاز داریم.
    پس بهتر هست که برای جلوگیری از تکرار دوباره تابع، اول یک متغییر از اون نوع تعریف
    و بعد خروجی تابع رو به اون منسوب کنیم.

  35. #35
    کاربر دائمی آواتار mazoolagh
    تاریخ عضویت
    اردیبهشت 1384
    سن
    72
    پست
    3,295

    نقل قول: در باره Class و User Defined Type (UDT)

    نقل قول نوشته شده توسط moustafa مشاهده تاپیک
    با اجازه برداشت شخصی من :
    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
    اشتباه نیست،
    ولی دقیق هم نیست!

    فکر کنم در پست ها و کدهای نمونه مشخص هست.

تاپیک های مشابه

  1. سوال: compile error : User-defined type not defined
    نوشته شده توسط lmaghsoodi در بخش برنامه نویسی در 6 VB
    پاسخ: 1
    آخرین پست: پنج شنبه 23 خرداد 1392, 11:59 صبح
  2. سوال: خطای user-defined type not found
    نوشته شده توسط amubashir در بخش برنامه نویسی در 6 VB
    پاسخ: 4
    آخرین پست: یک شنبه 11 مرداد 1388, 08:29 صبح
  3. user-defined type چیست؟
    نوشته شده توسط majidf4252 در بخش C#‎‎
    پاسخ: 2
    آخرین پست: سه شنبه 10 اردیبهشت 1387, 23:27 عصر

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •