Một số câu hỏi liên quan đến lập trình VBA: Private, Public sub

  • Thread starter Thread starter boyxin
  • Ngày gửi Ngày gửi
Liên hệ QC

boyxin

Members actively
Tham gia
10/3/08
Bài viết
1,664
Được thích
2,335
Em mới tập tẹ học mót VBA của các bác trên GPE em thấy code của các bác có

  • Sub
  • Public Sub
  • Private Sub
  1. Vị trí đặt code? Khi nào thì cần thêm Public? (tương tự với Private ?) vào trước Sub
  2. Nhiều lúc em thêm, bỏ Public (tương tự với Private) thì không thấy khác nhau, nhưng có trường hợp làm như vậy thì code đang chạy tốt -> không chạy (và ngược lại)

Mong được các bác giải thích thêm để em tiến bộ

--------------------------
Nếu câu hỏi bị coi là chen ngang chủ để thì mong MOD chuyển thành New Topic giúp em

Đúng là "chen ngang chủ đề". Đã chuyển thành New Topic. Phải chi ai cũng có một câu như bạn thì tốt quá. Thanks.
 
Chỉnh sửa lần cuối bởi điều hành viên:
  1. Vị trí đặt code? Khi nào thì cần thêm Public? (tương tự với Private ?) vào trước Sub
  2. Nhiều lúc em thêm, bỏ Public (tương tự với Private) thì không thấy khác nhau, nhưng có trường hợp làm như vậy thì code đang chạy tốt -> không chạy (và ngược lại)
Tôi xin được giải thích 1 chút theo ý hiểu của tôi nhé.
- Nếu trong cùng 1 Module thì Public hay Private là giống nhau.
- Nếu 2 module khác nhau thì đứng ở Module này chỉ sử dụng biến, hằng, thủ tục hoặc hàm của Module kia khi là Public, còn khi là Private thì không thể. Từ đó dễ hiểu là nếu bạn muốn viết 1 UDF thì bạn phải khai báo là Public, nếu là Private thì bạn không dùng được trên Sheet đâu.
- Đối với hàm(Function) hay thủ tục(Sub) viết trong 1 Module khi viết có thể khai báo tường minh(Có Public hoặc Private) hoặc không tường minh(Không có Public hoặc Private), nếu bạn khai báo không tường minh thì VBA sẽ mặc định coi là Public.
 
Upvote 0
Tôi xin được giải thích 1 chút theo ý hiểu của tôi nhé.
- Nếu trong cùng 1 Module thì Public hay Private là giống nhau.
- Nếu 2 module khác nhau thì đứng ở Module này chỉ sử dụng biến, hằng, thủ tục hoặc hàm của Module kia khi là Public, còn khi là Private thì không thể. Từ đó dễ hiểu là nếu bạn muốn viết 1 UDF thì bạn phải khai báo là Public, nếu là Private thì bạn không dùng được trên Sheet đâu.
- Đối với hàm(Function) hay thủ tục(Sub) viết trong 1 Module khi viết có thể khai báo tường minh(Có Public hoặc Private) hoặc không tường minh(Không có Public hoặc Private), nếu bạn khai báo không tường minh thì VBA sẽ mặc định coi là Public.
Tiện đây cho tôi hỏi phần này: Tôi có 2 phần
1/ Phần này là khi nhấn CB.
Cái này đặt trong Sheet "KT-N"
PHP:
Public Sub CBNha_Click()
Dim shName ' As String
'***Phan khai bao theo tung sh - 'xoa sheet Tmp
With Sheets("Tmp") 'Cai nay thay doi, muc III la muc Loc
    .[A2:J1000].ClearContents
    .[O1].Value = "MaCT"
    .[O2].Value = "'=" & "MaCT"
End With
shName = "KT-N"
LayBien
End Sub
Xoa tmp và gán shNam là "KT-N"
2/ Chạy code LayBien với shName là "KT-N"
Cái này đặt trong module
PHP:
Sub LayBien()
Dim RowCuoi As Long, ColCuoi As Long
Dim DKien As Range, Extract As Range, MaLoc As Range, iMaLoc As String
RowCuoi = 40: ColCuoi = 30
Set WF = WorksheetFunction
''***Phan khai bao theo tung sh
MsgBox Sheets(shName).Name

End Sub
Thì nó báo out of range, không lấy được shName.
Chân thành cám ơn!
 
Upvote 0
Tiện đây cho tôi hỏi phần này: Tôi có 2 phần
1/ Phần này là khi nhấn CB.
Cái này đặt trong Sheet "KT-N"
PHP:
Public Sub CBNha_Click()
Dim shName ' As String
'***Phan khai bao theo tung sh - 'xoa sheet Tmp
With Sheets("Tmp") 'Cai nay thay doi, muc III la muc Loc
    .[A2:J1000].ClearContents
    .[O1].Value = "MaCT"
    .[O2].Value = "'=" & "MaCT"
End With
shName = "KT-N"
LayBien
End Sub
Xoa tmp và gán shNam là "KT-N"
2/ Chạy code LayBien với shName là "KT-N"
Cái này đặt trong module
PHP:
Sub LayBien()
Dim RowCuoi As Long, ColCuoi As Long
Dim DKien As Range, Extract As Range, MaLoc As Range, iMaLoc As String
RowCuoi = 40: ColCuoi = 30
Set WF = WorksheetFunction
''***Phan khai bao theo tung sh
MsgBox Sheets(shName).Name

End Sub
Thì nó báo out of range, không lấy được shName.
Chân thành cám ơn!
Em vẫn chưa rõ code chỗ này lắm, bác có thể gửi luôn file lên không vì xem trực tiếp dễ hơn. Còn nếu em hiểu không nhầm thì nó báo lỗi dòng
Mã:
MsgBox Sheets(shName).Name
và có phải bác muốn shName ở đây là biến shName khai báo trong Sub CBNha_Click, nếu vậy thì bác bỏ khai báo ở đây đi và thay bằng khai báo ở trong Module dùng chung như sau
Mã:
Public shName as String
 
Upvote 0
Đã làm theo trên code
Public shName as String
Cám ơn bạn nhiều!
Còn vấn đề này muốn hỏi
PHP:
Sub CBNha_Click()
'***Phan khai bao theo tung sh - 'xoa sheet Tmp
'With Sheets("Tmp") 'Phan nay OK
'    .[A2:J1000].ClearContents
'    .[O1].Value = "MaCT"
'    .[O2].Value = "'=" & "III"
'End With
With Sheets("Tmp") 'Phan nay khong chiu No bao run time error 1004
    Range(.Cells(2, 1), .Cells(1000, 10)).ClearContents
    .Cells(1, 15) = "MaCT"
    .Cells(2, 15) = "'=" & "III"
End With
shName = "KT-N"
LayBien
End Sub
Trong code sau nếu khai
PHP:
With Sheets("Tmp") 'Phan nay OK
    .[A2:J1000].ClearContents
    .[O1].Value = "MaCT"
    .[O2].Value = "'=" & "III"
End With
Thì OK nhưng khi chuyển thành
PHP:
With Sheets("Tmp") 'Phan nay khong chiu No bao run time error 1004
    Range(.Cells(2, 1), .Cells(1000, 10)).ClearContents
    .Cells(1, 15) = "MaCT"
    .Cells(2, 15) = "'=" & "III"
End With
Thì báo 1004, mà
.[A2:J1000] có <> Range(.Cells(2, 1), .Cells(1000, 10))
Xin cám ơn. Do tôi học VBA không bài bản.
 

File đính kèm

Upvote 0
, Nhưng khi chuyển thành
PHP:
With Sheets("Tmp") 'Phan nay khong chiu No bao run time error 1004
    Range(.Cells(2, 1), .Cells(1000, 10)).ClearContents
    .Cells(1, 15) = "MaCT"
    .Cells(2, 15) = "'=" & "III"
End With
Thì báo 1004, mà
.[A2:J1000] có <> Range(.Cells(2, 1), .Cells(1000, 10))
Xin cám ơn. Do tôi học VBA không bài bản.

Hình như bạn thiếu 1 dấu chấm đầu dòng lệnh thứ 2:-=
 
Upvote 0
Đúng rồi nhỉ. Vì có lúc tôi khai báo như thế vẫn OK với With Sh Tmp mà không cần .Range
.[A2:J1000] có <> Range(.Cells(2, 1), .Cells(1000, 10))
Chắc là có trùng hợp nào nên vẫn OK hay lúc ấy tôi đang ở Sh Tmp
Để tôi kiểm lại các code.
Xin cám ơn rất nhiều, thiếu sót quá.

Xin hỏi bổ sung:
Trước kia tôi dùng .[A2:J1000], sau học của Thầy Phạm Duy Long chuyển qua cells(row,col)
Vậy các bạn hãy chỉ ra sự khác nhau giữa.
PHP:
With Sheet("Tmp")
 .Range(Cells(2,1),Cells(1000,10)).ClearContents
end With

PHP:
With Sheet("Tmp")
  .Range(.Cells(2,1),.Cells(1000,10)).ClearContents
 end With
Lưu ý những dấu "." trước Cells và range.
 
Upvote 0
.....Thì OK nhưng khi chuyển thành
PHP:
With Sheets("Tmp") 'Phan nay khong chiu No bao run time error 1004
    Range(.Cells(2, 1), .Cells(1000, 10)).ClearContents
    .Cells(1, 15) = "MaCT"
    .Cells(2, 15) = "'=" & "III"
End With
Thì báo 1004, mà
.[A2:J1000] có <> Range(.Cells(2, 1), .Cells(1000, 10))
Xin cám ơn. Do tôi học VBA không bài bản.


Dòng lệnh này : Range(.Cells(2, 1), .Cells(1000, 10)).ClearContents
ThuNghi chuyển thành : Range(Cells(2, 1), Cells(1000, 10)).ClearContents
Bỏ dấu chấm trước Cells sẽ OK NumberOne ngay thôi. Lý do : Hồi sau sẽ rõ
Thân
 
Upvote 0
Upvote 0
Lại nữa, hay nhỉ, bạn phải nghĩ rằng viết code có lúc như thư giãn mà đưa 1 trời link bảo hãy đọc. May rằng bạn không bảo tôi hãy mua sách lập trình về nghiên cứu.
Dù sao cũng cám ơn!
Thú thật nhiều lúc tôi trả lời bài, làm lại còn nhanh hơn lục lọi tìm kiếm.
 
Upvote 0
Trong trường hợp này bác phải có dấu chấm mới chính xác, bác chú ý câu lệnh With bên trên, khi bác có dấu chấm thì nó sẽ hiểu là Range và Cells của Sheet Tmp, khi bác không có dấu chấm thì nó hiểu là của ActiveSheet, vậy làm đúng thì phải có dấu chấm, không có dấu chấm như bạn anhphuong thì sẽ không cho kết quả đúng như mong đợi đâu ạ. Còn tại sao khi bỏ dấu chấm trước Range đi nó báo lỗi, là vì khi bác định nghĩa 1 Range bằng cách tham chiếu tới Cells thì khi đó bác phải tham chiếu tới Cells trên chính Sheet của Range mà bác định nghĩa, ở đây khi thiếu dấu chấm trước Range thì Range này là của ActiveSheet, còn .Cells thì nó là Cells của Sheet Tmp nên nó báo lỗi.
 
Upvote 0
Trong trường hợp này bác phải có dấu chấm mới chính xác, bác chú ý câu lệnh With bên trên, khi bác có dấu chấm thì nó sẽ hiểu là Range và Cells của Sheet Tmp, khi bác không có dấu chấm thì nó hiểu là của ActiveSheet, vậy làm đúng thì phải có dấu chấm, không có dấu chấm như bạn anhphuong thì sẽ không cho kết quả đúng như mong đợi đâu ạ. Còn tại sao khi bỏ dấu chấm trước Range đi nó báo lỗi, là vì khi bác định nghĩa 1 Range bằng cách tham chiếu tới Cells thì khi đó bác phải tham chiếu tới Cells trên chính Sheet của Range mà bác định nghĩa, ở đây khi thiếu dấu chấm trước Range thì Range này là của ActiveSheet, còn .Cells thì nó là Cells của Sheet Tmp nên nó báo lỗi.
Rất cám ơn! Với người chưa có căn bản về lập trình như tôi thì tôi rất tâm đắc với những câu trả lời bình dị, chính xác và cụ thể như trên.
Một lần nữa xin cám ơn!
 
Upvote 0
Web KT

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

Back
Top Bottom