Đố 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ẫn còn cách khác mà không phải là sử dụng mẹo - không theo đường chính như cách đó,

Vậy các bạn thử tìm xem,

hong biết là theo kiểu sau có được không anh?

If ... Then
ComboBox2.MatchRequired = False
Else
ComboBox2.MatchRequired = True
End If
 
Upvote 0
Vẫn còn cách khác mà không phải là sử dụng mẹo - không theo đường chính như cách đó,

Vậy các bạn thử tìm xem,

Lời giải của bải tôi đã đố chỉ đơn giản như thế này:
PHP:
Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If ComboBox1 = "" Or ComboBox1.ListIndex > -1 Then Exit Sub
    MsgBox "Ban chi duoc nhap muc co san trong list ma thoi!"
    Cancel = True
End Sub

Tuy nhiên, để thử làm cái mà bạn đố tiếp theo, tôi cũng cố thử như sau:

Tạo một biến Boolean bên ngoài, bẫy lỗi tại sự kiện Change, rồi theo biến Boolean "bắt lỗi" ở sự kiện Exit:

PHP:
Dim isErr As Boolean

Private Sub ComboBox1_Change()
    isErr = False
    On Error GoTo ErrCase
    Dim BienAo As String
    BienAo = ComboBox1.List(, 0)
    Exit Sub
ErrCase:
    isErr = True
End Sub

Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If ComboBox1 = "" Or isErr = False Then Exit Sub
    MsgBox "Ban chi duoc nhap muc co san trong list ma thoi!"
    Cancel = True
End Sub

Xem ra nó cũng na ná cái kia.
 
Upvote 0
Vẫn còn cách khác mà không phải là sử dụng mẹo - không theo đường chính như cách đó,

Vậy các bạn thử tìm xem,

@Nghĩa:
Nghĩa cứ tôi bạn, anh em là được. Tôi đã từng yêu cầu ai đó đừng gọi là Thầy. Nếu có khâu "nhận trò" thì lúc đó là quan hệ Thầy - Trò còn không thì chia sẻ lẫn nhau thôi.
Thực ra tôi không phải là Thầy ... bói để đoán được đáp án của Nghĩa. Cũng chả phải là Thầy do qua trường lớp, vì 1 khóa ngắn hạn về lập trình cũng chưa học.
--------------
Tôi cũng không bói được đáp án của vodoi2x, nhưng nếu viết khác đi thì cũng có thể thế này, nếu tôi không lầm:

[GPECODE=vb]
If Not ComboBox1.MatchFound Then
If MsgBox("Ban chi duoc nhap muc co san trong list ma thoi!" & vbCrLf & _
"Hay chon OK de tro lai nhap du lieu hoac Cancel de huy nhap du lieu", _
vbOKCancel, "Error") = vbOK Then
Cancel = True
Else
' lenh huy nhap du lieu
End If
End If
[/GPECODE]
 
Lần chỉnh sửa cuối:
Upvote 0
@Nghĩa:
Nghĩa cứ tôi bạn, anh em là được. Tôi đã từng yêu cầu ai đó đừng gọi là Thầy. Nếu có khâu "nhận trò" thì lúc đó là quan hệ Thầy - Trò còn không thì chia sẻ lẫn nhau thôi.
Thực ra tôi không phải là Thầy ... bói để đoán được đáp án của Nghĩa. Cũng chả phải là Thầy do qua trường lớp, vì 1 khóa ngắn hạn về lập trình cũng chưa học.
--------------
Tôi cũng không bói được đáp án của vodoi2x, nhưng nếu viết khác đi thì cũng có thể thế này, nếu tôi không lầm:

[GPECODE=vb]
If Not ComboBox1.MatchFound Then
If MsgBox("Ban chi duoc nhap muc co san trong list ma thoi!" & vbCrLf & _
"Hay chon OK de tro lai nhap du lieu hoac Cancel de huy nhap du lieu", _
vbOKCancel, "Error") = vbOK Then
Cancel = True
Else
' lenh huy nhap du lieu
End If
End If
[/GPECODE]

Đúng rùi, bác siwtom ah, đó mới chính là thuộc tính (.MatchFound)sinh ra để kiểm tra việc tồn tại của item đó hay không.

Dùng đúng chức năng từ công cụ thuộc tính sẵn có thì sẽ giúp code đơn giản và ưu thế về tốc độ.

Qua đây mới thấy Microsoft đã dự trù khá nhiều trường hợp và thật là kiến trúc tư duy có hệ thống có khác - hơn hẳn kiểu tư duy chắp vá vụ vặt như chúng ta
 
Upvote 0
@Nghĩa:
Nghĩa cứ tôi bạn, anh em là được. Tôi đã từng yêu cầu ai đó đừng gọi là Thầy. Nếu có khâu "nhận trò" thì lúc đó là quan hệ Thầy - Trò còn không thì chia sẻ lẫn nhau thôi.
Thực ra tôi không phải là Thầy ... bói để đoán được đáp án của Nghĩa. Cũng chả phải là Thầy do qua trường lớp, vì 1 khóa ngắn hạn về lập trình cũng chưa học.

Thầy kính quý,

Không phải ai em cũng nhận họ làm Sư phụ, làm Thầy, không phải người mà em đóng tiền học phí để đứng trên bục giảng thì trong lòng em tôn trọng là thầy mà tại vì họ là ông thầy.

Nhưng như em đã từng ghi trong chữ ký của em:

Ba người cùng đi, tất có người là Thầy ta: lựa cái hay của người này mà học, xét cái quấy của người kia mà tự sửa mình

Với bề dầy và sâu về kiến thức thì em đã học hỏi được ở Thầy rất là nhiều, thông qua đó em đã cải thiện được kiến thức mình nhiều hơn.

Vẫn biết chúng ta không có gì để ràng buộc tình nghĩa Thầy-Trò, nhưng trong tâm em thì em vẫn xem Thầy là Thầy của em ạ.

Chúc Thầy có nhiều sức khỏe và tặng thêm cho diễn đàn nhiều kiến thức bổ ích để những người còn kém cỏi như em được học thêm ạ.

Cám ơn Thầy vì tất cả.
 
Upvote 0
Code chuyển từ number sang Date

- Tôi có dữ liệu dạng number tại cột A
- Mỗi cell là 1 số có 8 chữ số
- Số được bố trí nhìn giống như dạng yyyymmdd. Ví dụ: 20130103, 20130104
- Tôi viết code để chuyển những số này thành Date. Ví dụ 20130103 sẽ được chuyển thành 3/1/2013
Code như sau:
Mã:
Sub Number2Date()
  Dim rng, rCel As Range, lTmp
  Dim lR As Long, lC As Long
  On Error Resume Next
  Set rng = Selection
  If TypeOf rng Is Range Then
    For Each rCel In rng
      lTmp = rCel.Value
      If IsNumeric(lTmp) Then
        If Val(lTmp) > 100000 Then
          lTmp = DateValue(Format(lTmp, "0000""/""00""/""00"))
          rCel.Value = lTmp
        End If
      End If
    Next
    rng.NumberFormat = "dd/mm/yyyy"
    MsgBox "Done!"
  End If
End Sub
Code chạy không có vấn đề nhưng nếu 1 cell nào đó được định dạng trước là dd/mm/yyyy thì code không có tác dụng.
Nói chung, nếu cell được định dạng General thì code chạy không có vấn đề
Xin hỏi: Phải giải quyết vấn đề này thế nào?
(Mời xem file để biết thêm chi tiết)
 

File đính kèm

  • Num2Date_Test.xls
    39 KB · Đọc: 13
Upvote 0
- Tôi có dữ liệu dạng number tại cột A
- Mỗi cell là 1 số có 8 chữ số
- Số được bố trí nhìn giống như dạng yyyymmdd. Ví dụ: 20130103, 20130104
- Tôi viết code để chuyển những số này thành Date. Ví dụ 20130103 sẽ được chuyển thành 3/1/2013
Code như sau:
Mã:
Sub Number2Date()
  Dim rng, rCel As Range, lTmp
  Dim lR As Long, lC As Long
  On Error Resume Next
  Set rng = Selection
  If TypeOf rng Is Range Then
    For Each rCel In rng
      lTmp = rCel.Value
      If IsNumeric(lTmp) Then
        If Val(lTmp) > 100000 Then
          lTmp = DateValue(Format(lTmp, "0000""/""00""/""00"))
          rCel.Value = lTmp
        End If
      End If
    Next
    rng.NumberFormat = "dd/mm/yyyy"
    MsgBox "Done!"
  End If
End Sub
Code chạy không có vấn đề nhưng nếu 1 cell nào đó được định dạng trước là dd/mm/yyyy thì code không có tác dụng.
Nói chung, nếu cell được định dạng General thì code chạy không có vấn đề
Xin hỏi: Phải giải quyết vấn đề này thế nào?
(Mời xem file để biết thêm chi tiết)

Nếu ô được định dạng ngày thì khi dùng .value để lấy giá trị kết quả sẽ là ngày. Trong dữ liệu của anh, các ô được định dạng ngày trước không hiển thị được do vượt quá giới hạn. Khi dùng .value lấy giá trị các ô này sẽ bị lỗi.

Vậy nên theo em thì anh dùng .value2 thay cho .value thì sẽ ổn.

Trích nguyên văn trong Help của Excel
The only difference between this property and the Value property is that the Value2 property doesn’t use the Currency and Date data types. You can return values formatted with these data types as floating-point numbers by using the Double data type.
 
Upvote 0
Đổi font size và tô màu cho text trong Label

Tôi vẽ 1 Label (thuộc Forms Control) trên Sheet
Ta thừa biết object này không thể đổi được font size hay font color gì cả
Vậy mà tôi đã làm được


Capture.JPG



Các bạn mở file xem và cho biết: Tôi đã làm điều đó như thế nào?
Ẹc... ẹc...
 

File đính kèm

  • Label_Example.xlsx
    10.6 KB · Đọc: 30
Upvote 0
Tôi vẽ 1 Label (thuộc Forms Control) trên Sheet
Ta thừa biết object này không thể đổi được font size hay font color gì cả
Vậy mà tôi đã làm được


View attachment 96280



Các bạn mở file xem và cho biết: Tôi đã làm điều đó như thế nào?
Ẹc... ẹc...

Em làm như đoạn clip ở dưới, hong biết còn cách nào nữa không Thầy.

[video=youtube;Vgt4YQkVaSk]http://www.youtube.com/watch?v=Vgt4YQkVaSk&feature=youtu.be[/video]
 
Upvote 0
Upvote 0
Rất có lý! Nhưng sao trong file của tôi, cái Label ấy không giống với cái Label mà Hai Lúa đang làm? (chẳng có công thức liên kết)
Ẹc... Ẹc...

Vậy là còn ít nhất 1 cách nữa, cách này không dùng cell phụ, phải dùng code phải không Thầy?
 
Upvote 0
Rất có lý! Nhưng sao trong file của tôi, cái Label ấy không giống với cái Label mà Hai Lúa đang làm? (chẳng có công thức liên kết)
Ẹc... Ẹc...
Thì thêm 1 bước nữa là chọn Label và xóa công thức trên Formula bar là được. Bây giờ thì cứ việc xóa ô A1 đi cũng chẳng sao.
 
Upvote 0
Vậy là còn ít nhất 1 cách nữa, cách này không dùng cell phụ, phải dùng code phải không Thầy?

Ai mà biết đâu nè
Cách gì cũng được, miễn sao ra kết quả Y CHANG như file của tôi là được rồi
Nói chung, cách của Hai Lúa hoàn toàn chấp nhận được, chỉ là "thiếu" 1 chút, vì chẳng lẽ khi cái Label đi đâu cũng phải "mang theo" cell phụ sao?
------------------------
Đất nước nghèo kiết xác như Bắc Triều Tiên cũng ráng bắn 1 phát tên lửa, vậy mà Hai Lúa còn xài Excel 2003 hen?
 
Upvote 0
Ai mà biết đâu nè
Cách gì cũng được, miễn sao ra kết quả Y CHANG như file của tôi là được rồi
Nói chung, cách của Hai Lúa hoàn toàn chấp nhận được, chỉ là "thiếu" 1 chút, vì chẳng lẽ khi cái Label đi đâu cũng phải "mang theo" cell phụ sao?
------------------------
Đất nước nghèo kiết xác như Bắc Triều Tiên cũng ráng bắn 1 phát tên lửa, vậy mà Hai Lúa còn xài Excel 2003 hen?

Nghĩa Phúc đã trả lời đúng câu hỏi của Thầy rồi phải không. Nghĩa Phúc nhanh tay thật.

---------------------
Hic, thật ra em cũng đang sử dụng 2010 ở máy cá nhân cho kịp thời đại, 2003 là máy cơ quan nên đành chịu.
 
Upvote 0
Thì thêm 1 bước nữa là chọn Label và xóa công thức trên Formula bar là được. Bây giờ thì cứ việc xóa ô A1 đi cũng chẳng sao.

Nghĩa Phúc đã trả lời đúng câu hỏi của Thầy rồi phải không. Nghĩa Phúc nhanh tay thật.
Nghe qua thì rất có lý, nhưng nên biết rằng topic này là BÀN VỀ VBA, tức là VIẾT CODE
Làm bằng tay xem như đã thông qua, vậy chúng ta viết code thế nào để ra được kết quả như vậy?
Chắc là các bạn sẽ nghĩ: Ôi, dễ ẹc, đã làm bằng tay được thì record macro sẽ có code --->Thì cứ thử đi rồi biết! (đố mà gán được công thức vào Label đấy!)
Tóm lại: Khi nào có code, cứ đưa lên đây để kiểm chứng
Ẹc... Ẹc...
 
Upvote 0
Nghe qua thì rất có lý, nhưng nên biết rằng topic này là BÀN VỀ VBA, tức là VIẾT CODE
Làm bằng tay xem như đã thông qua, vậy chúng ta viết code thế nào để ra được kết quả như vậy?
Chắc là các bạn sẽ nghĩ: Ôi, dễ ẹc, đã làm bằng tay được thì record macro sẽ có code --->Thì cứ thử đi rồi biết! (đố mà gán được công thức vào Label đấy!)
Tóm lại: Khi nào có code, cứ đưa lên đây để kiểm chứng
Ẹc... Ẹc...

Ghi macro thì thấy nó dùng macro4 (ExecuteExcel4Macro) nhưng ghi cho đã rồi gán ngược lại không được!
 
Upvote 0
Thì có KHÓ mới ĐỐ chứ
Nhưng đã là ĐỐ VUI thì giải pháp luôn rất đơn giản
Cố lên. Ẹc... Ẹc...

Hic, thử đủ các cách, nào là Formula, FormularR1C1, LinkCell v.v... làm ráo trọi, code không báo lỗi gì cả, nhưng kết quả không như ý!

Nhức đầu quá, thôi để cao thủ khác có cao kiến, mình đành đứng ngoài cuộc! Công nhận lâu lâu Thầy có những câu đố thật độc đáo!
 
Upvote 0
Web KT

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

Back
Top Bottom