Đố 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,906
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
 
Lâu quá không ghé thăm topic này. Hôm này mời các bạn xuất chiêu viết code cho tình huống như sau:
- Thông thường trong code, code nào viết trước sẽ dc thực hiện trước, code nào viết sau sẽ dc thực sau
Vậy nếu người ta yêu cầu:
- Thiết kế 1 bảng tính với 3 MsgBox
- Trong code, MsgBox thứ nhất nằm sau MsgBox thứ 2 và 3 (tức là viết code cho MsgBox thứ 2 và 3 trước... cả 3 MsgBox nằm chung 1 Sub)
Yêu cầu: Làm sao để khi chạy code thì MsgBox thứ nhất xuất hiện trước (rồi mới đến 2 MsgBox còn lại)
(Code càng ngắn càng tốt)
Tôi xin ví dụ code thế này:
PHP:
Sub MsgBox_Test()
  Dim Res As Long
  Res = MsgBox("Xin chon YES hoac NO", 4)
  If Res = 6 Then
    MsgBox "Ban da chon 'YES'"
  Else
    MsgBox "Ban da chon 'NO'"
  End If
End Sub
Bây giờ các bạn làm thế nào đưa MsgBox thứ nhất ra nằm sau 2 MsgBox còn lại (nhưng khi chạy code thì vẫn giống như ý đồ của code ví dụ trên)
 
Upvote 0
Chắc phải kèm theo điều kiện không dùng GoTo chứ, nếu dùng GoTo thì quá dễ.
 
Upvote 0
Từ đó đến giờ em chỉ thấy code dạng này là chạy ngược thôi!
PHP:
Sub chay()
Application.InputBox("chon vung:", Type:=8).AdvancedFilter _
Action:=xlFilterCopy, CopyToRange:=Application.InputBox("chon o:", Type:=8), Unique:=True
End Sub
Không biết có đúng ý sư huynh không?
Thân.
 
Upvote 0
Từ đó đến giờ em chỉ thấy code dạng này là chạy ngược thôi!
PHP:
Sub chay()
Application.InputBox("chon vung:", Type:=8).AdvancedFilter _
Action:=xlFilterCopy, CopyToRange:=Application.InputBox("chon o:", Type:=8), Unique:=True
End Sub
Không biết có đúng ý sư huynh không?
Thân.
Mình đang hỏi về MsgBox cơ mà!
Chắc phải kèm theo điều kiện không dùng GoTo chứ, nếu dùng GoTo thì quá dễ.
Mình viết bình thường thôi (đương nhiên cũng có tí xảo thuật) chứ ko GOTO gì cả
 
Lần chỉnh sửa cuối:
Upvote 0
Tiểu xảo thì thế này có được không nhỉ? Về bản chất vẫn cứ phải là tuần tự thôi.
Mã:
Sub test()
    Static l As Long
    If l = vbYes Then
        MsgBox "Yes"
    ElseIf l = vbNo Then
        MsgBox "No"
    Else
        l = MsgBox("Chon de", vbYesNo)
        Call test
    End If
End Sub
 
Upvote 0
anh thử code này xem sao:
PHP:
Sub Check()
GoTo myCase
If a = vbYes Then MsgBox "Ban da chon [YES]" Else MsgBox "Ban da chon [NO]"
myCase: a = MsgBox("Xin chon [YES] hoac [NO]", 4)
End Sub
 
Upvote 0
Tiểu xảo thì thế này có được không nhỉ? Về bản chất vẫn cứ phải là tuần tự thôi.
Mã:
Sub test()
    Static l As Long
    If l = vbYes Then
        MsgBox "Yes"
    ElseIf l = vbNo Then
        MsgBox "No"
    Else
        l = MsgBox("Chon de", vbYesNo)
        Call test
    End If
End Sub
Hehe! Code của anh chạy được có 1 lần à, chạy lại nó ra vui lắm!
 
Upvote 0
Upvote 0
Hehe! Code của anh chạy được có 1 lần à, chạy lại nó ra vui lắm!
Muốn chạy nhiều lần thì dễ thôi mà. Liệu có phải chăng bác anhtuan1066 muốn nói tới là cái Static này chăng. Sửa lại thêm 2 dòng màu đỏ dưới này là OK thôi.
Mã:
Sub test()
    Static l As Long
    If l = vbYes Then
        MsgBox "Yes"
        [COLOR=Red]l = 0[/COLOR]
    ElseIf l = vbNo Then
        MsgBox "No"
        [COLOR=Red]l = 0[/COLOR]
    Else
        l = MsgBox("Chon de", vbYesNo)
        Call test
    End If
End Sub
Code của Ca_Di dùng tới GoTo mất rồi ...
To ptm: Không thêm trước End Sub được bác ạ.
 
Upvote 0
To ptm: Không thêm trước End Sub được bác ạ.
Đựơc mà, mình test rồi. Về cơ bản thì Msg1 hoặc MSg2 hiện ra, nhấn OK đóng lại là thoát luôn ra ngoài If mà. Vậy câu lệnh đó đặt trong hay ngoài If cũng như nhau.
 
Upvote 0
Giãi pháp của tôi là:
PHP:
Sub MsgBox_Test()
 MsgBox "Ban da chon " & Choose(1 - (MsgBox("Ban chon 'Yes' hay 'No'?", 4) = 6), "'No'", "'Yes'")
End Sub
Chưa kịp test ---> Các bạn test lại xem!
 
Upvote 0
chào các bạn!
mình là thành viên mới tham gia vào chương trình, mình rất thích tìm hiểu về VBA nhưng mới tìm hiểu nên còn mù tịt. Tham gia vào chương trình thấy nhiều cái mới và khó hiểu quá nên còn đang nghiên cứu các opic để bổ sung kiến thức.
theo mình nghĩ thì code bạn đưa lên thì cho k lặp rồi mới gán giá trị cho cell A1 nên nó không hiểu nên mình nghĩ là gán biến k vào giá trị A1 rồi mới cho biến lặp thì giá trị sẽ tăng
Private Sub CommandButton1_Click()
k = Range("A1").Value
k = k + 1
Range("A1").Value = k
End Sub
mình mới tập tọe thôi nhưng thấy code trên chạy được nên nêu ra ý kiến mong các bạn góp ý nhé.
- về đoạn code 2 theo mình hiểu bạn cho đoạn code vào modul nhằm tạo 1 code chung cho các sheet. khi viết code cho các sheet khác nhau thì chỉ cần goi ra không cần viết lại đoạn code chung đó mất thời gian (giống như ý kiến bạn COSNET.
mình mới tìm hiểu nên còn nhiều cái chưa hiểu biết, rất mong các bạn góp ý nhé.
 
Upvote 0
anh thử code này xem sao:
PHP:
Sub Check()
GoTo myCase
If a = vbYes Then MsgBox "Ban da chon [YES]" Else MsgBox "Ban da chon [NO]"
myCase: a = MsgBox("Xin chon [YES] hoac [NO]", 4)
End Sub
Ko biết Kiệt có nhầm chổ nào ko? Sao code này nó chỉ xuất hiện có 1 cái MsgBox? Còn 2 cái nữa đâu? (có lẽ ngay từ đầu nó đã GOTO rồi)
Hi... hi...
 
Upvote 0
Các bạn chạy thử đoạn code này:
PHP:
Sub Magic()
  Dim i As Long, Ch1 As String, Ch2 As String
  For i = 0 To 5
    Ch1 = Ch1 & Chr(i * (i * (i * (i * (-0.75 * i + 7.2917) - 22.5) + 16.708) + 28.25) + 72)
    Ch2 = Ch2 & Chr(i * (i * (i * (i * (i * (0.425 * i - 6.8667) + 40.833) - 109.58) + 122.24) - 23.05) + 87)
  Next i
  MsgBox Ch1 & Ch2
End Sub
Hãy nói cho mọi người biết:
1> Bạn thấy kết quả gì?
2> Tại sao lại thế?
 
Upvote 0
Giả sử trong Sheet1, các cells từ A1 đến A20 chứa các giá trị: M001, M002, M003, M004 và M005 nhưng nằm lộn xộn (đại khái như hình dưới)

attachment.php


Lưu ý: Hình chỉ là minh họa, dử liêu thật có thể sắp xếp khác... Nói chung là TÙY THÍCH, miển sao A1:A20 chắc chắn có tồn tại 5 giá trị M001, M002, M003, M004 và M005
Tôi dùng 2 đoạn code sau đây:
PHP:
Sub Test1()
  With Range("A1:A20")
    MsgBox .Find("M004").Row
  End With
End Sub

PHP:
Sub Test2()
  With Range("A1:A20")
    MsgBox WorksheetFunction.Match("M004", .Cells, 0)
  End With
End Sub
Theo các bạn 2 đoạn code trên có kết quả giống nhau hay khác nhau? Tại sao?
 

File đính kèm

  • untitled.JPG
    untitled.JPG
    19.3 KB · Đọc: 225
Upvote 0
Chào bác anhtuan,
Khi chạy như thế này thì cùng trả kết quả là số dòng của M004.
Ý nghĩa lệnh Find và hàm Match thì bác biết rồi.
Tuy nhiên, nếu em thay M004 thành M004xx thì lại khác nhau hoàn toàn.

Cái này thì vẫn ra kết quả như cũ, vì mình ẩn đi tùy chọn tìm kiếm là xlPart.
PHP:
Sub Test1()
  With Range("A1:A20")
    MsgBox .Find("M004").Row
  End With
End Sub
Cái này thì báo lỗi, vì hàm MATCH không thể tìm thấy cell nào có giá trị giống hệt M004 nữa.
PHP:
Sub Test2()
  With Range("A1:A20")
    MsgBox WorksheetFunction.Match("M004", .Cells, 0)
  End With
End Sub
Nếu em có gì sai thì bác chỉnh lại nhé |||||
 
Upvote 0
Chào bác anhtuan,
Khi chạy như thế này thì cùng trả kết quả là số dòng của M004.
Ý nghĩa lệnh Find và hàm Match thì bác biết rồi.
Tuy nhiên, nếu em thay M004 thành M004xx thì lại khác nhau hoàn toàn.

Cái này thì vẫn ra kết quả như cũ, vì mình ẩn đi tùy chọn tìm kiếm là xlPart.
PHP:
Sub Test1()
  With Range("A1:A20")
    MsgBox .Find("M004").Row
  End With
End Sub
Cái này thì báo lỗi, vì hàm MATCH không thể tìm thấy cell nào có giá trị giống hệt M004 nữa.
PHP:
Sub Test2()
  With Range("A1:A20")
    MsgBox WorksheetFunction.Match("M004", .Cells, 0)
  End With
End Sub
Nếu em có gì sai thì bác chỉnh lại nhé |||||
Đưa câu hỏi lên hổm nay mà chẳng thấy ai hỏi han gì đến, cũng buồn...
May có người hỏi: Mừng quá!
Chúng ta đang tìm "M004"... vậy bạn thử thay cell A1 thành M004 rồi chạy 2 code xem nó thế nào? Từ đó suy ra kết luận
Ỳ tôi muốn nói đến trường hợp dử liệu cần tìm nằm ngay cell đầu tiên ấy
Và trong trường này Find làm việc ra sao?
He.. he..
 
Upvote 0
Em hiểu ý bác rồi, hihi
Cái thằng Find nó có tùy chọn After đúng không ạ ? Mình mà để mặc định thì nó bỏ qua the first cell bác nhỉ. Thảo nào trong trường hợp của bác thì kết quả lệnh Find và hàm Match là khác nhau.
Phải không bác nhỉ ?
 
Upvote 0
Các bạn chạy thử đoạn code này:
PHP:
Sub Magic()
  Dim i As Long, Ch1 As String, Ch2 As String
  For i = 0 To 5
    Ch1 = Ch1 & Chr(i * (i * (i * (i * (-0.75 * i + 7.2917) - 22.5) + 16.708) + 28.25) + 72)
    Ch2 = Ch2 & Chr(i * (i * (i * (i * (i * (0.425 * i - 6.8667) + 40.833) - 109.58) + 122.24) - 23.05) + 87)
  Next i
  MsgBox Ch1 & Ch2
End Sub
Hãy nói cho mọi người biết:
1> Bạn thấy kết quả gì?
2> Tại sao lại thế?

Cái này của bác là hàm Chr(charcode), nó sẽ trả về kí tự tương ứng theo bảng mã ASCII. Công thức của bác phức tạp quá nhưng em biết nó ra tập hợp là "Hello World!"
 
Upvote 0
Web KT
Back
Top Bottom