Đố 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,907
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
 
Hằng số Pi trong VBA

Trên bảng tính, để lấy hằng số Pi ta dùng hàm Pi()
Vậy xin hỏi trong VBA, ngoài cách dùng WorksheetFunction.Pi() thì còn cách nào khác để lấy số Pi hay không?
 
Upvote 0
Trên bảng tính, để lấy hằng số Pi ta dùng hàm Pi()
Vậy xin hỏi trong VBA, ngoài cách dùng WorksheetFunction.Pi() thì còn cách nào khác để lấy số Pi hay không?

= Application.Acos(-1)

Khà khà khà, hông biết, hông biết! Trả lời trớt quớt cho vui.
 
Upvote 0
= Application.Acos(-1)

Khà khà khà, hông biết, hông biết! Trả lời trớt quớt cho vui.
Dạ vâng!
Hướng đi của sư phụ gần giống với cách làm của em!
Có điều sư phụ dùng Application thì cũng chẳng khác nào với WorksheetFunction
Hi... Hi...
Để ý trong VBA có hàm ATN
Ta có:
TAN(Pi/4) = 1
Nên
ATN(1) = Pi/4
Suy ra
Pi = 4 * ATN(1)
Xong!
 
Upvote 0
Thêm 1 câu hỏi (có liên quan đến số Pi)

Thêm 1 câu hỏi nữa, nó có liên quan đến số Pi
Xem hình:



View attachment 42777

- Với Input Value là vùng màu xanh, làm thế nào xây dụng 1 hàm người dùng để cho kết quả giống như vùng màu vàng?
Gơi ý: Có thể tưởng tượng thế này:
- Một hình vuông được đặt vào hệ trục tọa độ Ox, Oy sao cho tâm của hình vuông trùng với tâm O của hệ trục tọa độ
- Kết quả tại vùng màu vàng chính là tọa độ giao điểm của hình vuông với 4 trục đối xứng (của hình vuông)
(Pos hình và chỉnh này giờ mà sao nó vẫn ko dc vậy ta?)
 

File đính kèm

  • ToaDo.xls
    16 KB · Đọc: 18
Lần chỉnh sửa cuối:
Upvote 0
Buồn buồn, chả có gì làm (hic). Ăn gian cho ngắn hàm.

PHP:
Function ResultX(InputN As Long) As Long
    Dim A As Long
    A = InputN Mod 8
    ResultX = Cos(Application.Pi() / 4 * A)
End Function

PHP:
Function ResultY(InputN As Long) As Long
    Dim B As Long
    B = InputN Mod 8
    ResultY = Sin(Application.Pi() / 4 * B)
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Thôi không ăn gian nữa, làm cho cụ thể tí.

PHP:
Function ResultX(InputN As Long) As Double
    Dim A As Long
    A = InputN Mod 8
    Select Case A
        Case 0, 2, 4, 6
            ResultX = Cos(Application.Pi() / 4 * A)
        Case 1, 3
            ResultX = Tan(Application.Pi() / 4 * A)
        Case 5, 7
            ResultX = -Tan(Application.Pi() / 4 * A)
    End Select
End Function

PHP:
Function ResultY(InputN As Long) As Double
    Dim B As Long
    B = InputN Mod 8
    Select Case B
        Case 0, 2, 4, 6
            ResultY = Sin(Application.Pi() / 4 * B)
        Case 1, 7
            ResultY = Tan(Application.Pi() / 4 * B)
        Case 3, 5
            ResultY = -Tan(Application.Pi() / 4 * B)
    End Select
End Function

Còn đây là hàm mảng tính 1 lần 2 ô:

PHP:
Function ResultXY(InputN)
    Dim ResultTmp(1 To 2)
    Dim A As Long
    A = InputN Mod 8
    Select Case A
        Case 0, 2, 4, 6
            ResultTmp(1) = Cos(Application.Pi() / 4 * A)
            ResultTmp(2) = Sin(Application.Pi() / 4 * A)
        Case 1
            ResultTmp(1) = Tan(Application.Pi() / 4 * A)
            ResultTmp(2) = Tan(Application.Pi() / 4 * A)
        Case 5
            ResultTmp(1) = -Tan(Application.Pi() / 4 * A)
            ResultTmp(2) = -Tan(Application.Pi() / 4 * A)
        Case 3
            ResultTmp(1) = Tan(Application.Pi() / 4 * A)
            ResultTmp(2) = -Tan(Application.Pi() / 4 * A)
        Case 7
            ResultTmp(1) = -Tan(Application.Pi() / 4 * A)
            ResultTmp(2) = Tan(Application.Pi() / 4 * A)
    End Select
    ResultXY = ResultTmp

End Function
 
Upvote 0
Thôi không ăn gian nữa, làm cho cụ thể tí.

PHP:
Function ResultX(InputN As Long) As Double
Dim A As Long
A = InputN Mod 8
Select Case A
Case 0, 2, 4, 6
ResultX = Cos(Application.Pi() / 4 * A)
Case 1, 3
ResultX = Tan(Application.Pi() / 4 * A)
Case 5, 7
ResultX = -Tan(Application.Pi() / 4 * A)
End Select
End Function

PHP:
Function ResultY(InputN As Long) As Double
Dim B As Long
B = InputN Mod 8
Select Case B
Case 0, 2, 4, 6
ResultY = Sin(Application.Pi() / 4 * B)
Case 1, 7
ResultY = Tan(Application.Pi() / 4 * B)
Case 3, 5
ResultY = -Tan(Application.Pi() / 4 * B)
End Select
End Function

Còn đây là hàm mảng tính 1 lần 2 ô:

PHP:
Function ResultXY(InputN)
Dim ResultTmp(1 To 2)
Dim A As Long
A = InputN Mod 8
Select Case A
Case 0, 2, 4, 6
ResultTmp(1) = Cos(Application.Pi() / 4 * A)
ResultTmp(2) = Sin(Application.Pi() / 4 * A)
Case 1
ResultTmp(1) = Tan(Application.Pi() / 4 * A)
ResultTmp(2) = Tan(Application.Pi() / 4 * A)
Case 5
ResultTmp(1) = -Tan(Application.Pi() / 4 * A)
ResultTmp(2) = -Tan(Application.Pi() / 4 * A)
Case 3
ResultTmp(1) = Tan(Application.Pi() / 4 * A)
ResultTmp(2) = -Tan(Application.Pi() / 4 * A)
Case 7
ResultTmp(1) = -Tan(Application.Pi() / 4 * A)
ResultTmp(2) = Tan(Application.Pi() / 4 * A)
End Select
ResultXY = ResultTmp
 
End Function

Sư phụ ơi!
Kết quả của hàm em cho vào file cụ thể đây! Sư phụ hãy so sánh với kết quả gốc nhé (có sai lệch)
Em xin nói thêm: Cái em cần là 1 hàm mảng ra kết quả cùng lúc 2 cell luôn (giống hàm ResultXY)
 

File đính kèm

  • ToaDo.xls
    27 KB · Đọc: 11
Upvote 0
Sai lệch là vô cùng bé do tính tan = phương pháp gì đó của Bill:
6,12303E-17 ~ = 0
 
Upvote 0
Sai lệch là vô cùng bé do tính tan = phương pháp gì đó của Bill:
6,12303E-17 ~ = 0
Đấy... đấy chính là cái rắc rối mà em cần giải quyết!
Phải tuyệt đối chính xác chứ sư phụ (vì còn dùng kết quả để tính toán cho các bài toán khác cơ mà)
Sao sư phụ không dùng pp "ăn gian" giống ở trên nhỉ? Có sao đâu, miễn kết quả đúng... Em thì không gọi đấy là "ăn gian" mà cho rằng đấy là "sáng tạo"
 
Lần chỉnh sửa cuối:
Upvote 0
Phải tuyệt đối chính xác chứ sư phụ (vì còn dùng kết quả để tính toán cho các bài toán khác cơ mà)

Vậy thì dùng hàm round đi, dùng trong VBA ấy. Round(ResultTmp(), 10) vẫn còn đúng chứ đừng nói Round(xxx, 0).
Còn PP ăn gian là ép vào loại biến Long.

PHP:
Function ResultXY(InputN As Long) 
    Dim A As Long, ResultTmp(1 to 2) As Long
    A = InputN Mod 8
    ResultTmp(1) = Cos(Application.Pi() / 4 * A)
    ResultTmp(2) = Sin(Application.Pi() / 4 * A)
    ResultXY = ResultTmp
End Function

Test rồi nha.
 
Upvote 0
Vậy thì dùng hàm round đi, dùng trong VBA ấy. Round(ResultTmp(), 10) vẫn còn đúng chứ đừng nói Round(xxx, 0).
Còn PP ăn gian là ép vào loại biến Long.

PHP:
Function ResultXY(InputN As Long) 
Dim A As Long, ResultTmp(1 to 2) As Long
A = InputN Mod 8
ResultTmp(1) = Cos(Application.Pi() / 4 * A)
ResultTmp(2) = Sin(Application.Pi() / 4 * A)
ResultXY = ResultTmp
End Function

Test rồi nha.
Vâng! Em vẫn thích "an gian" hơn!
Mà sư phụ nè:
- Đâu cần Mod 8 làm gì chứ, với SIN, COS thì hết 1 vòng tròn sẽ quay lại từ đầu thôi
- Thay Application.Pi() / 4 bằng ATN(1) gọn hơn
Em mạn phép sửa lại chút
PHP:
Function ResultXY(InputN As Long)
  Dim ResultTmp(1 To 2) As Long
  ResultTmp(1) = Cos(Atn(1) * InputN)
  ResultTmp(2) = Sin(Atn(1) * InputN)
  ResultXY = ResultTmp
End Function
 
Upvote 0
Em chưa dược học code mới học hàm thôi
các bác có thể chỉ cho em nơi nào học code
mà chương trình gì thì học nhanh nhất
 
Upvote 0
Em chưa dược học code mới học hàm thôi
các bác có thể chỉ cho em nơi nào học code
mà chương trình gì thì học nhanh nhất
Thì học ở đây chứ đâu nữa... Nếu có hứng thú hãy vào tham khảo 2 bài này:
Chập chững đến VBA! của sư phụ SA_DQ

Kiến thức cơ bản về Visual Basic for Applications (VBA) của thầy Phan Tự Hướng
Ngoài ra bạn cũng có thể mua sách do GPE xuất bản về xem
Còn cái vụ "
nhanh nhất" thì e rằng hỏng có... Vì trên đời này chẳng có cái vụ học gì mà không cực khổ cả
Có hiên nhẫn ắc có thành công!
 
Upvote 0
Em xin nói thêm: Cái em cần là 1 hàm mảng ra kết quả cùng lúc 2 cell luôn (giống hàm ResultXY)
Sao sư phụ không dùng pp "ăn gian" giống ở trên nhỉ? Có sao đâu, miễn kết quả đúng... Em thì không gọi đấy là "ăn gian" mà cho rằng đấy là "sáng tạo"
Vâng! Em vẫn thích "an gian" hơn!

Hình như mình bị trúng kế khích tướng thì phải? Ặc ặc!

Không sao, chỉ chuyển mỗi cái As Long từ dòng trên xuống dòng dưới thôi mà.
 
Lần chỉnh sửa cuối:
Upvote 0
Hihihi! Code hay quá!
Em cũng xin đề một bài đơn giản nhưng yêu cầu thuật toán cao nha! hihi
Đề: Tính số tiền Taxi chạy trên đường với bảng Km như sau:
Km <=2 thì lấy 15đ
3<=Km<=50 thì lấy 10đ/km
51<=Km<=200 thì lấy 7đ/Km
Km>200 thì lấy 5đ/km

Nếu xe đi 1m cũng lấy 15đ
Xe đi 10Km thì 2Km đầu là 15đ còn 8Km sau thì lấy 10đ/Km
Nếu Km bị âm thì hàm xuất dòng thông báo lỗi.
Thân.
[p/s: Nếu em tìm thấy đề nào hay hay thì em sẽ kiếm mấy bác làm phiền chơi nha! hihihi:D Nhớ mọi người rất nhiều!]
 
Upvote 0
Tay này ra đề có chuyện rồi:
2,001Km đến 2,999Km =?
50,001Km đến 50,999Km=?
 
Upvote 0
Hihihi! Code hay quá!
Em cũng xin đề một bài đơn giản nhưng yêu cầu thuật toán cao nha! hihi
Đề: Tính số tiền Taxi chạy trên đường với bảng Km như sau:
Km <=2 thì lấy 15đ
3<=Km<=50 thì lấy 10đ/km
51<=Km<=200 thì lấy 7đ/Km
Km>200 thì lấy 5đ/km

Nếu xe đi 1m cũng lấy 15đ
Xe đi 10Km thì 2Km đầu là 15đ còn 8Km sau thì lấy 10đ/Km
Nếu Km bị âm thì hàm xuất dòng thông báo lỗi.
Thân.
[p/s: Nếu em tìm thấy đề nào hay hay thì em sẽ kiếm mấy bác làm phiền chơi nha! hihihi:D Nhớ mọi người rất nhiều!]
Nếu đi được 2.5 Km thì lấy bao nhiêu?
Ẹc... Ẹc...
(bài này hao hao giống với tính thuế thu nhập cá nhân và tính tiền điện nhỉ ---> Đúng "bài" của anh Sealand rồi còn gì)
 
Upvote 0
Ndu "hich" 1 cái làm mình phấn khích nên cũng tham gia xem sao

PHP:
Function Cuoc(Dai As Double) As Variant
If Dai <= 0 Then Cuoc = 0: Cuoc = IIf(Dai = 0, 0, "Sai Km"): Exit Function
If Dai > Int(Dai) Then Dai = Int(Dai) + 1
Cuoc = Dai
Select Case Dai
Case Is > 200
Cuoc = Dai * 5
Case Is > 50
Cuoc = Dai * 7
Case Is > 10
Cuoc = Dai * 10
Case Is = 10
Cuoc = 110
Case Is < 10
Cuoc = Dai * 15
End Select
End Function

Minh phân vân vì tác giả đòi thuật toán cao nhưng mình thì "Chuyện thường ngày ở huyện."
 
Lần chỉnh sửa cuối:
Upvote 0
Ndu "hich" 1 cái làm mình phấn khích nên cũng tham gia xem sao

PHP:
Function Cuoc(Dai As Double) As Variant
If Dai <= 0 Then Cuoc = 0: Cuoc = IIf(Dai = 0, 0, "Sai Km"): Exit Function
If Dai > Int(Dai) Then Dai = Int(Dai) + 1
Cuoc = Dai
Select Case Dai
Case Is > 200
Cuoc = Dai * 5
Case Is > 50
Cuoc = Dai * 7
Case Is > 10
Cuoc = Dai * 10
Case Is = 10
Cuoc = 110
Case Is < 10
Cuoc = Dai * 15
End Select
End Function
Minh phân vân vì tác giả đòi thuật toán cao nhưng mình thì "Chuyện thường ngày ở huyện."
Theo em nghĩ, bài toán này phải tính theo lũy tiến chứ anh
Với số Km = 11, sao UDF của anh cũng ra kết quả = 110 vậy? (bằng luôn với trường hợp Km = 10)
 
Upvote 0
Nếu tính luỹ tiến thì câu điếu kiện 10Km phải là từ 10 đến 50Km là: 2km giá 15 còn lại giá 10.
Mình sửa lại theo dạng luỹ tiến:

PHP:
Function Cuoc1(Dai As Double) As Variant
If Dai <= 0 Then Cuoc = 0: Cuoc = IIf(Dai = 0, 0, "Sai Km"): Exit Function
If Dai > Int(Dai) Then Dai = Int(Dai) + 1
Cuoc = Dai
Select Case Dai
Case Is > 200
Cuoc = (Dai - 200) * 5 + 1560
Case Is > 50
Cuoc = (Dai - 50) * 7 + 510
Case Is > 9
Cuoc = (Dai - 2) * 10 + 30
Case Is < 10
Cuoc = Dai * 15
End Select
End Function
Nếu chỉ tính từ 1m trở đi còn dưới 1 m bỏ thì sửa câu lệnh

If Dai > Int(Dai) Then Dai = Int(Dai) + 1

Thành:

If Dai*100 > Int(Dai*100) Then Dai = Int(Dai) + 1
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT
Back
Top Bottom