[Class Module] Nhờ mọi người hướng dẫn để code chạy đúng ý

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

Mr.hieudoanxd

Thành viên thường trực
Tham gia
25/10/19
Bài viết
322
Được thích
150
Chào các anh chị trên diễn đàn!
Em mới bập bẹ học về Class module cũng được mấy ngày rồi. Tất cả vẫn còn như một tờ giấy trắng (không biết có bị đục hay không thì không rõ)
Đúng như các cụ nói, cái gì lần đầu cũng sướng. Hôm qua em mới tự viết được Class Module về Event trên WorkSheet phải nói là cảm giác lâng lâng các anh ạ! Dù chưa thành thục lắm.
Ngày hôm nay em viết thử với Event của control trong Useform cụ thể là Event Mouse_move. File em viết em để ở dưới. Đa phần cũng là lượm lặt của các anh trên diễn đàn, trên mạng và thêm mắm, thêm muối theo ý hiểu tuy nhiên nó không ra đúng ý của mình. Cụ thể như sau:
Mong muốn: di chuyển chuột vào Label nào đó thì chỉ label đó đổi Backcolor và Forecolor các label khác không bị ảnh hưởng
File em đang làm: di chuyển chuột vào label nào đó thì toàn bộ label đổi backcolor và forecolor
Nhờ các anh chị chỉ luôn lỗi sai trong code để em hiểu sâu hơn chút chứ
Thú thật với các anh là tuy viết được nhưng vẫn không hiểu rõ bản chất vẫn cứ "Mơ mơ tỉnh tỉnh"
 

File đính kèm

  • Test mouse move with class.xlsb
    18.8 KB · Đọc: 14
Chào các anh chị trên diễn đàn!
Em mới bập bẹ học về Class module cũng được mấy ngày rồi. Tất cả vẫn còn như một tờ giấy trắng (không biết có bị đục hay không thì không rõ)
Đúng như các cụ nói, cái gì lần đầu cũng sướng. Hôm qua em mới tự viết được Class Module về Event trên WorkSheet phải nói là cảm giác lâng lâng các anh ạ! Dù chưa thành thục lắm.
Ngày hôm nay em viết thử với Event của control trong Useform cụ thể là Event Mouse_move. File em viết em để ở dưới. Đa phần cũng là lượm lặt của các anh trên diễn đàn, trên mạng và thêm mắm, thêm muối theo ý hiểu tuy nhiên nó không ra đúng ý của mình. Cụ thể như sau:
Mong muốn: di chuyển chuột vào Label nào đó thì chỉ label đó đổi Backcolor và Forecolor các label khác không bị ảnh hưởng
File em đang làm: di chuyển chuột vào label nào đó thì toàn bộ label đổi backcolor và forecolor
Nhờ các anh chị chỉ luôn lỗi sai trong code để em hiểu sâu hơn chút chứ
Thú thật với các anh là tuy viết được nhưng vẫn không hiểu rõ bản chất vẫn cứ "Mơ mơ tỉnh tỉnh"
Dùng For quét hiện, thì tất cả cùng hiệu ứng đổi mầu là đúng rồi
thử cách này, trong module class
Mã:
Private Sub MouseMove(ilab As MSForms.Label)'   '
    ilab.BackColor = vbRed
    ilab.ForeColor = vbWhite   
End Sub

nhưng code cứ thế nào ý, nên làm lại cho cơ bản đã
 
Upvote 0
Chào các anh chị trên diễn đàn!
Em mới bập bẹ học về Class module cũng được mấy ngày rồi. Tất cả vẫn còn như một tờ giấy trắng (không biết có bị đục hay không thì không rõ)
Đúng như các cụ nói, cái gì lần đầu cũng sướng. Hôm qua em mới tự viết được Class Module về Event trên WorkSheet phải nói là cảm giác lâng lâng các anh ạ! Dù chưa thành thục lắm.
Ngày hôm nay em viết thử với Event của control trong Useform cụ thể là Event Mouse_move. File em viết em để ở dưới. Đa phần cũng là lượm lặt của các anh trên diễn đàn, trên mạng và thêm mắm, thêm muối theo ý hiểu tuy nhiên nó không ra đúng ý của mình. Cụ thể như sau:
Mong muốn: di chuyển chuột vào Label nào đó thì chỉ label đó đổi Backcolor và Forecolor các label khác không bị ảnh hưởng
File em đang làm: di chuyển chuột vào label nào đó thì toàn bộ label đổi backcolor và forecolor
Nhờ các anh chị chỉ luôn lỗi sai trong code để em hiểu sâu hơn chút chứ
Thú thật với các anh là tuy viết được nhưng vẫn không hiểu rõ bản chất vẫn cứ "Mơ mơ tỉnh tỉnh"
Tôi chả biết tý gì về Class Module. Nhưng thử thay iCtl thành ilab thì thấy nó nó chạy đúng với kết quả bạn mong muốn
Mã:
.......
        If TypeOf ilab Is MSForms.Label Then
            ilab.BackColor = vbRed
            ilab.ForeColor = vbWhite
        End If
........
Mong các thành viên khác xem qua và giải thích. Trân trọng cảm ơn.
 
Upvote 0
Em đã đọc được bài của các anh từ
Dùng For quét hiện, thì tất cả cùng hiệu ứng đổi mầu là đúng rồi
Em phải dùng For thì mới Set tất cả Label vào Class được chứ anh
nhưng code cứ thế nào ý, nên làm lại cho cơ bản đã
Anh có cao kiến gì không?
Nhưng thử thay iCtl thành ilab thì thấy nó nó chạy đúng với kết quả bạn mong muốn
Code chạy đúng ý rồi anh! thật tuyệt vời, có vẻ em đang đi đúng hướng.
Em để iCtl thì nó duyệt toàn bộ Label và đổi mầu, để ilab thì nó chỉ đổi mầu ở Label được thực hiện trong sub
Em vẫn cần các anh chị có kinh nghiệm giải quyết giúp em hoặc cho em một vài ví dụ, hoặc một vài file đã làm về Class module dạng đơn giản, cơ bản để em nắm được chặt hơn cái Class module này. Em cũng đã đọc một vài Bài viết trên diễn đàn của anh tuấn, anh tuân rồi ạ!
Note: Cách đặt tên biến của em khùng khoằm quá nên soi code nó cứ bị rối, cộng thêm cái Class module lại càng rối hơn nữa thành ra đầu óc quay mòng mòng
 
Upvote 0
Theo tôi bạn nên tách Class Label ra thành một Class riêng để dễ quản lý, bạn có thể tham khảo thêm một cách nửa như sau:
 

File đính kèm

  • Test mouse move with class.xlsb
    21.6 KB · Đọc: 19
Upvote 0
Cơ bản là em chưa hiểu bản chất vấn đề nên 1 Class vẫn chưa nắm rõ cách thức hoạt động. GIờ anh thêm 1 class nữa không khéo lại rối thêm anh ạ!
Anh có vài file class cơ bản nhẹ nhàng nào không gửi em xin với ạ
Theo tôi bạn nên tách Class Label ra thành một Class riêng để dễ quản lý, bạn có thể tham khảo thêm một cách nửa như sau:
 
Upvote 0
Upvote 0
Mong muốn: di chuyển chuột vào Label nào đó thì chỉ label đó đổi Backcolor và Forecolor các label khác không bị ảnh hưởng
File em đang làm: di chuyển chuột vào label nào đó thì toàn bộ label đổi backcolor và forecolor
Bạn bị rối trong code, khi truyền các tham số cho hàm, thủ tục.
Tôi sửa lại như sau:

- clsEventUF:

Mã:
Private WithEvents m_AniLabel As MSForms.Label
Private WithEvents m_Form As MSForms.UserForm
Private m_LabelColorOrig As Long
Private m_LabelForeColorOrig As Long

Public Property Set ContainForm(ByVal oForm As MSForms.UserForm)
    Set m_Form = oForm
End Property

Public Property Set AnimatedLabel(ByVal oLabel As MSForms.Label)
    Set m_AniLabel = oLabel
    m_LabelColorOrig = oLabel.BackColor     'luu mau goc cua label de tra ve hien trang cu
    m_LabelForeColorOrig = oLabel.ForeColor ' Luu mau font chu goc
End Property

Private Sub m_AniLabel_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    MoveEffect True
End Sub

Private Sub MoveEffect(blnON As Boolean)
    Select Case blnON   'Bat che do hieu ung
        Case True
            m_AniLabel.BackColor = vbRed
            m_AniLabel.ForeColor = vbWhite
        Case False
            m_AniLabel.BackColor = m_LabelColorOrig
            m_AniLabel.ForeColor = m_LabelForeColorOrig
    End Select
End Sub

Private Sub m_Form_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    MoveEffect False
End Sub

- Gọi Class clsEventUF trong Userform:

Mã:
Option Explicit

Dim colLabels As New Collection

Private Sub UserForm_Initialize()
    Dim oLabel As clsEventUF
    Dim ctl As Control
    For Each ctl In Me.Controls
        If TypeName(ctl) = "Label" Then
            Set oLabel = New clsEventUF
            Set oLabel.AnimatedLabel = ctl
            Set oLabel.ContainForm = Me
            colLabels.Add oLabel
        End If
    Next
End Sub

 

File đính kèm

  • Test mouse move class_ongke0711.xlsb
    25 KB · Đọc: 11
Upvote 0
Em đã đọc được bài của các anh từ

Em phải dùng For thì mới Set tất cả Label vào Class được chứ anh

Anh có cao kiến gì không?
Cao kiến, thì là gì nhỉ? đã nói làm lại thì sẽ hiểu
For tôi nhắc đến không liên quan đến Set tất cả Label
 
Upvote 0
Mã trên chỉ ở mức cơ bản. Bạn cần chặn đường dài để học tập.
Để hành động chuột di chuyển qua control hiển thị sinh động. Mã trên dùng biện pháp Move Over trên một control khác để trả về mặc định control trước. Phương pháp này có Nhược điểm khi Move Over trên control không có sự kiện.

Bạn tham khảo phương pháp dưới đây
 

File đính kèm

  • label effect.xlsm
    24.7 KB · Đọc: 19
Upvote 0
Mã trên chỉ ở mức cơ bản. Bạn cần chặn đường dài để học tập.
Để hành động chuột di chuyển qua control hiển thị sinh động. Mã trên dùng biện pháp Move Over trên một control khác để trả về mặc định control trước. Phương pháp này có Nhược điểm khi Move Over trên control không có sự kiện.

Bạn tham khảo phương pháp dưới đây
Đúng như anh nói move trên control thì mất mầu khi mình đổi, ngoài ra còn độ trễ thời gian đổi mầu, Em thử chỉnh tham số tLastest = Timer + 0.52 về + 0.10 thì độ trễ nhỏ hơn (đương nhiên chỉnh về 0.00 thì mất hẳn sự kiện rồi). Vậy 0.52 anh lấy là do đâu nhỉ?
 
Upvote 0
Đúng như anh nói move trên control thì mất mầu khi mình đổi, ngoài ra còn độ trễ thời gian đổi mầu, Em thử chỉnh tham số tLastest = Timer + 0.52 về + 0.10 thì độ trễ nhỏ hơn (đương nhiên chỉnh về 0.00 thì mất hẳn sự kiện rồi). Vậy 0.52 anh lấy là do đâu nhỉ?
Khoảng thời gian nhỏ nhất sự kiện gọi lại khi chuột nằm tại một vị trí duy nhất trên control
 
Upvote 0
Còn một giải thuật khác mà tôi chưa thử là cung cấp tham số kích thước control, khi chuột ra ngoài vùng đó thì tắt hiệu ứng. :)
Tôi thì cứ thường dùng khi chuột di chuyển qua một control khác ví dụ như: cái box, frame chứa các control cần hiệu ứng, nền Userform...
 
Upvote 0
Còn một giải thuật khác mà tôi chưa thử là cung cấp tham số kích thước control, khi chuột ra ngoài vùng đó thì tắt hiệu ứng. :)
Tôi thì cứ thường dùng khi chuột di chuyển qua một control khác ví dụ như: cái box, frame chứa các control cần hiệu ứng, nền Userform...
Hay là anh thử đi anh....
Theo hướng của anh thì phải biết vị trí trỏ chuột trong useform. Vậy thì phải xài API à anh?
 
Upvote 0
Trình độ viết Class Module không phải là trình độ thấp.
Bạn đã tới trình độ này thì phải biết là chỉ bí chỗ nào hỏi thẳng vào chỗ đó. Nhơ người khác debug cả một đống code là việc làm của tay mơ.
Nếu bạn chưa làm được việc này thì cần hỏi lại xem tại sao phải cần tới Class Module tỏng khi mình chả nắm vững gì về kỹ thuật này.
Nếu bạn tự cho rằng mình đủ trình độ thì đọc tiếp, không thì ngưng không đọc nữa và tìm cách viết code thường.

Nếu class hoạt động không như mình thiết kế thì phải cho biết rõ ràng bạn muốn cái class ấy có tính năng gì.
Người giúp cần biết chúng để xét lại thiết kế xem bạn có đủ:
1. các thuộc tính public cần thiết
2. các phuonwg thức cần public cần thiết
3. các thuộc tính và phuonwg thức private cần thức để hổ trợ 1 và 2 trên
4. các tính nnanwg đặc biệt như kỹ xảo để đi vòng qua các giới hạn của bảng tính, vv...
Thiết kế phải rõ thì mới debug được:
5. thiết kế đã đầy đủ chưa?
6. code có đúng như thiết kế?
 
Upvote 0
Trình độ viết Class Module không phải là trình độ thấp.
Bạn đã tới trình độ này thì phải biết là chỉ bí chỗ nào hỏi thẳng vào chỗ đó. Nhơ người khác debug cả một đống code là việc làm của tay mơ.
Em nhận luôn với anh em thuộc tầm trình độ thấp. Nhưng lại có hứng thú đặc biệt với việc tìm hiểu code, thậm chí bỏ công bỏ việc ngồi học viết code.
Cách học của em cũng có phần củ chuối. Với người khác đọc, hiểu nắm vững lý thuyết rồi đi vào thực hành. Còn với bản thân em tầm nhận thức hạn chế, đọc lý thuyết câu vào đầu, câu rớt ra ngoài mất tiêu. Do đó em thường hay xem file của mọi người làm trên này, nắm được quy luật quay lại xem chút lý thuyết và viết theo. Với kiểu học này em biết là có rất nhiều hạn chế ví dụ: Chỉ cần gặp bug lạ khác với những bài đã xem là tịt, hoặc như trong bài của em, em luẩn quẩn trong sử dụng biến thôi cũng thành ra khó. Nhưng biết sao được anh.
Nếu bạn chưa làm được việc này thì cần hỏi lại xem tại sao phải cần tới Class Module tỏng khi mình chả nắm vững gì về kỹ thuật này.
Nếu bạn tự cho rằng mình đủ trình độ thì đọc tiếp, không thì ngưng không đọc nữa và tìm cách viết code thường.
Về ví dụ này em đã viết được bằng code thường lâu rồi (em cũng thuộc kiểu mầu mè thích trang trí Useform), có điều code lập đi lập lại thôi. Em thiết nghĩ chả ai lại cần thiết phải hỏi bản thân có nên học hỏi một cái mới để nâng cao trình độ bản thân cả. Ai cũng có nhu cầu cầu tiến, đột phá giới hạn bản thân. Và cuối cùng, đôi lời gửi đến anh, dù trình độ em không đủ em vẫn muốn đọc và học tiếp!
Cảm ơn anh về một số góp ý ở dưới!
 
Upvote 0
.... Và cuối cùng, đôi lời gửi đến anh, dù trình độ em không đủ em vẫn muốn đọc và học tiếp!
Cảm ơn anh về một số góp ý ở dưới!
Xem kỹ lại phấn sau của bài tôi.

Code kiểu cấu trúc cần sơ đồ code.

Code kiểu class thì tuy VBA không phải là ngôn ngữ LTHĐT, nhưng class cũng có luật tối thiểu của nó: quy luật gói trọn.
Sơ đồ thiết kế class phải có phần từ 1 đến 4 tôi đã kể trên.
Phần 1 và 2 là giao diện của class.
Phần 3 là phần class không đưa ra, chỉ dùng bên trong class để hổ trợ 1 và 2 mà thôi.
Ví dụ bạn có class SoPhuc (complex number). Phần thuộc tính public là n, i, alpha, r, ...
Bình thường thì bạn chỉ cần chứa n và i thôi. alpha và r có thể tính ra. Vì vậy bạn đặt hai biến private, ii và ni để chứa i và n. 4 thuộc tính Public i, n, a, r bạn tính từ đó ra khi người dùng truy cập.
Đương nhiên còn một đống phương thức để tính cộng trừ nhân chia. Ví dụ tính cộng bạn có phương thức cong(c1, c2)
Function cong(c1 as SoPhuc, c2 as Sophuc) As Sophuc
cong.ii = c1.i + c2.i ' hàm này bên trong class nên có thể truy cập thuộc tính private của class
cong.ni = c1.n + c2.n
Dim usc as double
usc = UocSoChungLonNhat(cong.i, cong.n)
if usc > 1 Then
cong.ii = cong.ii / usc
cong.ni = cong.ni / usc
End If
End Function
Như trên, hàm cong là public, nhưng hàm UocSoChungLonNhat là private, người dùng không cần biết tới, thậm chí nó có thể là hàm ngoài Class.
Phần 4 có lẽ không cần vì như bạn nói chỉ tập viết thôi chứ không có ý lợi dụng class module để thực hiện một số viếc mà module thường bị Excel cấm. (Excel cấm vì chúng có khả năng phá vỡ cơ cấu bảng tính, Class Module mở ra là vì MS tin rằng ai đã có khả năng viết loại code này thì cũng có cách gỡ, chữa cháy)
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom