Hỏi về viết Class Module trong VBA (1 người xem)

Người dùng đang xem chủ đề này

langtuchungtinh360

Thành viên đã dừng hoạt động
Tham gia
7/10/13
Bài viết
1,062
Được thích
334
chào mọi người
lời đầu em chúc mọi người một buổi sáng đầu tuần mạnh khỏe và tràn đầy niềm vui
vào thẳng vấn đề luôn he
chả là e đang tập tành viết Class
vấn đề là trên Sheet thì mình có hàm offset(x,y,a,b) để lấy 1 vùng a,b bắt đầu tại vị trí x,y
vậy trong VBA thì lại không thể áp dụng vào để lấy 1 vùng trong mảng với offset và resize
nên em muốn viết 1 Class để làm công việc này
ví dụ trong ClassModule1 có sub xOffset (Mảng, vị trí z, vị trí y)
thì code là
with New ClassModule1
.xOffset(Arr,x,y).??????
end with
làm sao để có thể "." tiếp ngay sau hàm Offset được?
có thể em chưa biết lệnh nào tương tự như hàm Offset nên nếu có lệnh như thế mong mọi người chỉ giúp để em đỡ viết lệnh làm chậm quá trình xử lý đi
tiện thể chỉ em cách làm được vấn đề trên để sau này em áp dụng công việc viết class.
 
Lý thuyết class:
Nếu hàm xOffset(a,b,c) trả về một Object thì ta có thể gọi xOffset(a,b,c).CaiGiDo
Trong đấy, CaiGiDo là một hàm hay thuộc tính của loại Object trên

Ví dụ, nếu xOffset trả về 1 range thì có thể gọi xOffset(a,b,c).Cells(i,j) vì Cells là một thuộc tính của range
 
Upvote 0
Muốn sinh ra thêm cái gì sau dấu chấm thì cái hàm xOffset đó trả về một kết quả kiểu Class hoặc Type (đã có hoặc tự đặt). Rồi cứ chọt chấm cái là nó sổ ra //**/
Lý thuyết class:
Nếu hàm xOffset(a,b,c) trả về một Object thì ta có thể gọi xOffset(a,b,c).CaiGiDo
Trong đấy, CaiGiDo là một hàm hay thuộc tính của loại Object trên

Ví dụ, nếu xOffset trả về 1 range thì có thể gọi xOffset(a,b,c).Cells(i,j) vì Cells là một thuộc tính của range
vâng! quan trọng là em không biết viết như thế nào.+-+-+-+
 
Upvote 0
Bạn đã có ý tưởng như đầu tu pic nghĩa là bạn dư khả năng thực hiện rồi. Chẳng qua bạn bị hội chứng "bài tập mẫu" thời học sinh thôi. Tôi diễn ta nôm na thế này:

Class People:
Mã:
Public High As String
Sub Hênô()
    MsgBox "hê nô"
End Sub

Class Cambodian:
Mã:
Function Someone() As People
    Set Someone = New People
End Function


Áp dụng ta có:
Mã:
Sub test()
    Dim teo As Cambodian
    Set teo = New Cambodian
    teo.Someone.Hênô
End Sub
Đại loại như thế. Mới tự tét xong, chạy ầm ầm luôn.--=0
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn đã có ý tưởng như đầu tu pic nghĩa là bạn dư khả năng thực hiện rồi. Chẳng qua bạn bị hội chứng "bài tập mẫu" thời học sinh thôi. Tôi diễn ta nôm na thế này:

Class People:
Mã:
Public High As String
Sub Hênô()
    MsgBox "hê nô"
End Sub

Class Cambodian:
Mã:
Function Someone() As People
    Set Someone = New People
End Function


Áp dụng ta có:
Mã:
Sub test()
    Dim teo As Cambodian
    Set teo = New Cambodian
    teo.Someone.Hênô
End Sub
Đại loại như thế. Mới tự tét xong, chạy ầm ầm luôn.--=0
như thế thì phải dùng 2 class anh nhỉ, nếu mà viết cho 1 dự án thì nên viết class hay là nên viết hàm function anh nhỉ, hàm thì em viết được rồi. giờ đang tập class để cho bảng tính excel bớt hàm đi. chứ có nhiều hàm chỉ viết dùng cho VBA còn trong excel không dùng đến mà nó cứ hiện ra trong danh sách hàm tự tạo @@
 
Upvote 0
như thế thì phải dùng 2 class anh nhỉ, nếu mà viết cho 1 dự án thì nên viết class hay là nên viết hàm function anh nhỉ, hàm thì em viết được rồi. giờ đang tập class để cho bảng tính excel bớt hàm đi. chứ có nhiều hàm chỉ viết dùng cho VBA còn trong excel không dùng đến mà nó cứ hiện ra trong danh sách hàm tự tạo @@
Nếu bạn chưa biết cách viết thì tôi gợi ý cho bạn bài đơn giản thông tin về hình chữ nhật, bạn có thể xem cách viết và làm theo
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
như thế thì phải dùng 2 class anh nhỉ, nếu mà viết cho 1 dự án thì nên viết class hay là nên viết hàm function anh nhỉ, hàm thì em viết được rồi. giờ đang tập class để cho bảng tính excel bớt hàm đi. chứ có nhiều hàm chỉ viết dùng cho VBA còn trong excel không dùng đến mà nó cứ hiện ra trong danh sách hàm tự tạo @@
Không hiểu bạn có nhìn nhận Range, Sheet, Application.v.v. thuộc về một class nào đó không?

VBA có mấy class dựng sẵn đó bạn . Trong mỗi class dựng sẵn đó lại có properties hay proceduces thuộc về một class dựng sẵn khác. Cho nên thích thì ta lồng 2, 3....n class cũng chẳng ai trách được //////.

Viết class để tiếp cận với xu hướng lập trình hiện đại thôi. Còn nếu quen thì viết hướng module/proceduce/event... xưa cũng được. Tôi chưa bao giờ viết class cho mấy chú VBA/VB cả phần vì trình có hạn, phần nữa vì tính hướng đối trong VBA rất nghèo nàn.
 
Lần chỉnh sửa cuối:
Upvote 0
Lập trình Class Module trong VBA cần làm khi ứng dụng kha khá lớn hoặc trong hoàn cảnh đặc biệt cần nhân bản đối tượng. Để tạo ra Class hoạt động đúng tính chất (như các Object trong Excel: Range, Worksheet, Workbook,...) cần đầu tư học bài bản hoặc cần nhiều thời gian đọc tài liệu chuẩn còn học chắp vá thì Class Module tạo ra không thể hiện được điểm sáng gì so với lập trình thủ tục, hàm trong Module thông thường.
 
Upvote 0
Về bản chất VBA sinh ra là không để cho class, thiên về thực dụng, nên tốt nhất hạn chế sử dụng class càng nhiều càng tốt. Nếu vẫn ham Class thì nên học thông qua các ngôn ngữ lập trình thực khác.
 
Upvote 0
Về bản chất VBA sinh ra là không để cho class, thiên về thực dụng, nên tốt nhất hạn chế sử dụng class càng nhiều càng tốt. Nếu vẫn ham Class thì nên học thông qua các ngôn ngữ lập trình thực khác.

Có thể bạn lẫn lộn giữa class và lập trình hướng đối tượng. Hướng đối tượng thường được thể hiện qua class nhưng class không nhất thiết phải hội đủ các điều kiện của hướng đối tượng.

Nếu có dự tính làm việc lâu dài với VBA, và phát triển code hàng trăm modules (*) thì học phương pháp gói trọn code của class cũng là điều nên làm.

Lưu ý ở đây tôi cần nhấn mạnh từ modules. Người viết code phát triển (developer) phần mềm lớn cũng học luôn cách tách code ra từng cụm modules riêng biệt, thường thì những hàm, sub có nhiệm vụ tương tợ, môi trường tương tợ thì để chung với nhau. Kinh nghiệm chung cho thấy nếu gói gọn chúng vào những class modules thì sẽ dễ dùng và dễ bảo quản hơn là dùng code modules.

Đồng thời, với VBA thì class module là cách dễ nhất để thực hiện các hiện tượng (events) tự chế. Đây cũng là một nhiệm vụ quan trọng của class module.
 
Upvote 0
Tôi vốn dân nghiệp dư nên không dám bàn về chuyên môn kỹ thuật, nhưng tôi thấy nếu phù hợp thì gắng vận dụng mà xài.
Dân kế toán làm mấy file quản lý và sử lý dữ liệu không dùng SQL thì dùng Class Module tuyệt còn gì. Chỗ nào cũng hay đá đến Nhâp-Xuất-Tồn, Thu-Chi-Tồn, Du-Nợ-Có. Ta chỉ cần viết 1 Class Module khi sử lý cung cấp cho nó Tồn đầu kỳ, Nhập vào, Xuất ra vậy là có ngay số dư di động rồi. Khai báo dạng mảng là ta có ngay bảng xuất nhập tồn rồi. Khi dùng ta chỉ việc khai báo và cung cấp số liệu là xong, bớt nhiều cung đoạn cộng trừ nhân chia phức tạp. (Cứ tưởng tượng bảng XNT có cả lượng và tiền mà xem) . Quả thật, khi dùng nó code kiếc gọn gàng nhiều mà ít sai sót.
Hơn nữa, nó còn dễ bảo hơn nhiều môn phái khác, là người nhà nên còn bắt nạt được, chứ cái khác đành là hay nhưng chào thua vì nó đỏng đảnh quá đòi hỏi quá thì chiều sao nổi.
 
Upvote 0
sau một thời gian tìm hiểu để viết Class, cũng tích lũy được một ít
và sau khi mày mò đủ kiểu đã phát sinh 1 vấn đề không biết giải quyết thế nào
vấn đề là chạy code không thể gọi được thủ tục sự kiện
chi tiết mình có nêu trong file
mong nhận được sự giúp đỡ từ mọi người
do mình còn gà mờ về viết code nên không tránh được sai sót code quá dài hoặc dư thừa nên rất mong được sự chỉ bảo từ mọi người
ps: trong quá trình bình luận nếu mình có nói gì làm mất lòng thì mọi người bỏ quá cho. (mất lòng trước được lòng sau- tranh luận mà, phải có xích mích chứ nhỉ -\\/.)
mình đã xem bài của thầy tuân rồi mà vẫn chưa giải quyết được vấn đề
file đính kèm
một lần nữa rất mong nhận được sự giúp đỡ từ mọi người.
 
Upvote 0
sau một thời gian tìm hiểu để viết Class, cũng tích lũy được một ít
và sau khi mày mò đủ kiểu đã phát sinh 1 vấn đề không biết giải quyết thế nào
vấn đề là chạy code không thể gọi được thủ tục sự kiện
chi tiết mình có nêu trong file
mong nhận được sự giúp đỡ từ mọi người
do mình còn gà mờ về viết code nên không tránh được sai sót code quá dài hoặc dư thừa nên rất mong được sự chỉ bảo từ mọi người
ps: trong quá trình bình luận nếu mình có nói gì làm mất lòng thì mọi người bỏ quá cho. (mất lòng trước được lòng sau- tranh luận mà, phải có xích mích chứ nhỉ -\\/.)
mình đã xem bài của thầy tuân rồi mà vẫn chưa giải quyết được vấn đề
file đính kèm
một lần nữa rất mong nhận được sự giúp đỡ từ mọi người.
Không biết là tui may mắn hay bạn xui xẻo nữa... bởi tôi thực hiện các bước như mô tả trong file của bạn mà không phát hiện lỗi nào cả
 
Upvote 0
Không biết là tui may mắn hay bạn xui xẻo nữa... bởi tôi thực hiện các bước như mô tả trong file của bạn mà không phát hiện lỗi nào cả
lạ nhỉ, sao máy em nó lỗi lạ ta
[video=youtube;LNvoV43BdI0]https://www.youtube.com/watch?v=LNvoV43BdI0[/video]
 
Lần chỉnh sửa cuối:
Upvote 0
Không gọi được sự kiện classmodule khi Add Name vào sheet

mọi người giúp mình làm sao để không bị lỗi gọi sự kiện được vậy, sau mấy ngày ngồi viết code lại mới phát hiện ra là do Add Name vào thì không thể gọi được sự kiện, mong được trợ giúp từ mọi người
kết quả mình muốn là vừa Add Name thêm vào được, vừa tạo textbox, gọi được sự kiện ngay khi đóng form luôn.
sau khi đóng form thì code gọi sự kiện vẫn chạy được.
trong file mình có nêu các bước để thấy được lỗi
link
cảm ơn mọi người trước
 
Upvote 0
sau một thời gian tìm hiểu để viết Class, cũng tích lũy được một ít
và sau khi mày mò đủ kiểu đã phát sinh 1 vấn đề không biết giải quyết thế nào
vấn đề là chạy code không thể gọi được thủ tục sự kiện
chi tiết mình có nêu trong file
mong nhận được sự giúp đỡ từ mọi người
do mình còn gà mờ về viết code nên không tránh được sai sót code quá dài hoặc dư thừa nên rất mong được sự chỉ bảo từ mọi người
ps: trong quá trình bình luận nếu mình có nói gì làm mất lòng thì mọi người bỏ quá cho. (mất lòng trước được lòng sau- tranh luận mà, phải có xích mích chứ nhỉ -\\/.)
mình đã xem bài của thầy tuân rồi mà vẫn chưa giải quyết được vấn đề
file đính kèm
một lần nữa rất mong nhận được sự giúp đỡ từ mọi người.

Đưa file lên hỏi mà còn chèn quảng cáo nữa sao.
 
Upvote 0
mọi người giúp mình làm sao để không bị lỗi gọi sự kiện được vậy, sau mấy ngày ngồi viết code lại mới phát hiện ra là do Add Name vào thì không thể gọi được sự kiện, mong được trợ giúp từ mọi người
kết quả mình muốn là vừa Add Name thêm vào được, vừa tạo textbox, gọi được sự kiện ngay khi đóng form luôn.
sau khi đóng form thì code gọi sự kiện vẫn chạy được.
trong file mình có nêu các bước để thấy được lỗi
link
cảm ơn mọi người trước

Tôi cũng thực hiện ở các files (cả file mới) đưa lên đều không gặp lỗi gì cả (không hiểu ở đây bạn là lỗi gì?)

Có chăng thì chương trình vẫn chạy nhưng bị mất chức năng như bạn mong muốn?
nếu đúng thế thì Khắc phục:

Đừng bao giờ thực hiện b7
[TABLE="width: 296"]
[TR]
[TD]B7[/TD]
[TD]xóa dòng ghi chú 'XÓA DÒNG NÀY NHA[/TD]
[/TR]
[/TABLE]
Vì là người dùng cuối có bao giờ đang thực hiện chương trình lại chui vào VBE để nghịch code đâu, mà đã nghịch thì sau đó phải đóng file làm lại từ đầu hoặc người biết phải reset lại các biến global các liên kết (nếu có) trước khi chạy tiếp

Tại sao vậy, bạn chui vào code mà có thay đổi (dù xóa dòng ghi chú), thì VBE sẽ reset lại sub/function đó, mà đã reset lại thì những gì ở các biến global sẽ có thể bị tác động có thể mất phương hướng ... có thể là nguyên nhân dẫn đến tình trạng như bạn gặp
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi cũng thực hiện ở các files (cả file mới) đưa lên đều không gặp lỗi gì cả (không hiểu ở đây bạn là lỗi gì?)

Có chăng thì chương trình vẫn chạy nhưng bị mất chức năng như bạn mong muốn?
nếu đúng thế thì Khắc phục:

Đừng bao giờ thực hiện b7
[TABLE="width: 296"]
[TR]
[TD]B7[/TD]
[TD]xóa dòng ghi chú 'XÓA DÒNG NÀY NHA[/TD]
[/TR]
[/TABLE]
Vì là người dùng cuối có bao giờ đang thực hiện chương trình lại chui vào VBE để nghịch code đâu, mà đã nghịch thì sau đó phải đóng file làm lại từ đầu hoặc người biết phải reset lại các biến global các liên kết (nếu có) trước khi chạy tiếp

Tại sao vậy, bạn chui vào code mà có thay đổi (dù xóa dòng ghi chú), thì VBE sẽ reset lại sub/function đó, mà đã reset lại thì những gì ở các biến global sẽ có thể bị tác động có thể mất phương hướng ... có thể là nguyên nhân dẫn đến tình trạng như bạn gặp
bạn xem file mới tại #16 chưa, ý bạn trả lời mình đã giải quyết được rồi. file mới muốn hỏi tại sao khi đóng form đi thì có lênh add thêm Name vào thì code gọi sự kiện không hoạt động được.
vụ Add hay Xóa Name thì có ảnh hưởng gì đến lệnh gọi sự kiện trong class hay không? vậy có cách nào khắc phục không? cho dù có giải phóng biến thì khi đó gọi lại thì vẫn chạy được bình thường chứ nhỉ?
 
Upvote 0
bạn xem file mới tại #16 chưa, ý bạn trả lời mình đã giải quyết được rồi. file mới muốn hỏi tại sao khi đóng form đi thì có lênh add thêm Name vào thì code gọi sự kiện không hoạt động được.
vụ Add hay Xóa Name thì có ảnh hưởng gì đến lệnh gọi sự kiện trong class hay không? vậy có cách nào khắc phục không? cho dù có giải phóng biến thì khi đó gọi lại thì vẫn chạy được bình thường chứ nhỉ?

xem rồi, thấy các bước bạn nói trong file vẫn y như cũ có khác đâu?

và xem kỹ lại thì có thấy dòng code nào là
tại sao khi đóng form đi thì có lênh add thêm Name vào thì code gọi sự kiện không hoạt động được
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Taotextbox
End Sub
 
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
uhm file này thì khác
Nhưng vẫn tình trạng Lỗi chức năng chương trình khi bấm ADD dù có hay không có Add NAME - giống như cũ
lỗi thế nào bạn? mình thử chỉ có khi chạy code Add thêm Name cho file thì nó mới bị.
có cách nào khắc phục không bạn.
 
Upvote 0
lỗi thế nào bạn? mình thử chỉ có khi chạy code Add thêm Name cho file thì nó mới bị.
có cách nào khắc phục không bạn.

Lỗi là textbox không di chuyển theo sự kiện select..., dù có E1=0 (trường hợp down về mở file ngay) , và sau thì khi có name

KHẮC PHỤC:
Làm như sau:

- thay 2 sub Taotextbox Insert0, bởi 3 sub dưới đây
Mã:
 Sub Taotextbox()
    Insert0 ActiveSheet, "Forms.TextBox.1"
    Application.OnTime Now() + TimeValue("00:00:01"), "KhoiTaoGlobal"
    Application.Wait Now() + TimeValue("00:00:01")
End Sub

Sub Insert0(Optional ByVal Ws As Worksheet, Optional nID As String)
    Dim obj As OLEObject
    Application.EnableEvents = False
'XÓA DÒNG NÀY NHA
    For Each obj In Ws.OLEObjects
        If obj.progID = nID Then GoTo Thoat
    Next
    Set obj = Ws.OLEObjects.Add(ClassType:=nID, Link:=False, DisplayAsIcon:=False, _
            Left:=0, Top:=0, Width:=50, Height:=18)
Thoat:
    Application.EnableEvents = True
    Exit Sub
    
    If dim_clsTextbox Is Nothing Then
        Set dim_clsTextbox = New clsTextBox
        dim_clsTextbox.Wrap obj.Object
    End If
    If dim_WsChange Is Nothing Then
        Set dim_WsChange = New WsChange
        dim_WsChange.CreateApp Application
    End If
    'Set objtx = obj
   
    Application.EnableEvents = True
    
    Set Ws = Nothing
    Set obj = Nothing
End Sub

Sub KhoiTaoGlobal()    
    If dim_WsChange Is Nothing Then
        'MsgBox "xay ra 1 dim_WsChange Is Nothing "
        Set dim_WsChange = New WsChange
        dim_WsChange.CreateApp Application
    End If
    If dim_clsTextbox Is Nothing Then
        'MsgBox "xay ra 2 dim_clsTextbox Is Nothing "
        Set dim_clsTextbox = New clsTextBox
        dim_clsTextbox.Wrap ActiveSheet.TextBox1
    End If
End Sub

Bạn thử sẽ kết quả như ý, dù có name, hay không có add name

---------tìm nguyên nhân
tất nhiên từ sau đoạn
Exit Sub
của sub Insert0 thì các dòng code cũ đó có thể xóa đi, để lại cho bạn có thể thử tìm ra nguyên nhân, thử bằng cách
- bật 2 dòng chi chú MSGBOX trong sub KhoiTaoGlobal
- tạm tắt dòng Exit sub ở sub Insert0 trên đi
sẽ thấy là sao các biến obj từ các class dù đã gán ở insert0 (sau exit sub) nhưng sang khoitaoglobal nó vẫn là nothing (???) - sự mất phương hướng là ở chỗ này
==> bạn xem code và tự rút ra nguyên nhân tại sao,
Tôi chỉ tạm làm code chữa tình huống vậy thui, chắc còn nhiều cách khác hay hơn
 
Lần chỉnh sửa cuối:
Upvote 0
sẽ thấy là sao các biến obj từ các class dù đã gán ở insert0 (sau exit sub) nhưng sang khoitaoglobal nó vẫn là nothing (???) - sự mất phương hướng là ở chỗ này
==> bạn xem code và tự rút ra nguyên nhân tại sao,
Tôi chỉ tạm làm code chữa tình huống vậy thui, chắc còn nhiều cách khác hay hơn
xem mà cũng chả hiểu tại sao nữa bác ạ, code toàn mò chỉnh sửa lại không à nên không hiểu nguyên nhân.
rất mong được sự giải thích
trước kia mình nghĩ chắc là do code chạy nhanh quá nó tạo không kịp, phải dừng lại một thời gian mới được
nhưng sau khi thử thì chả có gì khác, tương tự như vậy, code bạn cho cũng có Wait


rồi ban đầu xem code bạn cho mình cũng lại nghĩ là do nguyên nhân trên hoặc do giải phóng biến Worksheet hay Object chăng.
đã thử cho code Application.Wait Now() + TimeValue("00:00:01") vào trước khi gọi class và không giải phóng biến thì class cũng chả chạy
=> bó tay. dân nghiệp dư ko có kiến thức cơ bản nên không hiểu nguyên do rồi bác ạ


với lại rất ít khi mình thấy code này xuất hiện
Application.Wait Now() + TimeValue("00:00:01")
lần duy nhất mình thấy là để xử lý file nén vì khi nén file không kịp mà code đã chạy tiếp nên phải chờ 1 thwofi gian để nó xử lý xong mới chạy code
có phải nguyên nhân cũng là đây
hay là do gọi sự kiện trước sau có khác nhau chăng


ps: rất mong được sự giải thích từ bác để mở rộng thêm
 
Upvote 0
Sử dụng được chưa?, nếu kết quả tốt rui thì dùng thui

trước kia mình nghĩ chắc là do code chạy nhanh quá nó tạo không kịp, phải dừng lại một thời gian mới được

Đúng 1 nửa rồi,

Không phải code chạy nhanh quá, mà là ngược lại

- vì code của bạn nhét vào sự kiện Form_QueryClose -- nên nó chưa kịp focus vào textbox được,
- nên cần 1 thời gian để thực hiện

(thử bỏ ra ngoài Form xem, tực là nút ADD trực tiếp TaoTextbox - thì sẽ không cần phải chờ gì cả)

Lý do đơn giản vậy thui
 
Upvote 0
Sử dụng được chưa?, nếu kết quả tốt rui thì dùng thui



Đúng 1 nửa rồi,

Không phải code chạy nhanh quá, mà là ngược lại

- vì code của bạn nhét vào sự kiện Form_QueryClose -- nên nó chưa kịp focus vào textbox được,
- nên cần 1 thời gian để thực hiện

(thử bỏ ra ngoài Form xem, tực là nút ADD trực tiếp TaoTextbox - thì sẽ không cần phải chờ gì cả)

Lý do đơn giản vậy thui
ok, cảm ơn bác, để thử lại các kiểu tìm nguyên nhân xem sao.
 
Upvote 0

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

Back
Top Bottom