Đố 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,911
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
 
Tôi không hiểu lắm. Tùy việc mà dùng thôi. Giết gà thì dùng dao mổ gà, giết trâu thì dùng dao mổ trâu.
Nếu cần mở tập tin đã biết đường dẫn (vd. được chọn trong ComboBox, có được sau khi đã tìm kiếm ở lần chạy code trước và được nhớ ở biến sPath chẳng hạn v...v) thì chạy code trong bài #711 chứ ai lại dùng code #716 để bắt người dùng nhọc công chọn cái tập tin mà đường dẫn đã được xác định? Còn nếu chưa xác định và cần phải chọn thì chạy code #716. Tùy việc mà chọn công cụ chứ nói cái này ưu điểm vì thay được cái kia thì không đúng.

Ý em muốn nói mở file với đường dẫn (tên file) chưa biết. Em hay dùng cách này:

Mã:
Sub OpenFile1()    
  With Application.FileDialog(msoFileDialogOpen)
        .InitialFileName = "D:\"
        .AllowMultiSelect = False
        .Filters.Clear
        .Filters.Add "File cua tui", "*.*"
        .Show
        If .SelectedItems.Count Then
            oFile = .SelectedItems(1)
            Set Wb = Workbooks.Open(oFile)
        End If
    End With
End Sub

Với code này em vừa phải dùng Application.FileDialog(msoFileDialogOpen) và vừa phải có Set Wb = Workbooks.Open(oFile).
Nên tính ra cách của ndu giới thiệu rất gọn, nếu nhu cầu chỉ mở file Excel (thử mở loại file khác thấy bị lỗi)
Chỉ có điều cách mới này ta không cố định được thư mục.

Khi hỏi bác Google về Application.FindFile thì thấy cũng ít sử dụng nên mới nghi nghờ vậy thôi.
 
Upvote 0
Nhớ một câu chuyện vui về các giai thoại của Anhxtanh (Albert Einstein), ông có nuôi 2 con chó, 1 con chó lớn và 1 con chó nhỏ. Ông làm cái nhà cho 2 con chó ở chung, sau khi làm cái cửa lớn cho con chó lớn xong, ông lại nghĩ cần có thêm 1 cái cửa nhỏ nữa để cho con chó nhỏ, thế là ông lại cưa thêm một cái lỗ nhỏ nữa! (lời bàn: chỉ cần một cửa lớn là 2 con chó cùng ra vào được!)

Cũng chả biết có phải huyền thoại về Albert Einstein hay không. Cũng có chuyện kể là: Có nhà bác học nọ có nuôi 1 con chó và 1 con mèo ... Và không phải cửa mà là 2 lỗ trên tường (cửa thì là cái đóng vào, mở ra)
Nhưng nghĩ ra cũng có thể ông bác học nọ không lú lẫn. Vì nếu 2 con vật cùng chạy do lý do gì đó thì 2 ô là hợp lý. Rồi nữa, nếu con chó qua 1 nửa mình rồi cứ đứng trêu ngươi con mèo thì sao? He he
 
Upvote 0
Cũng chả biết có phải huyền thoại về Albert Einstein hay không. Cũng có chuyện kể là: Có nhà bác học nọ có nuôi 1 con chó và 1 con mèo ... Và không phải cửa mà là 2 lỗ trên tường (cửa thì là cái đóng vào, mở ra)
Nhưng nghĩ ra cũng có thể ông bác học nọ không lú lẫn. Vì nếu 2 con vật cùng chạy do lý do gì đó thì 2 ô là hợp lý. Rồi nữa, nếu con chó qua 1 nửa mình rồi cứ đứng trêu ngươi con mèo thì sao? He he

Câu chuyện hay! Thử áp dụng cho một gia đình có nhiều người con, ông ta "mỗ" cho mỗi người 1 cửa trên tường! kakaka
 
Upvote 0
Chắc anh nói cái này. Làm theo gợi ý của anh.
PHP:
Sub Kiemtra_File_Da_Mo()
Dim kiemtra
kiemtra = Application.FindFile
If kiemtra Then MsgBox "OK"
End Sub

Chính xác là cái này nhưng phải On error resume next như anh siwtom đã nói
Mã:
Sub Test()
  Dim bChk As [COLOR=#ff0000]Boolean[/COLOR]
  [COLOR=#ff0000]On Error Resume Next[/COLOR]
  bChk = Application.FindFile
  If bChk Then
    MsgBox "File da mo thanh cong"
  Else
    MsgBox "That bai"
  End If
End Sub
Ta biết rằng phương thức Application.FindFile trả về kiểu biến Boolean chứ không "chỉ" đến 1 Workbook cụ thể nào cả. Nhưng điều chắc chắn rằng sau khi dùng FindFile để mở 1 file Excel, nếu file mở thành công thì Wb vừa mở sẽ được Active. Vậy nếu muốn chỉ đến Wb vừa mở, ta chỉ cần thêm câu lệnh Set wkb = ActiveWorkbook là được rồi
(Rảnh rỗi mình hay bấm F2 rồi "mò" trong cái đống hỗn độn, cứ thấy cái nào lạ lạ thì nghiên cứu chơi...)
 
Upvote 0
Xây dựng sự kiện Worksheet_Change

- Tôi có dữ liệu tại Sheet1, Range("A1:A10")
- Tôi muốn xây dựng sự kiện Worksheet_Change cho vùng này (chỉ cần có tác dụng khi nhập liệu bằng tay, không cần có tác dụng đối với trường hợp copy/paste hoặc kéo fill)
- Xin hỏi: Ngoài cách dùng sự kiện Worksheet_Change, ta có thể thiết kế 1 code dạng khác hay không? (có tác dụng như sự kiện Change)
Nói thêm rằng:
- Code này nằm trong 1 Module
- Không dùng Class
- Không dùng Validation để hổ trợ
------------------
Các bạn hãy suy nghĩ xem code ấy sẽ được viết thế nào? (Chẳng hạn tôi muốn khi nhập liệu vùng A1:A10, chỉ cho phép nhập number)
Tóm lại là: Một code gì đó NẰM TRONG 1 MODULE và có tác dụng như sự kiện Worksheet_Change
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
- Tôi có dữ liệu tại Sheet1, Range("A1:A10")
- Tôi muốn xây dựng sự kiện Worksheet_Change cho vùng này (chỉ cần có tác dụng khi nhập liệu bằng tay, không cần có tác dụng đối với trường hợp copy/paste hoặc kéo fill)
- Xin hỏi: Ngoài cách dùng sự kiện Worksheet_Change, ta có thể thiết kế 1 code dạng khác hay không? (có tác dụng như sự kiện Change)
Nói thêm rằng:
- Code này nằm trong 1 Module
- Không dùng Class
- Không dùng Validation để hổ trợ
------------------
Các bạn hãy suy nghĩ xem code ấy sẽ được viết thế nào? (Chẳng hạn tôi muốn khi nhập liệu vùng A1:A10, chỉ cho phép nhập number)
Tóm lại là: Một code gì đó NẰM TRONG 1 MODULE và có tác dụng như sự kiện Worksheet_Change
Ẹc... Ẹc...

Code đây code đây:
Mã:
Sub auto_open()
    ThisWorkbook.Worksheets("Sheet1").OnEntry = "MySub"
End Sub
Sub MySub()
    If Not Application.Intersect(ActiveCell, Range("A1:A10")) Is Nothing Then
        If TypeName(ActiveCell.Value) <> "Double" Then MsgBox "Nhap sai roi, hic!"
    End If
End Sub
 
Upvote 0
Code đây code đây:
Mã:
Sub auto_open()
    ThisWorkbook.Worksheets("Sheet1").OnEntry = "MySub"
End Sub
Sub MySub()
    If Not Application.Intersect(ActiveCell, Range("A1:A10")) Is Nothing Then
        If TypeName(ActiveCell.Value) <> "Double" Then MsgBox "Nhap sai roi, hic!"
    End If
End Sub

Chính xác là cái thằng OnEntry này
Nếu tìm trong Help, bảo đảm lòi con mắt cũng không có
OnEntry thật ra đã có người đăng lên diễn đàn mình từ lâu lắm rồi (có điều chẳng thấy ai để ý nên mới.. ĐỐ)
Ngoài OnEntry ra hình như còn có OnData (tác dụng gần tương tự)
 
Upvote 0
Chính xác là cái thằng OnEntry này
Nếu tìm trong Help, bảo đảm lòi con mắt cũng không có
OnEntry thật ra đã có người đăng lên diễn đàn mình từ lâu lắm rồi (có điều chẳng thấy ai để ý nên mới.. ĐỐ)
Ngoài OnEntry ra hình như còn có OnData (tác dụng gần tương tự)

Nhờ câu đố của ndu mình mới biết điều này, ngoài ra còn biết còn có thằng .OnDoubleClick cũng hay lắm.
 
Upvote 0
Xin mạo muội đố mọi người với file đính kèm ta phải viết code thế nào để có 1 đoạn code ngắn nhất mà có thể lọc được những người có trùng tên ra. Không dùng vòng lặp
 

File đính kèm

  • LOC_TEN.xlsx
    8.4 KB · Đọc: 26
Upvote 0
Xin mạo muội đố mọi người với file đính kèm ta phải viết code thế nào để có 1 đoạn code ngắn nhất mà có thể lọc được những người có trùng tên ra. Không dùng vòng lặp

Lọc trùng tên nghĩa là sao đây?
Tôi hiểu ý Hải chỉ muốn xét TÊN, không xét HỌ và CHỮ LÓT
Tuy nhiên tôi chưa hiểu chổ này: Lọc duy nhất (2 tên trở lên chỉ lấy 1) hay chỉ lọc những người bị trùng tên ra? (không trùng thì không lọc)
 
Upvote 0
Lọc trùng tên nghĩa là sao đây?
Tôi hiểu ý Hải chỉ muốn xét TÊN, không xét HỌ và CHỮ LÓT
Tuy nhiên tôi chưa hiểu chổ này: Lọc duy nhất (2 tên trở lên chỉ lấy 1) hay chỉ lọc những người bị trùng tên ra? (không trùng thì không lọc)
Nhìn vào file thì em hiểu thế này: Nhập tên vào ô A1, những người có tên giống tên vừa nhập sẽ được lọc ra cột C.
 
Upvote 0
Lọc trùng tên nghĩa là sao đây?
Tôi hiểu ý Hải chỉ muốn xét TÊN, không xét HỌ và CHỮ LÓT
Tuy nhiên tôi chưa hiểu chổ này: Lọc duy nhất (2 tên trở lên chỉ lấy 1) hay chỉ lọc những người bị trùng tên ra? (không trùng thì không lọc)
Anh nói đúng rồi. Chỉ lấy tên, không dính tới họ hoặc lót. Tất cả có tên giống nhau lấy hết.

Nhìn vào file thì em hiểu thế này: Nhập tên vào ô A1, những người có tên giống tên vừa nhập sẽ được lọc ra cột C.
Vâng, nhập tên vào A1 1 cái tên, dữ liệu được lọc ra tại cột C như file kèm
Sub này mình nghĩ cần 3 dòng lệnh (không tính sự kiện change)
 
Lần chỉnh sửa cuối:
Upvote 0
Anh nói đúng rồi. Chỉ lấy tên, không dính tới họ hoặc lót. Tất cả có tên giống nhau lấy hết.


Vâng, nhập tên vào A1 1 cái tên, dữ liệu được lọc ra tại cột C như file kèm
Sub này mình nghĩ cần 3 dòng lệnh (không tính sự kiện change)
Đoán chắc anh dùng AdvancedFilter, vì khi click vào đó còn "dấu vết" để lại.
 
Upvote 0
Đoán chắc anh dùng AdvancedFilter, vì khi click vào đó còn "dấu vết" để lại.

Em đoán là vậy :
[GPECODE=vb]
Sub LOC()
[IV2] = [A3]: [IV3] = "*" & [A1]
[A3:A1000].AdvancedFilter 2, [IV2:IV3], [C3]
End Sub
[/GPECODE]

Nhưng với code này tên Quý sẽ lọc được 2 tên là " Châu Văn Quý " và " Hồ Quý A"
Không biết ý anh Hải còn cần lọc lấy 1 tên, hay 2 tên như trên là được rồi !

Nếu để lọc lấy Hồ Quý A thì em sửa criteria như sau : "*" & [A1] & "?"
 
Lần chỉnh sửa cuối:
Upvote 0
Thế thì Advanced Filter thôi, có gì đâu chứ

Em đoán chắc anh Hải định nhấn mạnh cách viết : *[A1] , để lấy tên, nhưng theo em cách này thì chưa lấy chính xác được những người có tên trong [A1],<--- Theo em muốn lấy chính xác thì vùng tiêu chuẩn phải là 1 công thức ( true, false ) hay là cái gì gì đó ....
 
Upvote 0
Em đoán chắc anh Hải định nhấn mạnh cách viết : *[A1] , để lấy tên, nhưng theo em cách này thì chưa lấy chính xác được những người có tên trong [A1],<--- Theo em muốn lấy chính xác thì vùng tiêu chuẩn phải là 1 công thức ( true, false ) hay là cái gì gì đó ....

Ý bạn là sao đây?
Có phải ý muốn nói rằng: Nếu lọc những người có TÊN = "NGOC" thì rất có thể lọc nhầm sang những người có CHỮ LÓT = "NGOC", đúng không?
Mấy trò này đã từng có người hỏi đầy trên diễn đàn rồi
Nói chung công thức điều kiện sẽ theo kiểu ="=*"&A1
Ăn tiền là cái dấu = màu đỏ ấy
 
Upvote 0
Em đoán chắc anh Hải định nhấn mạnh cách viết : *[A1] , để lấy tên, nhưng theo em cách này thì chưa lấy chính xác được những người có tên trong [A1],<--- Theo em muốn lấy chính xác thì vùng tiêu chuẩn phải là 1 công thức ( true, false ) hay là cái gì gì đó ....
Muốn chính xác thì vùng điều kiện bạn làm vầy nè:
Mã:
 ="=* "&A1
Anh ndu thiếu một dấu " "
 
Upvote 0
Web KT

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

Back
Top Bottom