สมัครสมาชิก
 

อยากทราบว่า Class Module กับ Module ที่ไม่มี Class มันใช้ต่างกันอย่างไรคะ



0 สมาชิก และ 1 บุคคลทั่วไป กำลังดูหัวข้อนี้

22 ก.ค. 61 , 06:23:18
อ่าน 233 ครั้ง

มาลี

Class Module กับ Module

อยากทราบว่า Module สองแบบนี้ มีความหมาย ต่างกันอย่างไรคะ
ใช้แทนกันได้ไหม

เมื่อใดจะต้องใช้ Class Module
และเมื่อใดจะต้องใช้ Module แบบธรรมดา

ขอบคุณค่ะ

 

22 ก.ค. 61 , 20:51:16
ตอบกลับ #1

สันติสุข

Class Module ใช้เขียนโค้ดเพื่อสร้างตัว Object ของเราเอง เทียบอย่างเช่นเมื่อเราเขียน Dim RS as DAO.Recordset ตัว Recordset ก็คือคลาสจากไลบรารี่ DAO   ตัว RS ก็คือตัวแปร Object จากคลาส Recordset

Class และ Object เป็นแนวคิดการเขียนโปรแกรมเชิงวัตถุ (Object Oriented Programming, OOP) ซึ่งมีคุณสมบัติพิเศษมากมาย แต่ VBA มีแค่ส่วนนึงเท่านั้น จุดประสงค์หนึ่งก็เพื่อให้คนอื่นมาเรียกใช้โค้ดของเราอย่างที่ผมขอเรียกว่า "เข้าตามตรอก ออกตามประตู" ใครจะเรียกใช้ให้โค้ดเราทำอะไร ก็ต้องเรียกผ่านโค้ดที่เรากำหนด (ใน OOP เรียกว่า Method) หรือกำหนด/อ่านค่าอะไรของโค้ดเรา ก็ต้องส่ง/รับผ่าน Property เท่านั้น ไม่ว่าจะเป็น Method หรือ Property ก็จะเป็น Procedure ดังนั้นโค้ดใน Procedure เหล่านี้ก็จะสามารถกรองและตรวจสอบได้ว่าค่าที่ส่ง/รับ เป็นค่าที่เหมาะสมหรือไม่ ถ้าเราจะเขียน Module ธรรมดาเพื่อเลียนแบบให้โค้ดอื่น "เข้าตามตรอก ออกตามประตู" เหมือนกันก็ทำได้ แต่การอ้างชื่อจาก Module ของเราคงไม่สะดวกเท่าการเขียนด้วย Class Module และจะทำไปทำไมในเมื่อมี Class Module ให้ใช้อยู่แล้ว ผมก็เคยมีงานชิ้นนึงที่ตัดสินใจใช้ Class Module เพราะมีความซับซ้อนและเห็นว่าการเขียนในรูปแบบ Object.Property = ค่า และ Object.Method จะทำให้อ่านโค้ดได้เข้าใจมากกว่าเขียนเป็น Variable = ค่า และ Call Procedure มากๆครับ

ผมไม่ได้มีความเชี่ยวชาญอะไรเกี่ยวกับ OOP คงตอบได้แค่นี้ก่อนครับ
« แก้ไขครั้งสุดท้าย: 24 ก.ค. 61 , 00:14:48 โดย สันติสุข »

 
โพสต์นี้ได้รับคำขอบคุณจาก: มาลี

23 ก.ค. 61 , 05:59:33
ตอบกลับ #2

มาลี

ขอบพระคุณอย่างยิ่งค่ะอาจารย์

พอจะทราบหลักการและความแตกต่างบ้างแล้วค่ะ
หนูคงยังต้องศึกษาอีกมากมายเลยล่ะ

 

24 ก.ค. 61 , 00:09:47
ตอบกลับ #3

สันติสุข

ผมเขียนตัวอย่างสมมุติของ Class Recordset เพื่อให้เห็นภาพว่าเมื่อเราอ่านหรือกำหนดค่าให้ Property ของ Object ทำงาน มันจะไปสัมพันธ์กับโค้ดส่วนไหนใน Class นั้นๆ หวังว่าพอจะมีประโยชน์บ้างครับ แต่เอาไปรันจริงไม่ได้นะครับ แค่ตัวอย่างเท่านั้น

โค้ดข้างล่างนี้จะเขียนอยู่ใน Class Module และบันทึกในชื่อ Recordset
โค๊ด: [Select]
Option Compare Database
Option Explicit

Type RecordStructure                ' โครงสร้างของ Recordset Object
    RSField1    As Variant
    RSField2    As Variant
End Type

Dim Ptr         As Integer          ' เก็บตำแหน่งเรคอร์ดปัจจุบันของ Recordset นี้
Dim RC()        As RecordStructure  ' ตัวแปร Recordset Object

Private Sub Class_Initialize()
    ' Procedure จะทำงานโดยอัตโนมัติเมื่อ object ถูกสร้าง
    ' ตย.โค้ดเช่น เพิ่ม object นี้ลงใน Recordsets Collection (Collection คือ อ็อปเจ็คของกลุ่ม Object อีกที)
End Sub

Private Sub Class_Terminate()
    ' Procedure จะทำงานโดยอัตโนมัติเมื่อ object ถูกเคลียร์ให้เป็น Nothing
    ' ตย.โค้ดเช่น นำ object นี้ ออกจาก Recordsets Collection
End Sub

Public Property Let Bookmark(NewPosition As Integer)
    ' กำหนดตำแหน่งเรคอร์ดปัจจุบันของ Recordset
    If NewPosition <= UBound(RC) Then
        Ptr = NewPosition
    Else
        Err.Raise 1234, "Invalid Bookmark"
    End If
End Property

Public Property Get RecordCount() As Long
    ' คืนค่าจำนวนเรคอร์ดทั้งหมดใน Recordset
    RecordCount = UBound(RC)
End Property

Public Property Get Fields(Name As String) As Variant
    ' คืนค่าฟิลด์ตามชื่อฟิลด์ที่ส่งมาในตัวแปร Name
    Select Case Name
        Case "CustomerID"
            Fields = RC(Ptr).RSField1
        Case "CustomerName"
            Fields = RC(Ptr).RSField2
        Case Else
            Err.Raise 2589, "Invalid Field Name"
    End Select
End Property

Public Property Get EOF() As Boolean
    ' คืนค่า True เมื่อตำแหน่งเรคอร์ดปัจจุบันเลยเรคอร์ดสุดท้ายไปแล้ว
    If Ptr > UBound(RC) Then
        EOF = True
    Else
        EOF = False
    End If
End Property

Public Sub MoveNext()
    ' เลื่อนไปยังเรคอร์ดถัดไปใน Recordset
    If Ptr <= UBound(RC) Then
        Ptr = Ptr + 1
    Else
        Err.Raise 7654, "End of file"
    End If
End Sub

ส่วนข้างล่างนี้เป็นโค้ดที่อยู่ใน Module ธรรมดาๆ ที่เรียกใช้ Object, Method และ Property ต่างๆใน Class Module Recordset ครับ
โค๊ด: [Select]
Private Sub Example()
    ' โค้ดพิมพ์ CustomerID และ CustomerName จากเทเบิล Customer ตั้งแต่เรคอร์ดที่ 10 เป็นต้นไป
   
    Dim RS  As DAO.Recordset
       
    Set RS = CurrentDb.OpenRecordset("Customer")
    ' เมื่อ Object ถูกสร้าง จะไปเรียก Class_Initialize procedure มาทำงาน
   
    If RS.RecordCount > 10 Then     ' โค้ดใน Property Get RecordCount จะถูกทำงาน
        RS.Bookmark = 10            ' โค้ดใน Property Let Bookmark จะถูกทำงาน เป็นการนำค่าเข้าไปใน Property Bookmark
    End If
    Do Until RS.EOF                 ' โค้ดใน Property Get EOF จะถูกทำงาน
        Debug.Print RS.Fields("CustomerID") & ";" _
                  & RS.Fields("CustomerName") ' โค้ดใน Property Get Fields จะถูกทำงาน
        RS.MoveNext                 ' โค้ดใน Sub MoveNext จะถูกทำงาน
    Loop
   
    Set RS = Nothing
    ' เมื่อ Object ถูกเคลียร์ จะไปเรียกโค้ดใน Class_Initialize procedure มาทำงาน
End Sub
« แก้ไขครั้งสุดท้าย: 24 ก.ค. 61 , 00:16:03 โดย สันติสุข »

 
โพสต์นี้ได้รับคำขอบคุณจาก: ปิ่นณรงค์


บอร์ดเรียนรู้ Access สำหรับคนไทย