Đố 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
 
Vậy rốt cục nó như thế nào Anh nói ra luôn đi nhé!

Ở trên mấy anh đã giải thích hết rồi: Phụ thuộc vào cách tìm trước đó (nhưng chưa tắt Excel), trước đó nếu tìm bằng code, bằng Ctrl + H, hoặc bằng Ctrl + F .... ta tùy chọn kiểu gì thì lần sau nó tìm kiểu đó, còn khi mới khởi động Excel thì nó mặc định là tìm gần đúng: Trong chuỗi "GPE1" có chứa chuỗi "GPE" --> kết quả của tìm gần đúng là: Có tìm thấy.
Còn nếu tìm chính xác thì Cell cần tìm phải chứa chuỗi giống hệt chuỗi cần tìm, không thêm, không bớt kể cả ký tự trắng.
 
Lần chỉnh sửa cuối:
Upvote 0
Không ndu à, nếu bỏ qua tham số thì nếu chạy lần đầu nó còn phụ thuột tùy chon Find trên Excel (giả sử như mình tìm gì đó trên Excel trước khi chạy code),hình như mặc định là tìm gần đúng
Thì em đã nói trước đó rồi còn gì... rất rõ nữa là đàng khác
Còn nếu ta cố tình bỏ qua cái màu đỏ ở trên thì nó sẽ theo cái sự tìm kiếm của lần trước ---> Lần trước mình tìm chính xác thì giờ chạy code nó sẽ tìm chính xác... Còn lần trước mình tìm gần đúng thì lần này nó cũng sẽ tìm gần đúng
chỉ có sư phụ Mỹ là hiểu rất rõ em muốn nói về cái gì
hình như mặc định là tìm gần đúng
Không có tài liệu nào nói cái MẶC ĐỊNH của Excel là như thế nào đâu nha
Vậy rốt cục nó như thế nào Anh nói ra luôn đi nhé!
TRUE hay FALSE là tùy theo từng máy tính, không thể nói chính xác được đâu
------------------------
Nói thêm 1 chút về cái vụ LẦN TRƯỚC: Nó không chỉ có xlPart, xlWhole không thôi mà còn nhiều tham số khác phải quan tâm, như: xlValues hay xlFormulas, MatchCase = True hay False nữa ---> Nhắm mắt nhắm mũi viết đại có khi trên máy mình chạy được còn sang máy khác lại... toi
Ẹc... Ẹc...
 
Upvote 0
Không có tài liệu nào nói cái MẶC ĐỊNH của Excel là như thế nào đâu nha

Mình chưa thấy máy nào mới khởi động Excel mà mục Match entire cell contents trong tùy chọn của công cụ Find được check cả. Đánh dấu check vào, tắt Excel, mở lên lại mất dấu --> mình cho là mặc định nó vậy.
--------------
Khi dùng Find trong VBA với các tham số xlPart hoặc xlWhole cũng làm thay đổi được tùy chọn Match entire cell contents nhưng cũng chỉ có tác dụng trong phiên làm việc đó thôi.
 
Lần chỉnh sửa cuối:
Upvote 0
Mình chưa thấy máy nào mới khởi động Excel mà mục Match entire cell contents trong tùy chọn của công cụ Find được check cả. Đánh dấu check vào, tắt Excel, mở lên lại mất dấu --> mình cho là mặc định nó vậy.
--------------
Khi dùng Find trong VBA với các tham số xlPart hoặc xlWhole cũng làm thay đổi được tùy chọn Match entire cell contents nhưng cũng chỉ có tác dụng trong phiên làm việc đó thôi.
Em không nghĩ thế! Có thể với 1 vài tinh chỉnh nhỏ trong Registry có thể làm cho Match entire cell contents luôn luôn được check cũng không chừng
Anh và mọi người cứ nghiên cứu xem!
Nói tóm lại: Do ta không biết được cái gì là MẶC ĐỊNH nên khi dùng Find Method thôi thì cứ viết cho thật rõ ràng
 
Upvote 0
Bình thường khi nhấn AutoFilter 10 cột dữ liệu ta sẽ được như hình:

Filter1.jpg

Nhưng tôi muốn Filter kiểu khác, mỗi cột filter bắt đầu từ 1 dòng khác nhau:

Filter di lac.jpg

Câu đố là: Làm thế nào để được như vậy?

Câu này ndu biết, trong bài đố vali đi lạc bên trên.

Ghi chú:
Làm xong hông xài như ý mình muốn, nó chạy hông giống ai hết.
 
Upvote 0
Các bạn có thể thêm nút lệnh vào menu của VBE được không?, như hình sau nè:
 

File đính kèm

  • untitled.JPG
    untitled.JPG
    53.6 KB · Đọc: 66
Lần chỉnh sửa cuối:
Upvote 0
Các bạn có thể thêm nút lệnh vào menu của VBE được không?, như hình sau nè:
Chỉ cần thí nghiệm bằng code này:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls
    MsgBox Item.Caption
  Next
End Sub
Hoặc:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls("Tools").Controls
    MsgBox Item.Caption
  Next
End Sub
là có thể làm gì đó thoải mái ---> Giống như Menu của Workbook
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Upvote 0
Chỉ cần thí nghiệm bằng code này:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls
    MsgBox Item.Caption
  Next
End Sub
Hoặc:
PHP:
Sub Test()
  Dim Item As CommandBarControl
  For Each Item In Application.VBE.CommandBars("Menu Bar").Controls("Tools").Controls
    MsgBox Item.Caption
  Next
End Sub
là có thể làm gì đó thoải mái ---> Giống như Menu của Workbook
Ẹc... Ẹc...

Sư phụ thử chạy coi, ví dụ:
PHP:
Sub Test()
    Dim CmdBarItem As CommandBarControl
    With Application.VBE.CommandBars("Menu Bar").Controls("Tools")
        Set CmdBarItem = .Controls.Add
    End With
    With CmdBarItem
        .Caption = "First Item"
        .BeginGroup = True
        .OnAction = "DienDanExcel"
    End With
End Sub
Sub DienDanExcel()
    Sheets(1).Select
    [A1] = "GPE"
End Sub
Sub DeleteMenuItems()
    Application.VBE.CommandBars("Menu Bar").Controls("Tools").Reset
End Sub
Sub Auto_Close()
    DeleteMenuItems
End Sub
 
Upvote 0
Mình chưa thấy máy nào mới khởi động Excel mà mục Match entire cell contents trong tùy chọn của công cụ Find được check cả. Đánh dấu check vào, tắt Excel, mở lên lại mất dấu --> mình cho là mặc định nó vậy.
--------------
Khi dùng Find trong VBA với các tham số xlPart hoặc xlWhole cũng làm thay đổi được tùy chọn Match entire cell contents nhưng cũng chỉ có tác dụng trong phiên làm việc đó thôi.
Cũng cái Find này, khi làm bằng tay thì nó cho mình chọn tùy chọn Within (Workbook hay là Sheet). Nhưng sao khi dùng VBA thì nó không có tùy chọn này cho mình nhỉ. Và nó cũng lấy theo lần tìm kiếm trước đó. Xin hỏi có ai biết cách khắc phục cái này không?
 
Upvote 0
Sư phụ thử chạy coi, ví dụ:
PHP:
Sub Test()
    Dim CmdBarItem As CommandBarControl
    With Application.VBE.CommandBars("Menu Bar").Controls("Tools")
        Set CmdBarItem = .Controls.Add
    End With
    With CmdBarItem
        .Caption = "First Item"
        .BeginGroup = True
        .OnAction = "DienDanExcel"
    End With
End Sub
Sub DienDanExcel()
    Sheets(1).Select
    [A1] = "GPE"
End Sub
Sub DeleteMenuItems()
    Application.VBE.CommandBars("Menu Bar").Controls("Tools").Reset
End Sub
Sub Auto_Close()
    DeleteMenuItems
End Sub
Ý anh muốn nói gì đây? Action nó không được chăng? Muốn làm được điều này phải dùng ClassModule anh ơi
Xem cái này:
http://www.cpearson.com/excel/VbeMenus.aspx
 
Upvote 0
Cũng cái Find này, khi làm bằng tay thì nó cho mình chọn tùy chọn Within (Workbook hay là Sheet). Nhưng sao khi dùng VBA thì nó không có tùy chọn này cho mình nhỉ. Và nó cũng lấy theo lần tìm kiếm trước đó. Xin hỏi có ai biết cách khắc phục cái này không?

Mình nghĩ là cái này nó khác với tìm trong Excel:
- Khi tìm bằng Code mình đã chỉ định một Range (hoặc Name) rồi nên không thể nào là Workbook được.
- Còn trong Excel mình có thể không chọn vùng nào, cứ thế tìm tới, theo hàng hoặc theo cột (tùy chọn) vì vậy nó phải có cái tùy chọn là Wb hay Ws để gi[í hạn.
Theo Help:
expression.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
expression Required. An expression that returns a Range object.

To ndu: Đúng là không có gì Bạn không biết (by Excel).
 
Lần chỉnh sửa cuối:
Upvote 0
Cũng cái Find này, khi làm bằng tay thì nó cho mình chọn tùy chọn Within (Workbook hay là Sheet). Nhưng sao khi dùng VBA thì nó không có tùy chọn này cho mình nhỉ. Và nó cũng lấy theo lần tìm kiếm trước đó. Xin hỏi có ai biết cách khắc phục cái này không?
Có nhiều món bác Bill cho làm bằng tay nhưng lại không cho code để viết, chẳng hạn ta có thể "nén" toàn bộ Pictures trong bảng tính chỉ bằng 1 thao tác, vậy mà lại không thể viết ra thành code
Find Method cũng thuộc dạng này. Search google sẽ thấy rất nhiều người hỏi mà không có giải pháp nào nếu không dùng vòng lập
 
Upvote 0
Mình nghĩ là cái này nó khác với tìm trong Excel:
- Khi tìm bằng Code mình đã chỉ định một Range (hoặc Name) rồi nên không thể nào là Workbook được.
- Còn trong Excel mình có thể không chọn vùng nào, cứ thế tìm tới, theo hàng hoặc theo cột (tùy chọn) vì vậy nó phải có cái tùy chọn là Wb hay Ws để gi[í hạn.
Theo Help:

To ndu: Đúng là không có gì Bạn không biết (by Excel).
Đâu có phải như vậy. Bạn thử dùng Find bằng tay với phạm vi toàn Workbook. Sau đó dùng Find bằng Macro. Macro cũng sẽ tìm trên phạm vi toàn Workbook luôn.
 
Upvote 0
Đâu có phải như vậy. Bạn thử dùng Find bằng tay với phạm vi toàn Workbook. Sau đó dùng Find bằng Macro. Macro cũng sẽ tìm trên phạm vi toàn Workbook luôn.
Dù là vậy cũng chẳng xài được vào việc gì, thậm chí còn gây nhầm lẫn đáng tiếc nếu mang code sang máy khác nữa.
Nói chung vụ này tôi đã tìm khắp google rồi mà vẫn KHÔNG CÓ CÁCH
 
Upvote 0
Dù là vậy cũng chẳng xài được vào việc gì, thậm chí còn gây nhầm lẫn đáng tiếc nếu mang code sang máy khác nữa.
Nói chung vụ này tôi đã tìm khắp google rồi mà vẫn KHÔNG CÓ CÁCH
Vì tôi có viết một đoạn code, trong code dùng phương thức Replace cho một Sheet cố định. Nhưng nếu người dùng dùng Find trên phạm vi toàn Workbook thì sau đó code sẽ chạy sai.

Anh Bill không cho thì đành bó tay vậy //////
 
Upvote 0
Vì tôi có viết một đoạn code, trong code dùng phương thức Replace cho một Sheet cố định. Nhưng nếu người dùng dùng Find trên phạm vi toàn Workbook thì sau đó code sẽ chạy sai.

Anh Bill không cho thì đành bó tay vậy //////

Bạn cho mình một ví dụ đi, sao mình cố cho nó xảy ra giống Bạn mà không được. Nó chỉ tìm khi có địa chỉ được chỉ định và chỉ tìm trên sheet hiện hành dù trước đó có tìm bằng tay trên toàn Wb
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn cho mình một ví dụ đi, sao mình cố cho nó xảy ra giống Bạn mà không được. Nó chỉ tìm khi có địa chỉ được chỉ định và chỉ tìm trên sheet hiện hành dù trước đó có tìm bằng tay trên toàn Wb
Bạn Find bằng tay trên toàn Workbook rồi sau đó chạy code. Sang Sheet2 kiểm tra lại.
Cũng code đó nhưng trước khi chạy code bạn find trên Worksheet thôi thì kết quả lại khác.
 

File đính kèm

  • Test.xls
    56 KB · Đọc: 10
Upvote 0
Bạn Find bằng tay trên toàn Workbook rồi sau đó chạy code. Sang Sheet2 kiểm tra lại.
Cũng code đó nhưng trước khi chạy code bạn find trên Worksheet thôi thì kết quả lại khác.

Bạn thêm một câu lệnh này vào thử
Set Rng = Sheets(1).UsedRange.Find("*", , , xlPart)

PHP:
Sub Test()
    Application.ScreenUpdating = False
    Set Rng = Sheets(1).UsedRange.Find("*", , , xlPart)
        If Sheet1.[A1].HasFormula Then
            Sheet1.UsedRange.Replace What:="=", Replacement:="!@#", LookAt:=xlPart
        Else
            Sheet1.UsedRange.Replace What:="!@#", Replacement:="=", LookAt:=xlPart
        End If
        Application.ScreenUpdating = True
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Một bài toán tách số

Tôi có dữ liệu thế này:
4342gfgdfg
2342sdbdvb
345dvbcvb
54353
gdfgdfg

Các chuổi tuân thủ nguyên tắc:
- Hoặc không chứa bất kỳ số nào
- Hoặc chỉ toàn là số
- Hoặc lẩn lộn vừa số vừa chữ nhưng số luôn nằm cạnh nhau về bên trái còn chữ thì nằm bên phải
Yêu cầu tách lấy số:
4342gfgdfg ---> 4342
2342sdbdvb ----> 2342
345dvbcvb ----> 345
54353 ----> 54353
gdfgdfg ----> 0

Code không dùng vòng lập và nếu code ngắn dưới 3 dòng thì càng tốt...
 
Upvote 0
Nếu như nguyên tắc của Anh Tuan thì code sau có thể

Msgbox Val("1325gfghtv")
 
Upvote 0
Web KT

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

Back
Top Bottom