Đố vui về VBA!

Liên hệ QC

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,905
Nhằm cũng cố kiến thức về VBA cho các bạn mới bắt đầu và cả những bạn đang ứng dụng mà chưa hiểu nhiều về nó, tôi mở topic này với mong mõi qua những câu hỏi vui, các bạn sẽ nhận định lại sự hiểu biết cũa mình... (Kễ cã chính tôi cũng đang tập tành nên có rất nhiều cái chưa biết)
Mong rằng topic sẽ mang đến cho các bạn những khám phá thú vị với những cái tưỡng chừng như đã biết
Mong nhận dc bài viết về câu đố cũa các cao thủ! Còn các bạn mới thì đừng ngại khi đưa ra ý kiến cũa mình.. Có sai có sữa sẽ hoàn thiện!
Tôi xin mỡ màn trước bằng 1 câu hỏi đơn giãn
ANH TUẤN

CÂU HỎI 1: Tại sao biến K ko hoạt động?
Tôi muốn khi nhấn vào 1 button thì cell A1 sẽ tăng lên 1 đơn vị... Tôi đã làm như sau:
-Tạo 1 Command Button (nút nhấn thuộc thanh Control Toolbox), click phải chuột lên nút nhấn, chọn View code, rồi gõ vào đoạn code sau:
PHP:
Private Sub CommandButton1_Click()
   K = K + 1
   Range("A1").Value = K
End Sub
Ban đầu K chưa có gì, xem như =0, nhấn nút lần thứ nhất thì K dc tăng thêm 1, vậy K hiện tại sẽ bằng 1, và gán K vào cell A1 thì đương nhiên A1 sẽ =1... Nhấn nút lần 2, K lại dc tăng thêm 1 nên hiện tại K sẽ =2 và cell A1 cũng sẽ =2... vân vân.. từ đó diễn tiến tiếp...
Hi.. hi.. Điều này nghe qua có vẽ rất hợp lý, ấy thế mà khi nhấn nút nó chỉ hoạt động dc duy nhất 1 lần (A1 = 1) rồi thôi ko nhút nhít nữa...
Các bạn có thể giãi thích tại sao lại như thế ko? Tại sao những lần nhấn nút sau đó K lại ko tăng thêm tí nào (vì thực tế A1 vẫn cứ = 1 hoài) ?
ANH TUẤN
 
Có một câu hỏi nhỏ dành cho các bạn mới bắt đầu với VBA thế này:
Các bạn hãy mở một workbook mới, chèn code dưới đây vào Thisworkbook
Mã:
Private Sub Workbook_SheetActivate(ByVal [COLOR=#FF0000][B]Sh[/B][/COLOR] As [B][COLOR=#FF0000]Object[/COLOR][/B])
  MsgBox "Tên sheet là: '" & Sh.Name & "'"
End Sub
Đây là sự kiện SheetActivate, mỗi khi chọn vào một sheet nào đó thì sự kiện sẽ được kích hoạt. Cụ thể, với code trên thì mỗi khi chọn sheet sẽ xuất hiện một thông báo
Code rất bình thường. Vấn đề là không biết các bạn có từng thắc mắc tại sao biến Sh lại được khai báo dạng Object mà không phải là Worksheet. Tức tại sao lại không là:
Mã:
Private Sub Workbook_SheetActivate(ByVal Sh As [COLOR=#FF0000][B]Worksheet[/B][/COLOR])
Các bạn thử suy nghĩ xem!

ồ chào ngài "Anhtuan1066" , lâu quá không thấy anh viết bài mới . hi hi
em đoán vì Object to hơn Worksheet , chắc là để chứa nhiều thứ khác ngoài Worksheet , hi hi
 
Upvote 0
ồ chào ngài "Anhtuan1066" , lâu quá không thấy anh viết bài mới . hi hi
em đoán vì Object to hơn Worksheet , chắc là để chứa nhiều thứ khác ngoài Worksheet , hi hi

Có thấy người ta ghi cái này không:
Có một câu hỏi nhỏ dành cho các bạn mới bắt đầu với VBA thế này:
Anh Chim Hồng thì chắc người ta phải mời.. đi chơi chỗ khác
Ẹc...Ẹc...
 
Upvote 0
Có một câu hỏi nhỏ dành cho các bạn mới bắt đầu với VBA thế này:
Các bạn hãy mở một workbook mới, chèn code dưới đây vào Thisworkbook
Mã:
Private Sub Workbook_SheetActivate(ByVal [COLOR=#FF0000][B]Sh[/B][/COLOR] As [B][COLOR=#FF0000]Object[/COLOR][/B])
  MsgBox "Tên sheet là: '" & Sh.Name & "'"
End Sub
Đây là sự kiện SheetActivate, mỗi khi chọn vào một sheet nào đó thì sự kiện sẽ được kích hoạt. Cụ thể, với code trên thì mỗi khi chọn sheet sẽ xuất hiện một thông báo
Code rất bình thường. Vấn đề là không biết các bạn có từng thắc mắc tại sao biến Sh lại được khai báo dạng Object mà không phải là Worksheet. Tức tại sao lại không là:
Mã:
Private Sub Workbook_SheetActivate(ByVal Sh As [COLOR=#FF0000][B]Worksheet[/B][/COLOR])
Các bạn thử suy nghĩ xem!

Là tại vì "Trời Sinh nó thế"...
Chọn sự kiện thì anh Bill anh tự gán vào là (ByVal Sh As Object) --=0--=0--=0
 
Upvote 0
Nhờ bác google một tẹo:
Gõ từ khóa: "Workbook_SheetActivate" enter một cái. Chọn link đầu tiên đọc...
"The activated sheet. Can be a Chart or Worksheet object."
 
Upvote 0
ồ chào ngài "Anhtuan1066" , lâu quá không thấy anh viết bài mới . hi hi
em đoán vì Object to hơn Worksheet , chắc là để chứa nhiều thứ khác ngoài Worksheet , hi hi

Bạn Lặn và Trồi dùng từ "to" là chưa đúng lắm. Nói là "bao quát" mới đúng.
"vật dụng trong nhà" bao quát hơn "cái bàn", có thể dùng để chỉ bàn hay ghế, giường tủ đều được.
 
Upvote 0
Worksheet chỉ là 1 loại Sheet trong workbook.Sheets nên không thể đại diện cho 1 sheet bất kỳ Activate được. Khi giải đáp úp mở e không "an toàn".
 
Upvote 0
Worksheet chỉ là 1 loại Sheet trong workbook.Sheets nên không thể đại diện cho 1 sheet bất kỳ Activate được. Khi giải đáp úp mở e không "an toàn".

Vậy thì sẵn đây bạn mở luôn khỏi úp, giải thích luôn cho bà con biết các phần tử của collection sheets có thể là những loại sheet nào. Và tại sao chỉ Object mới bao được hết. Tại sao VBA không có một loại sheet bao quát?
 
Upvote 0
Vậy thì sẵn đây bạn mở luôn khỏi úp, giải thích luôn cho bà con biết các phần tử của collection sheets có thể là những loại sheet nào. Và tại sao chỉ Object mới bao được hết. Tại sao VBA không có một loại sheet bao quát?

Để biết có những loại Sheet nào có thể, nhấn chuột phải vào SheetTab---Chọn lệnh Insert: Excel hiện ra 1 cửa sổ các loại Sheet mà ta có thể Insert vào là:

-Worksheet: Là bảng tính ta vẫn làm quen thuộc.

-Chart: Sheet để thiết lập đồ thị.

-MS Excel 4.0 Macro.

-MS Excel 5.0 Dialog.
 
Lần chỉnh sửa cuối:
Upvote 0
Có thể giải thích thêm chút nữa:
1. thuộc tính Sheets của Workbook
2. tại sao VBA không có một loại kiểu riêng cho sheets. vd private sub Workbook_SheetActivate(ByVal sh as SheetType)
 
Upvote 0
Có thể giải thích thêm chút nữa:
1. thuộc tính Sheets của Workbook
2. tại sao VBA không có một loại kiểu riêng cho sheets. vd private sub Workbook_SheetActivate(ByVal sh as SheetType)

Như đã từng thổ lộ, em đến với VBA không bằng đường "Hàng Không" mà theo các lối mòn do có những người từng đi tạo ra. Vậy nên cách trả lời của em không mang hơi hướng sách vở mà có tính thực tế nhiều.


Câu 1, đây là con đường để ai cũng có thể tìm đầy đủ thuộc tính cũng như phương thức của 1 đối tượng theo 2 cách rất du kích nhưng khá đầy đủ (Tất nhiên nếu được học tập hay nghiên cứu tài liệu chuẩn thì quá tốt rồi):

A-Cách thứ nhất:
1/Trong Option của VBA Editor nhớ đánh dấu kiểm vào Option: Auto List Member trên thẻ Edit.
2/Khai tạm 1 Code: ví dụ Sub Test()...............End Sub
3/Ta khai báo đối tượng Worksheet: Ví dụ Dim Sh as Worksheet.
Vậy giờ ta gõ Sh và dấu chấm VBA sẽ liệt kê đầy đủ các thuộc tính cũng như phương thức của Worksheet. Khi chọn 1 thuộc tính nào đó Tools Tip sẽ có hướng dẫn cú pháp cũng như yêu cầu của nó.

B-Cách thứ hai:
Trong cửa sổ Editor VBA code ta nhấn chọn nút Object Browser (Hình hộp carton mở tung ra ba chấm màu) sẽ mở ra Dialog: Object Browser
Em nói qua cách sử dụng nó
-Đây là từ điển tra cứu tất cả các đối tượng, nếu biết đối tượng thuộc thư viện nào thì chọn thư viện trong Combo đầu tiên, nếu không biết chọn All hay để trống.
-Gõ tên đối tượng cần tìm vào Textbox 2 (Để trống thì tìm tất nhưng hơi hoa mắt)
-Cửa sổ bên trái hiện toàn bộ các đối tượng cần tìm. Chọn đối tượng bất kỳ, dưới chân sẽ có dòng trích yếu lý lịch của đối tượng và cửa sổ bên phải liệt kê các thuộc tính và phương thức của đối tượng. Cần tra cứu thuộc tính nào ta chọn dòng thuộc tính đó dưới chân cửa sổ cũng có kê rõ nguồn gốc yêu cầu và cú pháp.
Cần chi tiết hơn thì tại đối tượng hay thuộc tính đang chọn nhấn nút có dấu ? sẽ mở ra trang Help khá cụ thể
Muốn tham khảo thêm chép thuộc tính đó vào Google xem thiên hạ họ làm. Ngoài ra còn có 1 số chức năng nữa tùy yêu cầu nghiên cứu thêm.
Từ đây tự tìm hiểu thuộc tính Sheets có lẽ đầy đủ hơn giải thích.


Câu 2:

Private Sub Workbook_SheetActivate(ByVal Sh As Worksheet)

Đây là Proceduce của sự kiện chọn 1 sheet bất kỳ của Workbook. Hơn nữa, tham số Sh là biến đại diện cho chính Sheet được chọn mở. Như ta đã biết có nhiều loại Sheet trong Workbook có thể chọn mở nên VBA quy định bắt buộc tham số Sh phải khai báo dạng Object, nếu khai báo khác đi VBA không thừa nhận sự kiện và phát sinh lỗi
 
Lần chỉnh sửa cuối:
Upvote 0
Bổ thêm:

Workbook có 3 thuộc tính collection liên quan đến sheet.
1. Worksheets: gồm tất cả các worksheets trong workbook
2. Charts: gồm tất cả các charts trong workbook. Lưu ý, đây chỉ là các charts loại chiếm hữu sheet riêng biệt. Các charts nằm bên trong worksheet không được tính.
3. Sheets: gồm tất cả các loại được liệt vào hàng "sheets", tức là cả gồm cả 2 cái collections kể trên, và thêm các loại sheet cổ điển nữa.

SheetActivate là loại hàm bắt sự kiện hàng sheets. Để biết được đối tượng của sự kiện, các hàm bắt sự kiện thường thảy đối tượng này vào làm tham số.

Theo nguyên tắc LT HĐT, code có thể gói (tiếng chuyên môn là box) đối tượng vào bậc (class) thô hơn để bao quát hoá kiểu dữ liệu, đến khi cần làm việc thẳng với đối tượng thì code lại mở gói (unbox). Hai đối tượng khác kiểu có thể mò về kiểu thô mà chúng chia sẻ gần nhất để gói/box (hãy tưởng tượng như ước số chung lớn nhất của 2 số nguyên). Hiện tượng này ta sẽ thường gặp trong collection, array, và tham số của hàm.

Tuy Worksheet và Chart có cùng đẳng cấp (sheets) nhưng trên thực tế chúng chả có gì giống nhau cả. Nếu phải dùng 1 class riêng để gói thì chả hữu lý chút nào. Vì vậy, hàm Workbook_SheetActivate gói thẳng chúng vào kiểu thô nhất là Object (nếu bạn đang tưởng tượng ước số chung thì đây là trường hợp số 14 và số 15, chúng đều có ước số nhưng không có ước số chung, cuối cùng quy về số 1)

@sealand: sỡ dĩ tôi đòi hỏi bạn giải thích thêm là vì tôi thấy đây là cơ hội tốt để các bạn mới tập code làm quen với khái niệm Đa Hình trong LT Hướng Đối Tượng.
 
Lần chỉnh sửa cuối:
Upvote 0
Với 1 UserForm duy nhất, ta có thể mở nhiều lần lên được không? Bằng cách nào?

(xem ảnh minh họa). +-+-+-+--=0
 

File đính kèm

  • OpenForm.jpg
    OpenForm.jpg
    49.5 KB · Đọc: 63
Upvote 0
Với 1 UserForm duy nhất, ta có thể mở nhiều lần lên được không? Bằng cách nào?

(xem ảnh minh họa). +-+-+-+--=0

các bạn không nên quá chú ý tới câu hỏi , mà hãy để ý cách anh í ghi câu cuối : xem ảnh minh họa , rồi cười .
xem ảnh xong các bạn sẽ nhận ra anh í có chìa khóa vạn năng để mở được VBA project nè , mở khóa Workbook được nè , ghê chưa ? :vampire: chứ câu hỏi thì trả lời ngắn gọn
Mã:
Public Sub hello()
Dim f1 As UserForm1, r As Byte
For r = 1 To 5 Step 1
    Set f1 = New UserForm1
    f1.Show 0
Next
End Sub
 
Upvote 0
các bạn không nên quá chú ý tới câu hỏi , mà hãy để ý cách anh í ghi câu cuối : xem ảnh minh họa , rồi cười .
xem ảnh xong các bạn sẽ nhận ra anh í có chìa khóa vạn năng để mở được VBA project nè , mở khóa Workbook được nè , ghê chưa ? :vampire: chứ câu hỏi thì trả lời ngắn gọn
Mã:
Public Sub hello()
Dim f1 As UserForm1, r As Byte
For r = 1 To 5 Step 1
    Set f1 = New UserForm1
    f1.Show 0
Next
End Sub

OK, cái tên này trả lời đúng rồi, nhưng mắc mớ gì phải STEP 1 chi không biết! Và có một chút phá bỉnh không hề nhẹ!

Vậy đố tiếp, bằng lệnh gì để tất cả các form show lên đó được Unload?
 
Upvote 0
OK, cái tên này trả lời đúng rồi, nhưng mắc mớ gì phải STEP 1 chi không biết! Và có một chút phá bỉnh không hề nhẹ!

Vậy đố tiếp, bằng lệnh gì để tất cả các form show lên đó được Unload?
Không biết như sau được không:

Mã:
Sub Dong()
    Dim frm As UserForm
    For Each frm In UserForms
        Unload frm
    Next
End Sub
 
Upvote 0
Không biết như sau được không:

Mã:
Sub Dong()
    Dim frm As UserForm
    For Each frm In UserForms
        Unload frm
    Next
End Sub
Cũng hay đấy chứ! Nhưng có thể có giải pháp khác không có vòng lặp được chăng?

Ứng dụng cho việc show một Form cho nhiều lần một lúc cũng hay hay, chẳng hạn như trong hình dưới đây, ta không cần thiết phải làm nhiều form cho một file!

attachment.php


attachment.php
 

File đính kèm

  • UngDung1.jpg
    UngDung1.jpg
    16.7 KB · Đọc: 51
  • UngDung2.jpg
    UngDung2.jpg
    92.8 KB · Đọc: 54
Upvote 0
Cũng hay đấy chứ! Nhưng có thể có giải pháp khác không có vòng lặp được chăng?

Ứng dụng cho việc show một Form cho nhiều lần một lúc cũng hay hay, chẳng hạn như trong hình dưới đây, ta không cần thiết phải làm nhiều form cho một file!

đố được 1 câu mà nhiều người không biết là anh ghê rồi , bữa nay doveandrose đành chịu bị lêu lêu chờ đáp án của ních xanh rồi . hu hu :.,:.,
 
Upvote 0
Web KT
Back
Top Bottom