Chú ý: Các thành viên học lớp "Lập trình VBA trong Excel" có thể trao đổi bài ở đây (1 người xem)

  • Thread starter Thread starter NH_DK
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

NH_DK

Let's patience
Tham gia
29/7/10
Bài viết
865
Được thích
1,204
Nghề nghiệp
Kế toán
Em thấy việc trao đổi bài giữa các thành viên qua Mail không tiện lắm. Vậy em "Khởi tạo topic này" để làm nơi các thành viên trong lớp học có thể trao đổi bài trong lớp cho tiện. Mình vừa trao đổi bài lại vừa có thể tìm thông tin ở GPE.
Em đặt vấn đề như vậy, nếu OK thì mời mọi người có thắc mắc, hãy gửi bài lên đây để mọi người cùng chia sẻ nhé!
Thân mếm!
 
Em có câu hỏi này, có thể là hỏi trước vấn đề học (nhưng em đã làm rồi), xin thầy Tuân chỉ dùm em nha:
Trong việc Copy từ Sheet1 sang Sheet2 thì em đã thiết lập 2 đoạn code (Thử theo 2 cách): thì 1 trong 2 đoạn code đó có đoạn không chạy được đúng ý muốn của em. Đoạn kia thì chạy tốt. cụ thể là đoạn này:
PHP:
Sub CopyDL() 'Sao cai nay khong chay duoc theo y muon nhi!?
Dim n As Long, i As Long, m As Long
    Application.ScreenUpdating = False
    Sheet2.Range("A3:I65535").Clear
    n = Sheet1.Range("I65535").End(xlUp).Row
    Sheet1.Range("A3:I" & n).Copy Destination:=Sheet2.Range("A3")
    With Sheet2
    m = .Range("A65535").End(xlUp).Row
        For i = m To 2 Step -1
            If .Cells(i, 1) & .Cells(1, 2) & .Cells(i, 3) = .Cells(i - 1, 1) & _
            .Cells(i - 1, 2) & .Cells(i - 1, 3) Then .Cells(i, 1).Resize(, 3) = Empty
 
        Next
    End With
End Sub

Em đã kiểm tra kỹ mà chưa phát hiện ra lỗi.
 

File đính kèm

Bài số 2 em không hiểu đề, bác nào giải thích hộ em với ạ
" Tạo 1 macro sắp xếp một vùng dữ liệu"
 
Em có câu hỏi này, có thể là hỏi trước vấn đề học (nhưng em đã làm rồi), xin thầy Tuân chỉ dùm em nha:
Trong việc Copy từ Sheet1 sang Sheet2 thì em đã thiết lập 2 đoạn code (Thử theo 2 cách): thì 1 trong 2 đoạn code đó có đoạn không chạy được đúng ý muốn của em. Đoạn kia thì chạy tốt. cụ thể là đoạn này:
PHP:
Sub CopyDL() 'Sao cai nay khong chay duoc theo y muon nhi!?
Dim n As Long, i As Long, m As Long
Application.ScreenUpdating = False
Sheet2.Range("A3:I65535").Clear
n = Sheet1.Range("I65535").End(xlUp).Row
Sheet1.Range("A3:I" & n).Copy Destination:=Sheet2.Range("A3")
With Sheet2
m = .Range("A65535").End(xlUp).Row
For i = m To 2 Step -1
If .Cells(i, 1) & .Cells(1, 2) & .Cells(i, 3) = .Cells(i - 1, 1) & _
.Cells(i - 1, 2) & .Cells(i - 1, 3) Then .Cells(i, 1).Resize(, 3) = Empty
 
Next
End With
End Sub

Em đã kiểm tra kỹ mà chưa phát hiện ra lỗi.
Sai chỗ này nè
If .Cells(i, 1) & .Cells(i, 2) & .Cells(i, 3)
I chứ hổng phải 1 à nha
Híc
Ủa, quên, mình hổng có học có sửa được hông "zị"
 
Em có câu hỏi này, có thể là hỏi trước vấn đề học (nhưng em đã làm rồi), xin thầy Tuân chỉ dùm em nha:
Trong việc Copy từ Sheet1 sang Sheet2 thì em đã thiết lập 2 đoạn code (Thử theo 2 cách): thì 1 trong 2 đoạn code đó có đoạn không chạy được đúng ý muốn của em. Đoạn kia thì chạy tốt. cụ thể là đoạn này:
PHP:
Sub CopyDL() 'Sao cai nay khong chay duoc theo y muon nhi!?
Dim n As Long, i As Long, m As Long
    Application.ScreenUpdating = False
    Sheet2.Range("A3:I65535").Clear
    n = Sheet1.Range("I65535").End(xlUp).Row
    Sheet1.Range("A3:I" & n).Copy Destination:=Sheet2.Range("A3")
    With Sheet2
    m = .Range("A65535").End(xlUp).Row
        For i = m To 2 Step -1
            If .Cells(i, 1) & .Cells(1, 2) & .Cells(i, 3) = .Cells(i - 1, 1) & _
            .Cells(i - 1, 2) & .Cells(i - 1, 3) Then .Cells(i, 1).Resize(, 3) = Empty
 
        Next
    End With
End Sub
Em đã kiểm tra kỹ mà chưa phát hiện ra lỗi.
Bị lỗi chỗ này nè Ngọc:
Mã:
[COLOR=#000000][COLOR=#007700].[/COLOR][COLOR=#0000BB]Cells[/COLOR][COLOR=#007700]([/COLOR][COLOR=red][COLOR=#0000BB]1[/COLOR][/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]2[/COLOR][COLOR=#007700])
[/COLOR][/COLOR]Sửa lại như vầy:
Mã:
[COLOR=#000000][COLOR=#007700].[/COLOR][COLOR=#0000BB]Cells[/COLOR][COLOR=#007700]([/COLOR][COLOR=#0000BB]i[/COLOR][COLOR=#007700], [/COLOR][COLOR=#0000BB]2[/COLOR][COLOR=#007700])
[/COLOR][/COLOR]


 
Mạn fép thầy Tuân, đưa lên 1 macro nữa cho vui cửa nhà

PHP:
Sub CopyDL()
 Dim eRw As Long, jJ As Long
 
 Application.ScreenUpdating = False
 Range("A3:I65535").Clear
 eRw = Sheet1.Range("I65535").End(xlUp).Row
4 Sheet1.Range("A3:I" & eRw).Copy Destination:=Sheet2.Range("A3")
 eRw = Range("A65535").End(xlUp).Row
 For jJ = eRw To 4 Step -1
   With Cells(jJ, 1)
      If .Value = .Offset(-1).Value And .Offset(, 1).Value = _
         .Offset(-1, 1).Value And .Offset(, 2) = .Offset(-1, 2) Then
         .Resize(, 3).Value = ""
      End If
   End With
Next
End Sub

(*) Mình thường khai báo 1 biến nào đó gồm ít nhất là 2 chữ cái, để trong đó ít nhất có 1 chữ viết hoa & 1 chữ viết thường; Và mình hết sức tránh dùng chữ cái 'n' mà hay dùng jj, ww zz, & ff vì để các fím có độ hư đồng đều. (Khà, khà,. . .)

(*) Bỡi nút lệnh của bạn đang ở Sheet2, nên cũng không cần thiết ới gọi trang tính này trong các câu lệnh nữa;

(*) Kể từ sau dòng 4 ta có thể xài lại biến eRw với việc gán cho nó 1 trị mới. Vì thật ra biến n của bạn cũng không dùng nữa kể từ sau dòng lệnh này; Tất nhiên sẽ gây cho ta 1 chút rắc rối cần thiết nào đó trong việc quản lí các biến của mình. Lâu dần ta sẽ có thói quen quản các biến trong những chương trình vĩ đại sau này của bạn.

Rất vui nếu được bạn cho đây là những lời khuyên không vô bổ.
 
Lần chỉnh sửa cuối:
Em có câu hỏi này, có thể là hỏi trước vấn đề học (nhưng em đã làm rồi), xin thầy Tuân chỉ dùm em nha:
Trong việc Copy từ Sheet1 sang Sheet2 thì em đã thiết lập 2 đoạn code (Thử theo 2 cách): thì 1 trong 2 đoạn code đó có đoạn không chạy được đúng ý muốn của em. Đoạn kia thì chạy tốt. cụ thể là đoạn này:
PHP:
Sub CopyDL() 'Sao cai nay khong chay duoc theo y muon nhi!?
Dim n As Long, i As Long, m As Long
    Application.ScreenUpdating = False
    Sheet2.Range("A3:I65535").Clear
    n = Sheet1.Range("I65535").End(xlUp).Row
    Sheet1.Range("A3:I" & n).Copy Destination:=Sheet2.Range("A3")
    With Sheet2
    m = .Range("A65535").End(xlUp).Row
        For i = m To 2 Step -1
            If .Cells(i, 1) & .Cells(1, 2) & .Cells(i, 3) = .Cells(i - 1, 1) & _
            .Cells(i - 1, 2) & .Cells(i - 1, 3) Then .Cells(i, 1).Resize(, 3) = Empty
 
        Next
    End With
End Sub

Em đã kiểm tra kỹ mà chưa phát hiện ra lỗi.

Ý đồ thì tốt nhưng thực hiện chưa tốt (ý kiến cá nhân). Ngọc đi trước xa bài học quá thì lớp mình mấy ai thảo luận được đây.
Nếu là thảo luận trong phạm vi lớp học thì hãy mở đầu bằng những gì đã được học ở bài học đầu tiên.
Tớ nghĩ ngay bài học đầu tiên ta cũng có quá nhiều điều phải hỏi và thảo luận rồi
Chẳng qua, chúng ta chưa làm đi làm lại các tình huống xoay quanh bài học đó thôi.

Thảo luận + Ghóp ý + Phê Bình = Cùng tiến bộ
 
Sai chỗ này nè
If .Cells(i, 1) & .Cells(i, 2) & .Cells(i, 3)
I chứ hổng phải 1 à nha
Híc
Ủa, quên, mình hổng có học có sửa được hông "zị"

Đúng là cháu sơ xuất quá (lỗi không đáng có!?)! Hi.......... (Mọi người đừng cười nha!!)
 
Lần chỉnh sửa cuối:
Bài số 2 em không hiểu đề, bác nào giải thích hộ em với ạ
" Tạo 1 macro sắp xếp một vùng dữ liệu"

Có nghĩa là: Bạn tạo một vùng dữ liệu bao gồm các số lớn bé linh tinh không theo thứ tự trong cột. Sau đó sắp xếp chúng lại theo thứ tự.
Từ lớn đến bé hoặc từ bé đến lớn.
 

File đính kèm

PHP:
Sub CopyDL()
Dim eRw As Long, jJ As Long

Application.ScreenUpdating = False
Range("A3:I65535").Clear
eRw = Sheet1.Range("I65535").End(xlUp).Row
4 Sheet1.Range("A3:I" & eRw).Copy Destination:=Sheet2.Range("A3")
eRw = Range("A65535").End(xlUp).Row
For jJ = eRw To 4 Step -1
With Cells(jJ, 1)
If .Value = .Offset(-1).Value And .Offset(, 1).Value = _
.Offset(-1, 1).Value And .Offset(, 2) = .Offset(-1, 2) Then
.Resize(, 3).Value = ""
End If
End With
Next
End Sub

(*) Mình thường khai báo 1 biến nào đó gồm ít nhất là 2 chữ cái, để trong đó ít nhất có 1 chữ viết hoa & 1 chữ viết thường; Và mình hết sức tránh dùng chữ cái 'n' mà hay dùng jj, ww zz, & ff vì để các fím có độ hư đồng đều. (Khà, khà,. . .)

(*) Bỡi nút lệnh của bạn đang ở Sheet2, nên cũng không cần thiết ới gọi trang tính này trong các câu lệnh nữa;

(*) Kể từ sau dòng 4 ta có thể xài lại biến eRw với việc gán cho nó 1 trị mới. Vì thật ra biến n của bạn cũng không dùng nữa kể từ sau dòng lệnh này; Tất nhiên sẽ gây cho ta 1 chút rắc rối cần thiết nào đó trong việc quản lí các biến của mình. Lâu dần ta sẽ có thói quen quản các biến trong những chương trình vĩ đại sau này của bạn.

Rất vui nếu được bạn cho đây là những lời khuyên không vô bổ.

Cám ơn những ý kiến đóng góp của thầy Chanh@ thật bổ ích!
 
Câu hỏi: Tại sao khi copy sheet1 sang Sheet1(2) này thì 4 macro (MC) đã được tạo từ khi ở Sheet1 chỉ có 2 cái kẻ khung và bỏ kẻ khung chạy
Còn 2 cái MC sắp xếp không chạy
Câu này bạn huongchuoi hỏi, mình chỉ trả lời được như thế này thôi vì:
Khi MC chạy nó mặc định tạo: ActiveWorkbook.Worksheets("Sheet1")
Nếu nó tạo là : Activesheet
Thì thì 2 MC sắp xếp sẽ chạy được khi copy sang Sheet1(2)
Còn tại sao bác Bill không làm như thế khi tạo 2 MC định dạng khung và nền thì mình không hiểu.

Nhờ các bạn và thầy giáo giải thích giúp!
 

File đính kèm

Câu hỏi: Tại sao khi copy sheet1 sang Sheet1(2) này thì 4 macro (MC) đã được tạo từ khi ở Sheet1 chỉ có 2 cái kẻ khung và bỏ kẻ khung chạy
Còn 2 cái MC sắp xếp không chạy
Câu này bạn huongchuoi hỏi, mình chỉ trả lời được như thế này thôi vì:
Khi MC chạy nó mặc định tạo: ActiveWorkbook.Worksheets("Sheet1")
Nếu nó tạo là : Activesheet
Thì thì 2 MC sắp xếp sẽ chạy được khi copy sang Sheet1(2)
Còn tại sao bác Bill không làm như thế khi tạo 2 MC định dạng khung và nền thì mình không hiểu.

Nhờ các bạn và thầy giáo giải thích giúp!

Căn cứ vào đâu mà bạn xác định nó không chạy? Nó vẫn chạy mà vẫn bon bon là đằng khác. Bạn cố định nó vào Sheet1 rồi nên nó chỉ chơi với Sh1, bạn thay đổi trật dòng Sh1 rồi chạy code để kiểm tra xem. Giờ muốn chạy Sh khác phải tìm cách thay đổi Sh1 bằng chỉ định hay gán luôn Sh hiện hành
 
Căn cứ vào đâu mà bạn xác định nó không chạy? Nó vẫn chạy mà vẫn bon bon là đằng khác. Bạn cố định nó vào Sheet1 rồi nên nó chỉ chơi với Sh1, bạn thay đổi trật dòng Sh1 rồi chạy code để kiểm tra xem. Giờ muốn chạy Sh khác phải tìm cách thay đổi Sh1 bằng chỉ định hay gán luôn Sh hiện hành
Thì Em đang bảo là không đổi lại là Activesheet thì nó không chạy là gì.
Khi tạo MC tự động có những hành động (từ này có vẻ không chuẩn lắm) bị ấn định cố định tên Sh và có những cái thì không.
2 Cái MC sắp xếp không chạy do bị ấn định là Sheet1 nên không chạy trên Sheet1(2)
2 Cái định dạng kẻ khung, và tô nền vẫn chạy trên ca Sheest1 và Sheet1(2) do không bị ấn định sh khi MC khởi tạo nó ở Sheet1

Tại sao? Cùng là ghi MC tự động cái thì bị gán name Sh cố định cái thì không ?
 
Lần chỉnh sửa cuối:
Thì Em đang bảo là không đổi lại là Activesheet thì nó không chạy là gì.
Khi tạo MC tự động có những hành động (từ này có vẻ không chuẩn lắm) bị ấn định cố định tên Sh và có những cái thì không.
2 Cái MC sắp xếp không chạy do bị ấn định là Sheet1 nên không chạy trên Sheet1(2)
2 Cái định dạng kẻ khung, và tô nền vẫn chạy trên ca Sheest1 và Sheet1(2) do không bị ấn định sh khi MC khởi tạo nó ở Sheet1

Tại sao? Cùng là ghi MC tự động cái thì bị gán name Sh cố định cái thì không ?

Em không hiểu bài của huongchuoi lắm! Đây là ví dụ em làm: Em chỉ sắp xếp và kẻ đường viền thôi.
Lưu ý: Nếu khi muốn copy sang Sheet khác (mà vẫn để đúng vị trì cũ) thì chạy tốt. Cón nếu muốn thay đổi vị trí khác thì anh phải kiểm tra lại địa chỉ để sắp xếp nha!
 

File đính kèm

Chỉ là câu hỏi này thôi mà Tại sao? Cùng là ghi MC tự động cái thì bị gán name Sh cố định cái thì không ?
 
Mọi người hãy làm bài tập đi nhé để buối tối đi học có thắc mắc nào để hỏi các thành viên hoặc thầy giáo!
 
So sánh 2 đoạn code được trích ra từ file của mình và của Ngọc
Đoạn của NGọc

Selection.Sort Key1:=Range("D3"), Order1:=xlDescending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal

Đoạn của Minh:

ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A5"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal

Trong file đã gửi phía trên.

Nếu như cùng thao tác ghi MC giống nhau mà cho 2 đoạn Code khác nhau có lẽ sử dụng Office khác nhau. Mình dùng 2007
Vì đoạn code của Ngọc không ấn định nameSheet nên sang Sheet khác chạy vô tư là đúng.
Mình vẫn là câu thắc mắc như trên Tại sao? Cùng là ghi MC tự động cái thì bị gán name Sh cố định cái thì không ?
 
So sánh 2 đoạn code được trích ra từ file của mình và của Ngọc
Đoạn của NGọc

Selection.Sort Key1:=Range("D3"), Order1:=xlDescending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal

Đoạn của Minh:

ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A5"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal

Trong file đã gửi phía trên.

Nếu như cùng thao tác ghi MC giống nhau mà cho 2 đoạn Code khác nhau có lẽ sử dụng Office khác nhau. Mình dùng 2007
Vì đoạn code của Ngọc không ấn định nameSheet nên sang Sheet khác chạy vô tư là đúng.
Mình vẫn là câu thắc mắc như trên Tại sao? Cùng là ghi MC tự động cái thì bị gán name Sh cố định cái thì không ?

Câu hỏi này phải nhờ đến thầy Tuân thôi. Em cũng không hiểu lắm đâu.
 
Hai người cùng Record nhưng khác nhau: Ngọc Bôi chọn vùng dữ liệu còn Minh thì không? (Các bạn Test xem có đúng vậy không)
 
Hỏi về cách sắp xếp tự động

Em đã xem file của anh Minh và anh Ngọc nhưng em thấy việc sắp xếp chỉ được ở những vùng đã chọn khi ghi macro mà không áp dụng được với vùng khác (bất kỳ) mình tạo ra sau đó (em có gửi file đính kèm). Mong thầy giáo và các anh chị giải đáp giúp!
 

File đính kèm

Em đã xem file của anh Minh và anh Ngọc nhưng em thấy việc sắp xếp chỉ được ở những vùng đã chọn khi ghi macro mà không áp dụng được với vùng khác (bất kỳ) mình tạo ra sau đó (em có gửi file đính kèm). Mong thầy giáo và các anh chị giải đáp giúp!
Để chọn được vùng bất kỳ Bạn để ý tại D3 ở đoạn code dưới phải tự động cập nhật.
Mã:
......Key1:=Range([COLOR=red]"D3"[/COLOR])
Bạn có thể thay đoạn code trên bằng đoạn code sau nó sẽ tự động tìm vùng chọn của Bạn:
Mã:
......Key1:=Range([COLOR=red]Cells(Selection.Row,Selection.Column).Address[/COLOR])
 

File đính kèm

Em làm được rồi nhưng làm sao để không hiện cái viền màu đỏ khi chọn ah?
 
Em làm được rồi nhưng làm sao để không hiện cái viền màu đỏ khi chọn ah?
Chúc mừng bạn! MC làm như vậy nhưng mình cũng phải hiểu là từng đoạn code trong đó nó thực hiện cái gì bạn ah
Tất nhiên với trình của AE mình bây giờ không thể biết tường tận thì cũng nên biết
Chức năng sắp xếp nó chỉ cần đoạn này

Sub Sapxep()
Selection.Sort Key1:=Range(Cells(Selection.Row,Selection.Column).Address), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
' Đã thay theo gợi ý của bác minhcong

Bạn chia cửa sổ Excel và VBE làm hai nửa màn hình. Sau đó ghi MC sẽ thấy MC nó làm gì với mỗi hành động của ta làm.
Như vậy, các hành động thừa ta sẽ xoá bỏ bớt đi. VD: trong Code trên. Bạn chỉ cần sắp xếp thì xoá bỏ các đoạn Code tô viền của ô đi.
Với việc chia màn hình ra thế này để xem, sửa, chạy thử… xem dc ngay kết quả của Excel làm khi ta tác động vào Code.

Mình thấy cách làm này rất hay mình muốn chia sẻ với tất cả mọi người mới học như mình.
 

File đính kèm

  • chia cua so.jpg
    chia cua so.jpg
    14.4 KB · Đọc: 86
Lần chỉnh sửa cuối:
Em làm được rồi nhưng làm sao để không hiện cái viền màu đỏ khi chọn ah?

Để không hiện đường viền thì bạn sửa lại code chút là được mà. Bạn xem lại file đính kèm nha! Mình đã bỏ đương viền rồi đó Hoàn.

(Khi làm chưa thấy bài của anh Minh. Post rồi mới thấy.Hi.......hi.... "Lại dụng hàng rồi")
 

File đính kèm

Lần chỉnh sửa cuối:
Đây là ví dụ bài tập mà buổi học tối qua thầy giáo cho. Mình đã làm và giờ mình post lên để mọi người tham khảo nha!
 

File đính kèm

Đây là ví dụ bài tập mà buổi học tối qua thầy giáo cho. Mình đã làm và giờ mình post lên để mọi người tham khảo nha!
Cám ơn bạn nhiều. Sao bạn không đưa yêu cầu mà đưa đáp án không à. Mới học hết buổi thứ 2 mà bài tập có vẻ khó.
 
Đây là ví dụ bài tập mà buổi học tối qua thầy giáo cho. Mình đã làm và giờ mình post lên để mọi người tham khảo nha!
Mình có góp ý nhỏ với Ngọc nhé!
Tất cả các trường hợp có thưởng đều có điều kiện chung là: Ngaycong >=20 và Giadinh = "Co" -> Vậy sao Bạn không gộp nó thành điều kiện chung rồi dùng IF cho trường hợp còn lại là chức vụ thôi.
Đại loại như vầy:
Mã:
Function Thuong(ByVal CVu As String, NgCong As Long, GDinh As String) As String
    If NgCong >= 20 And GDinh = "Co" Then
       If CVu = "GD" Then Thuong = "Xe may Attila"
       If CVu = "PGD" Then Thuong = "Xe may Jupiter"
       If CVu = "TP" Then Thuong = "Xe may Wave anpha"
       If CVu = "NV" Then Thuong = "Bo hoa tuoi"
    Else
       Thuong = "That dang tiec!"
    End If
End Function
Cho Mình tham gia giải với nhé! Trình đo VBA Mình còn kém lắm, tự học là chính, đây là điều kiện tốt...hè...hè
 

File đính kèm

Lần chỉnh sửa cuối:
Mình có góp ý nhỏ với Ngọc nhé!
Tất cả các trường hợp có thưởng đều có điều kiện chung là: Ngaycong >=20 và Giadinh = "Co" -> Vậy sao Bạn không gộp nó thành điều kiện chung rồi dùng IF cho trường hợp còn lại là chức vụ thôi.
Đại loại như vầy:
Mã:
Function Thuong(ByVal CVu As String, NgCong As Long, GDinh As String) As String
If NgCong >= 20 And GDinh = "Co" Then
If CVu = "GD" Then Thuong = "Xe may Attila"
If CVu = "PGD" Then Thuong = "Xe may Jupiter"
If CVu = "TP" Then Thuong = "Xe may Wave anpha"
If CVu = "NV" Then Thuong = "Bo hoa tuoi"
Else
Thuong = "That dang tiec!"
End If
End Function
Cho Mình tham gia giải với nhé! Trình đo VBA Mình còn kém lắm, tự học là chính, đây là điều kiện tốt...hè...hè

Dạ, cám ơn anh! Em cũng làm được như vậy rồi. Nhưng tại lớp em còn có nhưng người mới nữa nên em đưa bài làm như vậy để mọi người tiếp thu dần dần anh ah!
Một lần nữa cám ơn anh Minh Công!
 
Đây là ví dụ bài tập mà buổi học tối qua thầy giáo cho. Mình đã làm và giờ mình post lên để mọi người tham khảo nha!
Tôi thấy code của bạn:
PHP:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
    If (sChucVu = "GD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Attila"
    ElseIf (sChucVu = "PGD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Jupiter"
    ElseIf (sChucVu = "TP") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Wave anpha"
    ElseIf (sChucVu = "NV") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Bo hoa tuoi"
    Else
        TinhThuong = "That dang tiec!"
    End If
End Function
Để ý dòng nào cũng có điều kiện (lNgayCong >= 20) And (sGiaDinh = "Co") vậy sao không đưa nó lên đầu cùng
Kiểu vầy:
PHP:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  TinhThuong = "That dang tiec!"
  If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
    If sChucVu = "GD" Then TinhThuong = "Xe may Attila"
    If sChucVu = "PGD" Then TinhThuong = "Xe may Jupiter"
    If sChucVu = "TP" Then TinhThuong = "Xe may Wave anpha"
    If sChucVu = "NV" Then TinhThuong = "Bo hoa tuoi"
  End If
End Function
Có gọn hơn không?
Ngoài ra còn có thể dùng Select Case thay cho IF
---------------------------
Dạ, cám ơn anh! Em cũng làm được như vậy rồi. Nhưng tại lớp em còn có nhưng người mới nữa nên em đưa bài làm như vậy để mọi người tiếp thu dần dần anh ah!
Một lần nữa cám ơn anh Minh Công!
Với người mới, cần tiếp thu dần thì càng phải dùng code dễ hiểu nhất
Tôi cho rằng code của bạn khi diễn giải sẽ khó hiểu hơn ấy chứ
Ẹc... Ẹc...
 
Lần chỉnh sửa cuối:
Mình cũng tham gia tí nhé! Thấy Hàm TinhThuong này mình thử làm Select Case:
PHP:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
    Select Case sChucVu
      Case "GD": TinhThuong = "Xe may Attila"
      Case "PGD": TinhThuong = "Xe may Jupiter"
      Case "TP": TinhThuong = "Xe may Wave anpha"
      Case "NV": TinhThuong = "Bo hoa tuoi"
      Case Else: TinhThuong = "That dang tiec!"
    End Select
  End If
End Function

Hình như chưa chuẩn, như thế này mới đúng:

PHP:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  TinhThuong = "That dang tiec!"
  If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
    Select Case sChucVu
      Case "GD": TinhThuong = "Xe may Attila"
      Case "PGD": TinhThuong = "Xe may Jupiter"
      Case "TP": TinhThuong = "Xe may Wave anpha"
      Case "NV": TinhThuong = "Bo hoa tuoi"
    End Select
  End If
End Function
 
Lần chỉnh sửa cuối:
Bài viết của bác nud
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
TinhThuong = "That dang tiec!"
If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
If sChucVu = "GD" Then TinhThuong = "Xe may Attila"
If sChucVu = "PGD" Then TinhThuong = "Xe may Jupiter"
If sChucVu = "TP" Then TinhThuong = "Xe may Wave anpha"
If sChucVu = "NV" Then TinhThuong = "Bo hoa tuoi"
End If
End Function
va minhcong thực sự là sáng tạo (trong khuôn khổ lớp học của bọn E) còn của learnig_Excel thì cấu trúc Select case bọn E chưa học tới
Rất cám ơn các bác đã nhiệt tình tham gia .
 
Mình cũng ngứa chưn tay, thêm 1 món cho lạ miệng

PHP:
Option Explicit
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  Const GPE As String = "PGDTPNV"

  If lNgayCong >= 20 And sGiaDinh = "Co" And InStr(GPE, sChucVu) Then
      TinhThuong = Switch(sChucVu = "GD", "Xe may Attila", sChucVu = "PGD", "Xe may Jupiter" _
            , sChucVu = "TP", "Xe may Wave anpha", sChucVu = "NV", "Bo hoa tuoi")
  ElseIf Not InStr(GPE, sChucVu) Then
      TinhThuong = "That dang tiec!"
  End If
End Function
 
PHP:
Option Explicit
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
Const GPE As String = "PGDTPNV"

If lNgayCong >= 20 And sGiaDinh = "Co" And InStr(GPE, sChucVu) Then
TinhThuong = Switch(sChucVu = "GD", "Xe may Attila", sChucVu = "PGD", "Xe may Jupiter" _
, sChucVu = "TP", "Xe may Wave anpha", sChucVu = "NV", "Bo hoa tuoi")
ElseIf Not InStr(GPE, sChucVu) Then
TinhThuong = "That dang tiec!"
End If
End Function

Da, code của anh thì OK rồi.Nhưng cho em hỏi thêm về cấu trúc Switch(..) và ý nghĩa nhé!?
 
E rằng fóng lao fải theo lao thôi.

Trước tiên, Switch() là 1 hàm của VBA giống như hàm Choose(jJ,"1","1A","@C",. . .) cũng trong VBA

Nhưng hàm Choose(. . .), thì trị jJ đó fải là kiểu Byte, hay Integer
Còn hàm Switch() như bạn thấy nó có thề xài với tham biến nhiều kiểu dữ liệu khác nhau

Có lúc mình đã thử hơn 100 trị Jj trong hàm nó vẫn không kêu ca chi hết.

Thí dụ: GPE= Switch(jJ<3,0 , Jj=5, 3,. . . . )

Bạn có thể tìm hiểu thêm lúc rỗi trong fần trợ giúp của CS VBE, nói nhiều hơn ở đây e không fải chổ.

Thân ái.
 
Dùng lệnh IF..THEN sao cho hiệu quả

Cấu trúc IF có các dạng

Dạng 1:


Mã:
IF btLogic Then
    Làm gì đó khi btLogic = True
End If

Dạng 2:

Mã:
IF btLogic Then
    Làm gì đó khi btLogic = True
Else
    Làm gì đó khi btLogic = False
End If

Dạng 3:
Mã:
IF btLogic1 Then
    Làm gì đó khi btLogic1 = True
ElseIF btLogic2 Then
    Làm gì đó khi btLogic2 = True
...
ElseIF btLogicN Then
    Làm gì đó khi btLogicN = True
Else
    Làm gì đó khi tất cả các btLogic1,2,...N đều = False
End If

Chúng ta lưu ý các vấn đề:
1. Có thể không cần dùng nhánh Else nếu ta không quan tâm tới các trường hợp không thỏa mãn điều kiện (các btLogic đều = False).
2. Có If thì phải có End If để kết thúc khối lệnh If. Nhánh Else, ElseIf thì không cần End If. Nếu lệnh If...Then... trên một dòng thì không dùng End If.
3. Biểu thức logic (btLogic) là gì?
Biểu thức logic là một phép toán so sánh mà kết quả của nó trả về giá trị kiểu Logic - Boolean tức là chỉ trả về 1 trong 2 giá trị True, False

Phép toán so sánh:
= bằng
> lớn hơn
>= lớn hơn hoặc bằng
< nhỏ hơn
<= nhỏ hơn hoặc bằng
<> khác (không bằng)
Like -->như là :học sau
Is -->là: học sau

Xây dựng phép toán so sánh

A so soánh với B. Ví dụ A = B, A > B, A>= B ,....

Viết hàm trả lời theo các tình huống của các ví dụ dưới đây.
Ví dụ 1: Nếu tuổi lớn hơn hoặc bằng 18 thì trả lời được phép lập gia đình

Mã:
Function KiemTra(Byval lTuoi As Long) As String
     If lTuoi >= 18 Then
         KiemTra = "Được phép lập gia đình"
     End If
End Function

Ví dụ 2: Nếu tuổi lớn hơn hoặc bằng 18 thì trả lời "Được phép lập gia đình", trường hợp khác trả lời "Không đủ tuổi lập gia đình"

Mã:
Function KiemTra(Byval lTuoi As Long) As String
     If lTuoi >= 18 Then
         KiemTra = "Được phép lập gia đình"
     Else
         KiemTra = "Không đủ tuổi lập gia đình"
     End If
End Function

Ví dụ 3: Nếu tuổi lớn hơn hoặc bằng 18 và giới tính là Nam thì trả lời "Được phép lấy vợ"
Nếu tuổi lớn hơn hoặc bằng 18 và giới tính là Nữ thì trả lời "Được phép lấy chồng"
Trường hợp khác trả lời "Không được phép lập gia đình"
Mã:
Function KiemTra(Byval lTuoi As Long, Byval sGioiTinh As String) As String
     If lTuoi >= 18 Then
         If sGioiTinh = "Nam" Then
              KiemTra = "Được phép lấy vợ"
         ElseIf sGioiTinh = "Nữ"   Then
              KiemTra = "Được phép lấy chồng"
         End If
     Else
         KiemTra = "Không được phép lập gia đình"
     End If
End Function

Một biểu thức logic có thể là sự kết hợp của nhiều cặp logic khác, có thể dùng các phép hợp: And - và; Or - hoặc; Not (btLogic) - phủ định btLogic
Vẫn ví dụ trên, ta có thể viết cách khác

Mã:
Function KiemTra(Byval lTuoi As Long, Byval sGioiTinh As String) As String
     If (lTuoi >= 18) And (sGioiTinh = "Nam") Then
         KiemTra = "Được phép lấy vợ"
     ElseIf (lTuoi >= 18) And (sGioiTinh = "Nữ") Then
         KiemTra = "Được phép lấy vợ"       
     Else
         KiemTra = "Không được phép lập gia đình"
     End If
End Function

Vẫn ví dụ trên, chỉ cần tuổi >=18 còn giới tính Nam hoặc Nữ thì trả lời "Được phép lập gia đình", trường hợp khác trả lời "Không được phép lập gia đình"

Mã:
Function KiemTra(Byval lTuoi As Long, Byval sGioiTinh As String) As String
     If (lTuoi >= 18) And ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) Then
         KiemTra = "Được phép lập gia đình"
     Else
         KiemTra = "Không được phép lập gia đình"
     End If
End Function

Qua ví dụ trên chúng ta phát triển biểu thức logic phức tạp hơn. Chúng ta chú ý tới ngoặc mở "(" và ngoặc đóng ")" cho mỗi biểu thức logic.
btlogic (lTuoi >= 18) được so sánh và/And với cả btlogic ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ"))
btlogic ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) trả về đúng nếu ít nhất một cặp logic trong đó đúng, bằng sai khi tất cả các cặp logic trong đó sai--->Giống hàm OR trong Excel.

VB (Visual Basic) thực hiện việc tính toán từ trái sang phải, trong ngoặc trước ngoài ngoặc sau. Có nghĩa là:
(lTuoi >= 18) được duyệt đầu tiên sau đó mới duyệt đến ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) ,
Trong ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) nó lại duyệt (sGioiTinh = "Nam") rồi mới đến (sGioiTinh = "Nữ")

Chúng ta cần am hiểu điều này thật sâu sắc để sau này xây dựng những biểu thức logic phức tạp hơn nhiều, cần biết cái gì được tính trước và cái gì thì sau trong VB.

Nói về kết hợp Or - Hoặc
btLogic ((sGioiTinh = "Nam") Or (sGioiTinh = "Nữ")) trả về đúng khi ít nhất một btLogic trong đó đúng. Có nghĩa là khi VB duyệt (sGioiTinh = "Nam") mà là đúng thì thôi không duyệt btLogic (sGioiTinh = "Nữ") nữa vì kết quả biểu thức này chắc chắn là đúng cho dù các btLogic đứng sau đó kết quả là gì chăng nữa. Nhưng VB vẫn tính tất cả-->Đây là điều rất dở của ngôn ngữ VB vì không đảm bảo tính tối ưu trong tính toán, suy diễn, phải tính hết lẽ ra chỉ phải tính 1==>Tốc độ ứng dụng chạy chậm!

Viết lệnh If sao cho máy tính giảm công việc tính toán ==> Tối ưu tính toán ==> Tốc độ ứng dụng nhanh!

Ví dụ 4: Hàm đọc số thành chữ, từ 1->9
Cách 1:
Mã:
Function SoThanhChu(Byval lSo1_9 As Long) As String
     SoThanhChu = "Không biết"
     If (lSo1_9 = 1)  Then SoThanhChu = "Một"
     If (lSo1_9 = 2)  Then SoThanhChu = "Hai"
     If (lSo1_9 = 3)  Then SoThanhChu = "Ba"
     If (lSo1_9 = 4)  Then SoThanhChu = "Bốn"
     If (lSo1_9 = 5)  Then SoThanhChu = "Năm"
     If (lSo1_9 = 6)  Then SoThanhChu = "Sáu"
     If (lSo1_9 = 7)  Then SoThanhChu = "Bảy"
     If (lSo1_9 = 8)  Then SoThanhChu = "Tám"
     If (lSo1_9 = 9)  Then SoThanhChu = "Chín"
End Function

Tôi nhắc lại là nếu lệnh If được viết trên cùng một dòng thì không cần End If

Nhận xét cách 1:
Khi thoả mãn một btLogic và nhận giá trị thì VB lại xuống dòng tiếp theo để duyệt và tính tiếp, số lần tính toán là 10 lần! Lẽ ra nó chỉnh phải tính 1 lần rồi thoát!
Vậy cách 1 không tốt ==>KHÔNG ĐƯỢC DÙNG IF KIỂU NÀY!!!

Cách 2:
Mã:
Function SoThanhChu(Byval lSo1_9 As Long) As String
     If (lSo1_9 = 1)  Then 
         SoThanhChu = "Một"
     ElseIf (lSo1_9 = 2)  Then 
         SoThanhChu = "Hai"
     ElseIf (lSo1_9 = 3)  Then 
         SoThanhChu = "Ba"
     ElseIf (lSo1_9 = 4)  Then 
         SoThanhChu = "Bốn"
     ElseIf (lSo1_9 = 5)  Then 
         SoThanhChu = "Năm"
     ElseIf (lSo1_9 = 6)  Then 
         SoThanhChu = "Sáu"
     ElseIf (lSo1_9 = 7)  Then 
         SoThanhChu = "Bảy"
     ElseIf (lSo1_9 = 8)  Then 
         SoThanhChu = "Tám"
     ElseIf (lSo1_9 = 9)  Then 
         SoThanhChu = "Chín"
    Else
        SoThanhChu = "Không biết"
    End If
End Function

Nhận xét cách 2:
Khi thoả mãn một btLogic và nhận giá trị thì thoát khỏi hàm mà không duyệt và tính tiếp các logic đúng sau nó. Như vậy số phép tính có thể là từ 1->10, nếu thoả mãn ở dòng thứ 1 thì số phép tính là 1, nếu thoả mãn ở dòng thứ 4 thì số phép tính là 4, ....Như vậy số phép tính và VB phải tính phụ thuốc vào số các btLogic đứng trước không thoả mãn! NÊN DÙNG CÁCH 2 HƠN CÁCH 1!!! (cách 1 dù thế nào cũng phải mất 10 phép tính)

Cách 3:
Mã:
Function SoThanhChu(Byval lSo1_9 As Long) As String
     If (lSo1_9 < 1) Or  (lSo1_9 > 9) Then '//Ngoài khoảng
        SoThanhChu = "Không biết"
     ElseIf (lSo1_9 = 1)  Then 
         SoThanhChu = "Một"
     ElseIf (lSo1_9 = 2)  Then 
         SoThanhChu = "Hai"
     ElseIf (lSo1_9 = 3)  Then 
         SoThanhChu = "Ba"
     ElseIf (lSo1_9 = 4)  Then 
         SoThanhChu = "Bốn"
     ElseIf (lSo1_9 = 5)  Then 
         SoThanhChu = "Năm"
     ElseIf (lSo1_9 = 6)  Then 
         SoThanhChu = "Sáu"
     ElseIf (lSo1_9 = 7)  Then 
         SoThanhChu = "Bảy"
     ElseIf (lSo1_9 = 8)  Then 
         SoThanhChu = "Tám"
     ElseIf (lSo1_9 = 9)  Then 
         SoThanhChu = "Chín"
    End If
End Function
Nhận xét cách 3:
Khi điều kiện không thoả mãn (lSo1_9 ngoài khoảng xét) thì thoát khỏi hàm và không duyệt phép tính nào nữa, số phép tính là 1. Cũng là trường hợp không thoả mãn này mà ở cách 2 thì số phép tính 10. Vậy NÊN DÙNG CÁCH 3 HƠN CÁCH 2!!!

Như vậy chúng ta đã biết, để tối ưu trong tính toán ta nên dùng cách 3.

Trong một ứng dụng tổng hợp, chúng ta có rất nhiều phép tính, với sự am hiểu hãy tối ưu nó để tiết kiệm năng lực của máy và tăng tốc độ ứng dụng.

Còn một số vấn đề khác liên quan tới hàm If cũng như xây dựng biểu thức logic với phép so sánh: Not, Like, Is tôi sẽ phân tích sau. Nội dung chỉ nằm trong phạm vi đã được học của lớp VBA căn bản, các vấn để nâng cao hơn sẽ trình bày ở các bài học sau này.

Nhân bài giảng về cấu trúc If của lớp VBA căn bản tại Hà Nội, tôi viết bài phân tính cấu trúc cũng như cách ứng dụng nó để chúng ta hiểu sâu sắc về nó cũng như ứng dụng trong các trường hợp được linh hoạt, đảm bảo tính tối ưu.

Ở lớp VBA này, tôi muốn hướng dẫn các bạn để có kiến thức nền tảng về ngôn ngữ VB từ đó chúng ta tự nâng cao kiến thức sau này.

Cảm ơn các thành viên đã cùng chia sẻ kinh nghiệm!
 
Lần chỉnh sửa cuối:
Đây là ví dụ bài tập mà buổi học tối qua thầy giáo cho. Mình đã làm và giờ mình post lên để mọi người tham khảo nha!
Mã:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
    If (sChucVu = "GD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Attila"
    ElseIf (sChucVu = "PGD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Jupiter"
    ElseIf (sChucVu = "TP") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Wave anpha"
    ElseIf (sChucVu = "NV") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Bo hoa tuoi"
    Else
        TinhThuong = "That dang tiec!"
    End If
End Function


Mới học viết được như vậy là khá đấy Ngọc à. Qua hàm Ngọc viết, tôi có nhận xét thế này.

+ Về cách đặt tên tham số đúng quy ước ==>Tốt.
+ Về định dạng code đúng theo quy ước ==> Tốt.
+ Trình bày cấu trúc If đúng ==> Tốt.
+ Khai báo kiểu giá trị, tham số sGiaDinh As String nên là bGiaDinh As Boolean vì tham số này chỉ nhận 1 trong hai giá trị True, False mà thôi.
+ Khai báo tham số thiếu Byval ==> Không chuẩn. "Làm gì đều cần có lý do" :).

Qua bài phân tích hàm If của tôi ở trên, Ngọc và các bạn khác hãy chỉnh lại cho tối ưu hơn?
 
Qua đây để nói thêm đây chỉ là bài học VBA căn bản ở lớp của Hà Nội vì vậy các cao thủ không nên đưa ra các ví dụ rút gọn cao siêu dễ dẫn đến " Rối loạn tiêu hoá"
 
Mình nghĩ cũng nên đưa ra các giải thuật hay để các học viên tham khảo giống như bài tập bình thường và bài nâng cao vậy. Có như vậy mới khuyến khích vận dụng sáng tạo những cái VBA cung cấp để phục vụ yêu cầu của mình. Ngay như bài này cũng vậy, Ngọc và các bạn cũng tham khảo hàm này của mình xem sao? Vậy là ít nhất các bạn cũng có 2 cách viết

Mã:
Function TinhThuong1(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  With WorksheetFunction
    If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
      TinhThuong1 = .Index(Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", _
       "Bo hoa tuoi"), .Match(sChucVu, Array("GD", "PGD", "TP", "NV")))
       Else
     TinhThuong1 = "That dang tiec!"
    End If
  End With
End Function
 
Mình nghĩ cũng nên đưa ra các giải thuật hay để các học viên tham khảo giống như bài tập bình thường và bài nâng cao vậy. Có như vậy mới khuyến khích vận dụng sáng tạo những cái VBA cung cấp để phục vụ yêu cầu của mình. Ngay như bài này cũng vậy, Ngọc và các bạn cũng tham khảo hàm này của mình xem sao? Vậy là ít nhất các bạn cũng có 2 cách viết

Mã:
Function TinhThuong1(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  With WorksheetFunction
    If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
      TinhThuong1 = .Index(Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", _
       "Bo hoa tuoi"), .Match(sChucVu, Array("GD", "PGD", "TP", "NV")))
       Else
     TinhThuong1 = "That dang tiec!"
    End If
  End With
End Function
Đã vậy thì làm thêm 1 cách, chả biết có nhanh hơn nhưng nghiên cứu thêm về code cho vui.
PHP:
Function TinhThuongDic(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
Dim iKQ As String, Arr01(), Arr02(), i As Long
Arr01 = Array("GD", "PGD", "TP", "NV")
Arr02 = Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", "Bo hoa tuoi")
If lNgayCong >= 20 And sGiaDinh = "Co" Then
  For i = 0 To UBound(Arr01)
    With CreateObject("Scripting.Dictionary")
      .Add Arr01(i), i
      If .Exists(sChucVu) Then
        iKQ = Arr02(.Item(sChucVu))
        Exit For
      End If
    End With
  Next i
Else
  iKQ = "That dang tiec!"
End If
TinhThuongDic = iKQ
Erase Arr01, Arr02
End Function
Nhưng mà dài quá.
 
Mình nghĩ cũng nên đưa ra các giải thuật hay để các học viên tham khảo giống như bài tập bình thường và bài nâng cao vậy. Có như vậy mới khuyến khích vận dụng sáng tạo những cái VBA cung cấp để phục vụ yêu cầu của mình. Ngay như bài này cũng vậy, Ngọc và các bạn cũng tham khảo hàm này của mình xem sao? Vậy là ít nhất các bạn cũng có 2 cách viết

Mã:
Function TinhThuong1(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  With WorksheetFunction
    If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
      TinhThuong1 = .Index(Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", _
       "Bo hoa tuoi"), .Match(sChucVu, Array("GD", "PGD", "TP", "NV")))
       Else
     TinhThuong1 = "That dang tiec!"
    End If
  End With
End Function

Cảm ơn anh đã chia sẻ. Chắc chắn một điều những học viên mới học đến buổi thứ hai về VBA này mới biết thế nào là Macro, Thủ tục, Hàm, Kiểu giá trị, khai báo biến, Cấu trúc If thì đọc bài của anh không thể hiểu đâu. Anh hãy chia sẻ những giải thuật hay trong phạm vi kiến thức của họ. Ví dụ hiểu sâu sắc về tham số trong hàm, thủ tục? Hiểu sâu sắc về cách xây dựng biểu thức logic,.....Đó là cơ sở để sáng tạo đó. Trong bài của anh có đụng tới việc khai thác đối tượng của Excel là WorksheetFunction và kiến thức về mảng Array. Đến bài học này chắc bài viết này của anh sẽ có ích nhiều cho các học viên. Lúc đó anh cho các ví dụ và phân tích sâu sắc về ứng dụng chúng nhé.
 
Lần chỉnh sửa cuối:
Xin phép chủ topic, xin phép các Thầy, các anh cho em chen ngang chút xíu:

Thật sự mà nói em không biết gì về VBA cả nên khi thấy có topic này cũng hy vọng là mình có thể nắm được những định nghĩa ban đầu cái mà chị HYên gọi là i tờ, nên em theo dõi cũng thường xuyên topic này, em rất thích những bài viết kiểu như bài về IF và có sự phân tích của Thầy Tuân trong topic này. Hỏng biết có thành viên nào đó của lớp học có thể sau mỗi buổi học chịu khó ghi chép và post lại về lý thuyết bài giảng, những ví dụ và cả phần bài tập hôm đó để thành viên khác như em ở xa không có điều kiện tham gia củng có thể học tại đây được không ah.

Chân thành cảm ơn và chúc các anh chị thành công.
 
Trước tiên, em xin cám ơn thầy Tuân đã góp ý dùm em. Thứ 2, em xin cám ơn tất cả các AC ở GPE đã chia sẻ cho em và các thành viên trong lớp học "Lập trình VBA trong Excel" những ví dụ và những lời khuyên thật hữu ích! Tuy lớp học bắt bắt đầu, nhưng các thầy và các AC đã rất nhiệt tình giúp đỡ chúng em. Trong quá trình học, em cũng như các thành viên trong lớp rất mong các thầy và các AC trên GPE chia sẻ cho chúng em thêm về kiến thức VBA nhé!
Một lần nữa, em xin chân thành cám ơn các thầy và các AC trong GPE!
 
Xin phép chủ topic, xin phép các Thầy, các anh cho em chen ngang chút xíu:

Thật sự mà nói em không biết gì về VBA cả nên khi thấy có topic này cũng hy vọng là mình có thể nắm được những định nghĩa ban đầu cái mà chị HYên gọi là i tờ, nên em theo dõi cũng thường xuyên topic này, em rất thích những bài viết kiểu như bài về IF và có sự phân tích của Thầy Tuân trong topic này. Hỏng biết có thành viên nào đó của lớp học có thể sau mỗi buổi học chịu khó ghi chép và post lại về lý thuyết bài giảng, những ví dụ và cả phần bài tập hôm đó để thành viên khác như em ở xa không có điều kiện tham gia củng có thể học tại đây được không ah.

Chân thành cảm ơn và chúc các anh chị thành công.
Em cũng có ý kiến như anh tungnguyen_kt! Việc tạo ra những topic này đúng là rất có ích cho những người mới bắt đầu học. Bản thân Em thì tự mày mò tự học trên sách và trên diễn đàn, thấy cái nào hay là cóp nhặt về nghiên cứu rồi tập hợp lại thành. Trước đây cũng có chuyên đề về vòng lặp For....next của anh Mỹ (PTM) mở
http://www.giaiphapexcel.com/forum/showthread.php?6354-Giới-thiệu-Cơ-bản-về-vòng-lặp-For-.-.-.-next
Cũng như Bài tập về vòng lặp anh Tuấn (NDU) mở
http://www.giaiphapexcel.com/forum/showthread.php?39326-Bài-tập-về-vòng-lặp
Các Anh lại tận tình hướng dẫn, giúp đỡ. các bạn nào mứoi bắt đầu học hay đang học nên thường xuyên theo dõi, tham gia giải các Bài tập mà các Bạn, các anh đưa ra -> nếu không rõ cái gì post lên nhờ giúp đỡ dần dần sẽ quen.
 
Lớp mình nếu ai chưa hiểu lắm về Byval và Byref thì đọc thêm ở đây nhé! Đây là bài của thầy P.T.Hướng viết trên GPE.
 
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
If (sChucVu = "GD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Attila"
ElseIf (sChucVu = "PGD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Jupiter"
ElseIf (sChucVu = "TP") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Xe may Wave anpha"
ElseIf (sChucVu = "NV") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
TinhThuong = "Bo hoa tuoi"
Else
TinhThuong = "That dang tiec!"
End If
End Function

Thầy ơi! E hỏi tý: sChucVu as String có lãng phí không ạ vì nếu chức vụ nằm ngoài "GD, PGD, NV,TP" là đã thực hiện cái này:

Else
TinhThuong = "That dang tiec!"

Điều này có nghĩa, biến sChucVu chỉ cần đặt bé tẹo hoặc interger là ổn (không biết em hiểu vậy có đúng không)

Mọi người cùng cho ý kiến nhé.
 
Lần chỉnh sửa cuối:
"E hỏi tý: sChucVu as String có lãng phí không ạ"

Khai báo như vậy thường người ta gọi là khai báo tường minh & như trên là thấy Tuân khen rồi còn gì;

Còn khai báo khơi khơi í ư?

Tôi sẵn cho bạn 1 vì dụ đây:

Nhà có nhiều loại dao, nào lá cán gỗ, bằng nhựa hoàn toàn, cán bằng nhựa & cán bằng inox;

Khi Sếp chuẩn bị thái thịt & ra lệnh "Đưa tôi con dao"

(*) Lúc vui thì đưa dao cán gỗ thái được thịt;
(*) Lúc buốn thì đưa con dao nhựa ra chơi! Làm gì nhau nào;

Tất nhiên so sánh là khập khiển, nhưng cũng có người nói, khai tường minh sẽ nhanh có đáp án hơn.

& ờ đây là Thầy Tuân không chỉ truyền đạt trí thức không đâu, mà còn truyền thụ cả tri thức nữa đó bạn.



Chân thành chúc Lớp ta thành công mỹ mãn!
 
Khai báo như vậy thường người ta gọi là khai báo tường minh & như trên là thấy Tuân khen rồi còn gì;

Còn khai báo khơi khơi í ư?

Tôi sẵn cho bạn 1 vì dụ đây:

Nhà có nhiều loại dao, nào lá cán gỗ, bằng nhựa hoàn toàn, cán bằng nhựa & cán bằng inox;

Khi Sếp chuẩn bị thái thịt & ra lệnh "Đưa tôi con dao"

(*) Lúc vui thì đưa dao cán gỗ thái được thịt;
(*) Lúc buốn thì đưa con dao nhựa ra chơi! Làm gì nhau nào;

Tất nhiên so sánh là khập khiển, nhưng cũng có người nói, khai tường minh sẽ nhanh có đáp án hơn.

& ờ đây là Thầy Tuân không chỉ truyền đạt trí thức không đâu, mà còn truyền thụ cả tri thức nữa đó bạn.



Chân thành chúc Lớp ta thành công mỹ mãn!

Cám ơn bác. Thế mới hay bấy lâu cách hiểu của em là có vấn đề.
Em cứ nghỉ rằng khai báo trong khoảng hẹp hơn thì rõ hơn và tiết kiệm "tài nguyên hơn" vì thấy Interger nó nhận (-32,768 to 32,767)
Còn String nó nhận (1 to approximately 65,400)
Vì vậy Em lại hiểu khai báo Interger là thu hẹp khoảng lại là "Con dao dùng được" Còn String nó sẽ nhận "con dao bất kỳ"

Em muốn tiến bộ nên không dấu dốt nhờ thầy giáo và các Bác giảng giải thêm để em có thể sáng hơn được chút.

P/s: Đoạn này là em mới sửa thêm.
đáng ra Em phải hiểu Interger nó là kiểu số và String nó là kiểu chuỗi thì có vẻ ổn hơn các bác nhỉ
 
Lần chỉnh sửa cuối:
Mình nghĩ cũng nên đưa ra các giải thuật hay để các học viên tham khảo giống như bài tập bình thường và bài nâng cao vậy. Có như vậy mới khuyến khích vận dụng sáng tạo những cái VBA cung cấp để phục vụ yêu cầu của mình. Ngay như bài này cũng vậy, Ngọc và các bạn cũng tham khảo hàm này của mình xem sao? Vậy là ít nhất các bạn cũng có 2 cách viết

Mã:
Function TinhThuong1(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
  With WorksheetFunction
    If (lNgayCong >= 20) And (sGiaDinh = "Co") Then
      TinhThuong1 = .Index(Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", _
       "Bo hoa tuoi"), .Match(sChucVu, Array("GD", "PGD", "TP", "NV")))
       Else
     TinhThuong1 = "That dang tiec!"
    End If
  End With
End Function
Thiết nghĩ ai biết công thức Excel thì kiến thức này chẳng phải là quá cao siêu (cũng như ta gõ trên cell thôi)
Có điều em nghĩ nếu dùng MATCH thì anh phải bẫy lỗi thôi ----> Mọi trường hợp khiến cho hàm MATCH bị lỗi đều phải trả về kết quả "Thật đáng tiếc"
 
Congminh
Mình có góp ý nhỏ với Ngọc nhé!
Tất cả các trường hợp có thưởng đều có điều kiện chung là: Ngaycong >=20 và Giadinh = "Co" -> Vậy sao Bạn không gộp nó thành điều kiện chung rồi dùng IF cho trường hợp còn lại là chức vụ thôi.
Đại loại như vầy:
Code:
Function Thuong(ByVal CVu As String, NgCong As Long, GDinh As String) As String
If NgCong >= 20 And GDinh = "Co" Then
If CVu = "GD" Then Thuong = "Xe may Attila"
If CVu = "PGD" Then Thuong = "Xe may Jupiter"
If CVu = "TP" Then Thuong = "Xe may Wave anpha"
If CVu = "NV" Then Thuong = "Bo hoa tuoi"
Else
Thuong = "That dang tiec!"
End If
End Function



Ý tưởng này rất hay. cám ơn bác minh công nhé
 
Lần chỉnh sửa cuối:
[
HTML:
[QUOTE][QUOTE][B]Nguyên văn bởi NH_DK  
Đây là ví dụ bài tập mà buổi học tối qua thầy giáo cho. Mình đã làm và giờ mình post lên để mọi người tham khảo nha!
Code:
Function TinhThuong(ByVal sChucVu As String, lNgayCong As Long, sGiaDinh As String) As String
    If (sChucVu = "GD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Attila"
    ElseIf (sChucVu = "PGD") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Jupiter"
    ElseIf (sChucVu = "TP") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Xe may Wave anpha"
    ElseIf (sChucVu = "NV") And (lNgayCong >= 20) And (sGiaDinh = "Co") Then
        TinhThuong = "Bo hoa tuoi"
    Else
        TinhThuong = "That dang tiec!"
    End If
End Function

Mới học viết được như vậy là khá đấy Ngọc à. Qua hàm Ngọc viết, tôi có nhận xét thế này.

+ Về cách đặt tên tham số đúng quy ước ==>Tốt.
+ Về định dạng code đúng theo quy ước ==> Tốt.
+ Trình bày cấu trúc If đúng ==> Tốt.
+ Khai báo kiểu giá trị, tham số sGiaDinh As String nên là bGiaDinh As Boolean vì tham số này chỉ nhận 1 trong hai giá trị True, False mà thôi.
+ Khai báo tham số thiếu Byval ==> Không chuẩn. "Làm gì đều cần có lý do" :).

Qua bài phân tích hàm If của tôi ở trên, Ngọc và các bạn khác hãy chỉnh lại cho tối ưu hơn?[QUOTE][TABLE][B][/B][/TABLE][/QUOTE]][/QUOTE]



thầy ơi, theo em thì nếu muốn dùng kiểu boolean thì trước khi mình chạy lệnh IF mình phải có lệnh gán "có = TRUE", "không=FALSE". nếu ko thì lúc mình viết biểu thức logic thì nó sẽ không hiểu "có" hoặc "không" là gì.
 
Lần chỉnh sửa cuối:
CODE:
Mã:
Option Explicit


Function TienThuong(ByVal sChucVu As String, ByVal iSoNgayCong As Integer, ByVal iSoCon As Integer) As Double
    
    If (iSoNgayCong < 285) Then
        TienThuong = iSoCon * 50000
    
        ElseIf (285 <= iSoNgayCong < 290) Then
            If (sChucVu = "TP") Then
                TienThuong = (iSoNgayCong / 25) * 2000000 + iSoCon * 50000
                ElseIf (sChucVu = "NV") Then
                    TienThuong = (iSoNgayCong / 25) * 1500000 + iSoCon * 50000
            End If
        ElseIf (290 <= iSoNgayCong <= 300) Then
            If (sChucVu = "TP") Then
                TienThuong = (iSoNgayCong / 25) * 2200000 + iSoCon * 50000
                ElseIf (sChucVu = "NV") Then
                    TienThuong = (iSoNgayCong / 25) * 1700000 + iSoCon * 50000
            End If
    End If
      
        
End Function

đây là bài em làm để tính tiền thưởng cuối năm. mong cả nhà chỉ giáo thêm giúp em.
P/S:
 
Lần chỉnh sửa cuối:
đây là bài em làm để tính tiền thưởng cuối năm. mong cả nhà . . .

Bạn xài quá nhiều số không, thật là lãng fí & dễ sai sót;
Nếu Thầy chưa truyền đạt thì xin mạn fép thông báo

Ta nên khai báo 1 hằng số Tr cho trường hợp làm việc với tiền đồng của chúng ta; Khai báo đó là:
Mã:
 Const Tr As Long = 10^6
Sau đó trong chương trình thay vì dòng

Mã:
TienThuong = (iSoNgayCong / 25) * 2000000 + iSoCon * 50000
ta xài

PHP:
TienThuong = (iSoNgayCong / 25) * 2* Tr + iSoCon * 50000
Hãy làm thế với số hàng vạn, nếu trong chương trình xài nhiều số hàng vạn, hay với các số khác . . . .


Chúc vui cuối tuần, khà,khà,. . .
 
Đây là bài của em làm nhưng hình như hơi rườm rà, mong mọi người cho ý kiến ah.
Mã:
Option Explicit

Function Thuong(ByVal sChucVu As String, ByVal iSocon As Integer) As Long
    Dim lThuongCV As Long
    Dim lThuongCon As Long
    If (sChucVu = "GD") Then
    lThuongCV = 2000000
        ElseIf (sChucVu = "PGD") Then
        lThuongCV = 1500000
            ElseIf (sChucVu = "TP") Then
            lThuongCV = 1000000
                ElseIf (sChucVu = "PP") Then
                lThuongCV = 500000
                     ElseIf (sChucVu = "NV") Then
                    lThuongCV = 300000
    End If
    If iSocon = 0 Then
    lThuongCon = 0
        ElseIf iSocon = 1 Then
        lThuongCon = 500000
             ElseIf iSocon = 2 Then
            lThuongCon = 1000000
    End If
    Thuong = lThuongCV + lThuongCon
End Function
 

File đính kèm

Lần chỉnh sửa cuối:
Ngồi rảnh nên "ngứa tay" và đã làm ví dụ đơn gian này để mọi người mới tham khảo thêm.........!!

PHP:
Option Explicit
Public Const App = "Hien thong bao"
Sub TinhTong()
    Dim MyRng As Range
    Dim answer As Double
    Set MyRng = Worksheets("Sheet1").Range("A1:A5")
    answer = Application.WorksheetFunction.Sum(MyRng)
    MsgBox "Ket qua la: " & answer, vbInformation, App
End Sub
 
Đây là bài của em làm nhưng hình như hơi rườm rà, mong mọi người cho ý kiến ah.
Mã:
Option Explicit
 
Function Thuong(ByVal sChucVu As String, ByVal iSocon As Integer) As Long
Dim lThuongCV As Long
Dim lThuongCon As Long
If (sChucVu = "GD") Then
lThuongCV = 2000000
ElseIf (sChucVu = "PGD") Then
lThuongCV = 1500000
ElseIf (sChucVu = "TP") Then
lThuongCV = 1000000
ElseIf (sChucVu = "PP") Then
lThuongCV = 500000
ElseIf (sChucVu = "NV") Then
lThuongCV = 300000
End If
If iSocon = 0 Then
lThuongCon = 0
ElseIf iSocon = 1 Then
lThuongCon = 500000
ElseIf iSocon = 2 Then
lThuongCon = 1000000
End If
Thuong = lThuongCV + lThuongCon
End Function

Bài của Hoàn mình xin chỉnh lại chút thôi nhé:

PHP:
Function Thuong(ByVal sChucVu As String, ByVal iSocon As Integer) As Double
    Dim lThuongCV As Double
    Dim lThuongCon As Double
    If (sChucVu = "GD") Then
        lThuongCV = 2000000
        ElseIf (sChucVu = "PGD") Then lThuongCV = 1500000
        ElseIf (sChucVu = "TP") Then lThuongCV = 1000000
        ElseIf (sChucVu = "PP") Then lThuongCV = 500000
        ElseIf (sChucVu = "NV") Then lThuongCV = 300000
    Else
        lThuongCV = 0
    End If
    If iSocon = 0 Then
        lThuongCon = 0
        ElseIf iSocon = 1 Then lThuongCon = 500000
        ElseIf iSocon = 2 Then lThuongCon = 1000000
    End If
    Thuong = lThuongCV + lThuongCon
End Function
Chúc vui vui.......!!!
 
Lần chỉnh sửa cuối:
Bạn xài quá nhiều số không, thật là lãng fí & dễ sai sót;
Nếu Thầy chưa truyền đạt thì xin mạn fép thông báo

Ta nên khai báo 1 hằng số Tr cho trường hợp làm việc với tiền đồng của chúng ta; Khai báo đó là:
Mã:
 Const Tr As Long = 10^6
Sau đó trong chương trình thay vì dòng

Mã:
TienThuong = (iSoNgayCong / 25) * 2000000 + iSoCon * 50000
ta xài

PHP:
TienThuong = (iSoNgayCong / 25) * 2* Tr + iSoCon * 50000
Hãy làm thế với số hàng vạn, nếu trong chương trình xài nhiều số hàng vạn, hay với các số khác . . . .


Chúc vui cuối tuần, khà,khà,. . .

Khai báo Const thầy Tuân dạy rùi. Chỉ là bọn E chưa biết vận dụng thôi.
Khi làm bài, em cứ phải đếm số 0 để nhập (Vì chưa viết vận dụng)
Thế là lại thêm 1 điều hay.
Thanks bác Hyen17. Em post bài bên dưới bác ngó qua giúp em nhé
 
Lần chỉnh sửa cuối:
Nộp bài buổi học thứ 2 - VBA

E nộp bài. Mong thầy giáo, các bác và các bạn cho ý kiến. Các bác nếu ở trên cao thì nhìn tà tà xuống bên dưới chút nhé. kẻo bọn E tẩu hoả nhập ma, khi đọc code của các bác mất.
 

File đính kèm

PHP:
Option Explicit
Const tr As Long = 10 ^ 6
Function thuong83(ByVal sChucvu As String, ByVal iNgaycong As Integer, ByVal bGioitinh As String)

1 If (sChucvu = "gd") And (iNgaycong < 5) And (bGioitinh = "nu") Or (bGioitinh = "nam") Then
    thuong83 = 0
 ElseIf (sChucvu = "gd") And (iNgaycong > 30) And (bGioitinh = "nu") Then
11        thuong83 = 10 * tr * 2
 ElseIf (sChucvu = "gd") And (iNgaycong > 20) And (iNgaycong <= 30) And (bGioitinh = "nu") Then
   thuong83 = 8 * tr * 2
 ElseIf (sChucvu = "gd") And (iNgaycong >= 15) And (iNgaycong <= 20) And (bGioitinh = "nu") Then
   thuong83 = 5 * tr * 2
 ElseIf (sChucvu = "gd") And (iNgaycong >= 10) And (iNgaycong < 15) And (bGioitinh = "nu") Then
   thuong83 = 3 * tr * 2
 End If

2 If (sChucvu = "tp") And (iNgaycong < 5) And (bGioitinh = "nu") Or (bGioitinh = "nam") Then
    thuong83 = 0
 ElseIf (sChucvu = "tp") And (iNgaycong > 30) And (bGioitinh = "nu") Then
21   thuong83 = 10 * tr * 1.5
 ElseIf (sChucvu = "tp") And (iNgaycong > 20) And (iNgaycong <= 30) And (bGioitinh = "nu") Then
   thuong83 = 8 * tr * 1.5
 ElseIf (sChucvu = "tp") And (iNgaycong >= 15) And (iNgaycong <= 20) And (bGioitinh = "nu") Then
   thuong83 = 5 * tr * 1.5
 ElseIf (sChucvu = "tp") And (iNgaycong >= 10) And (iNgaycong < 15) And (bGioitinh = "nu") Then
   thuong83 = 3 * tr * 1.5
 End If

3 If (sChucvu = "nv") And (iNgaycong < 5) And (bGioitinh = "nu") Or (bGioitinh = "nam") Then
   thuong83 = 0
 ElseIf (sChucvu = "nv") And (iNgaycong > 30) And (bGioitinh = "nu") Then
31   thuong83 = 10 * tr
 ElseIf (sChucvu = "nv") And (iNgaycong > 20) And (iNgaycong <= 30) And (bGioitinh = "nu") Then
   thuong83 = 8 * tr
 ElseIf (sChucvu = "nv") And (iNgaycong >= 15) And (iNgaycong <= 20) And (bGioitinh = "nu") Then
   thuong83 = 5 * tr
 ElseIf (sChucvu = "nv") And (iNgaycong >= 10) And (iNgaycong < 15) And (bGioitinh = "nu") Then
   thuong83 = 3 * tr
 End If
End Function
Mình xin gợi 1 số í như sau:

(*) Tên hàm nên có chữ in & chữ thường, ví dụ Thuong83; (Để tránh lỗi chính tả không đáng có khi gõ nhập tên hàm trong chương trình & đây là thói quen không tồi chút nào)

Khi viết xong hàm, ta thở fào vài fút, sau 1 thời gian nào đó bạn nhìn lại & nghiền ngẫm 1 số vấn đề như sau

(*) Với số ngày công <5 thì dù có là bà trời đi nữa cũng có TT (tiền thưởng) = 0;
Như vậy ta có thể dùng 1 dòng lệnh thay cho ba dòng lệnh về ngày công < 5 trong hàm trên; ( tự thử đi nghe)

(*) Kế đến là TT chỉ fát cho đàn bà con gái, nên sGioiTinh="Nam", thì TT=0 (Ta dùng ngay 1 câu lệnh để hất đấn mày râu ra rìa;

(**) Thành tố trong khi tính hàm còn lại là thưởng theo chức vụ & theo ngày công;
Để tiếp, ta nên khai báo thêm biến để giữ HST (hệ số thưởng) theo chức vụ & HST theo ngày công;
Ví dụ
Dim HSChVu As Double, HSNgCg As Double

Sau đó ta tách ra cho từng trường hợp
If sChucVu ="GD" Then HSCVu =10
If sChucVu ="TF" Then HSCVu =8
. . . . .

Tương tự như vậy với ngày công;
. . . . . .

Sau cùng là dòng lệnh

Thuong83 = HSChVu * HSNgCg * Tr

Các bạn thử bớt chút thời gian thực thi theo gợi í của mình xem; Sẽ thấy thoáng mát trong chương trình ngay đó mà!

Chúc lớp nhiều thành công!
 
Lần chỉnh sửa cuối:
Ngồi rảnh nên "ngứa tay" và đã làm ví dụ đơn gian này để mọi người mới tham khảo thêm.........!!

PHP:
Option Explicit
Public Const App = "Hien thong bao"
Sub TinhTong()
    Dim MyRng As Range
    Dim answer As Double
    Set MyRng = Worksheets("Sheet1").Range("A1:A5")
    answer = Application.WorksheetFunction.Sum(MyRng)
    MsgBox "Ket qua la: " & answer, vbInformation, App
End Sub

Ngọc nhớ nguyên tắc đặt tên nhé!

Dim MyRng As Range

Nhìn vào MyRng người ta không biết nó nói lên thông tin gì? Vậy nên sửa là

Dim rngDoanhThu As Range

Với biến là kiểu Object/Class thì tiếp đầu ngữ là 3 ký tự viết tắt của kiểu giá trị hay tên Object/Class. Đây là bài học đầu tiên của lớp VBA mà.

Nhân đây cũng góp ý với các bạn là, đừng lo nghĩ về chuyện code ngắn hay dài mà quan trọng nó có tiết kiệm số phép tính cho máy hay không, nó có dễ đọc hiểu hay không.

Chúng ta lưu ý là, người viết truyện mà họ đọc lại thì đương nhiên họ sẽ hiểu ví chữ nghĩa rõ ràng. Nhưng người viết code thì phụ thuộc vào cách họ đặt tên biến, hàm , thủ tục , đối tượng, và trình bày rõ ràng, văn bản code có cấu trúc (cấp văn bản) thì sau này hay người khác mới có hy vọng biết mình làm gì.
 
...
Sau đó ta tách ra cho từng trường hợp
If sChucVu ="GD" Then HSCVu =10
If sChucVu ="TF" Then HSCVu =8
. . . . .

Không nên viết thế bạn ạ. Một khi sChucVu ="GD" thì không bao giờ xảy ra sChucVu ="TF" nữa, nên với cách viết trên của bạn máy tính phải làm những công việc mà không cần làm.

Với các bạn đang học lớp VBA Hà Nội. Chúng ta bắt đầu học thì hãy cố học bước căn bản đầu tiên, lưu ý những vấn đề chúng tôi đã nói hay đã viết ra ở đây hay ở lớp học. Các bạn gắng tập trung và kiên định đừng nóng vội về viết code hay mục tiêu của các bạn mà thành ẩu sau này khó đạt được cái đích của lớp học này.
 
Đây là bài của em làm nhưng hình như hơi rườm rà, mong mọi người cho ý kiến ah.
PHP:
Option Explicit

Function Thuong(ByVal sChucVu As String, ByVal iSocon As Integer) As Long
    Dim lThuongCV As Long
    Dim lThuongCon As Long
    If (sChucVu = "GD") Then
    lThuongCV = 2000000
        ElseIf (sChucVu = "PGD") Then
        lThuongCV = 1500000
            ElseIf (sChucVu = "TP") Then
            lThuongCV = 1000000
                ElseIf (sChucVu = "PP") Then
                lThuongCV = 500000
                     ElseIf (sChucVu = "NV") Then
                    lThuongCV = 300000
    End If
    If iSocon = 0 Then
    lThuongCon = 0
        ElseIf iSocon = 1 Then
        lThuongCon = 500000
             ElseIf iSocon = 2 Then
            lThuongCon = 1000000
    End If
    Thuong = lThuongCV + lThuongCon
End Function

Về nội dung hàm bạn viết là tốt. Không biết có phải do định dạng của diễn đang không mà code của bạn định dạng code là sai. Các khối lệnh cùng cấp văn bản thì để một level, khối con thì thụt vào một tab.

Để trình bày code trong diễn đang, nhìn dưới đáy màn hình bên phải, nhấn nút "Đổi Sang Khung Lớn", các bạn chọn những dòng code và bấm vào nút "CODE".
 
"Không nên viết thế bạn ạ. Một khi sChucVu ="GD" thì không bao giờ xảy ra sChucVu ="T

Có khi nó trở thành cái bẫy để tìm ra học viên có những suy nghĩ độc lập & sáng tạo cũng nên.


Chúc lớp học đạt nhiều thành quả!
 
E nộp bài. Mong thầy giáo, các bác và các bạn cho ý kiến. Các bác nếu ở trên cao thì nhìn tà tà xuống bên dưới chút nhé. kẻo bọn E tẩu hoả nhập ma, khi đọc code của các bác mất.
Không biết đề bài như thế nào, nhưng nhìn qua cách trình bày thuật toán của Bạn VuMinh, Em cũng có bài giải theo bài của Bạn VuMinh như sau. Mong các Thầy và các Anh xem góp ý nhé!
Mã:
Option Explicit
Const Tr As Long = 10 ^ 6
Function Thuong(ByVal sChucvu As String, ByVal iNgaycong As Integer, ByVal sGioitinh As String) As Long
    If (iNgaycong < 10) Or (sGioitinh = "nam") Then
        Thuong = 0
    ElseIf (iNgaycong > 30) Then
        If (sChucvu = "gd") Then
            Thuong = 10 * Tr * 2
        ElseIf (sChucvu = "tp") Then
            Thuong = 10 * Tr * 1.5
        Else
            Thuong = 10 * Tr
        End If
    ElseIf (iNgaycong > 20) Then
        If (sChucvu = "gd") Then
            Thuong = 8 * Tr * 2
        ElseIf (sChucvu = "tp") Then
            Thuong = 8 * Tr * 1.5
        Else
            Thuong = 8 * Tr
        End If
    ElseIf (iNgaycong >= 15) Then
        If (sChucvu = "gd") Then
            Thuong = 5 * Tr * 2
        ElseIf (sChucvu = "tp") Then
            Thuong = 5 * Tr * 1.5
        Else
            Thuong = 5 * Tr
        End If
    Else
        If (sChucvu = "gd") Then
            Thuong = 3 * Tr * 2
        ElseIf (sChucvu = "tp") Then
            Thuong = 3 * Tr * 1.5
        Else
            Thuong = 3 * Tr
        End If
    End If
End Function
 

File đính kèm

Không nên viết thế bạn ạ. Một khi sChucVu ="GD" thì không bao giờ xảy ra sChucVu ="TF" nữa, nên với cách viết trên của bạn máy tính phải làm những công việc mà không cần làm.

Với các bạn đang học lớp VBA Hà Nội. Chúng ta bắt đầu học thì hãy cố học bước căn bản đầu tiên, lưu ý những vấn đề chúng tôi đã nói hay đã viết ra ở đây hay ở lớp học. Các bạn gắng tập trung và kiên định đừng nóng vội về viết code hay mục tiêu của các bạn mà thành ẩu sau này khó đạt được cái đích của lớp học này.

Code bài 2 cũ như thế này:
Mã:
Option Explicit
Const tr As Long = 10 ^ 6
Function thuong83(ByVal sChucvu As String, ByVal iNgaycong As Integer, ByVal bGioitinh As String)

If (sChucvu = "gd") And (iNgaycong < 5) And (bGioitinh = "nu") Or (bGioitinh = "nam") Then
    thuong83 = 0
    ElseIf (sChucvu = "gd") And (iNgaycong > 30) And (bGioitinh = "nu") Then
        thuong83 = 10 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong > 20) And (iNgaycong <= 30) And (bGioitinh = "nu") Then
        thuong83 = 8 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong >= 15) And (iNgaycong <= 20) And (bGioitinh = "nu") Then
        thuong83 = 5 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong >= 10) And (iNgaycong < 15) And (bGioitinh = "nu") Then
        thuong83 = 3 * tr * 2
End If

If (sChucvu = "tp") And (iNgaycong < 5) And (bGioitinh = "nu") Or (bGioitinh = "nam") Then
    thuong83 = 0
    ElseIf (sChucvu = "tp") And (iNgaycong > 30) And (bGioitinh = "nu") Then
        thuong83 = 10 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong > 20) And (iNgaycong <= 30) And (bGioitinh = "nu") Then
        thuong83 = 8 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong >= 15) And (iNgaycong <= 20) And (bGioitinh = "nu") Then
        thuong83 = 5 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong >= 10) And (iNgaycong < 15) And (bGioitinh = "nu") Then
        thuong83 = 3 * tr * 1.5
                        
End If
If (sChucvu = "nv") And (iNgaycong < 5) And (bGioitinh = "nu") Or (bGioitinh = "nam") Then
    thuong83 = 0
    ElseIf (sChucvu = "nv") And (iNgaycong > 30) And (bGioitinh = "nu") Then
        thuong83 = 10 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong > 20) And (iNgaycong <= 30) And (bGioitinh = "nu") Then
        thuong83 = 8 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong >= 15) And (iNgaycong <= 20) And (bGioitinh = "nu") Then
        thuong83 = 5 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong >= 10) And (iNgaycong < 15) And (bGioitinh = "nu") Then
        thuong83 = 3 * tr
                        
End If
End Function



Thầy ơi! Em cho gọn hơn thế này có được không ah.

Mã:
Option Explicit
Const tr As Long = 10 ^ 6
Function Thuong83(ByVal sChucvu As String, ByVal iNgaycong As Integer, ByVal bGioitinh As String)

If (iNgaycong < 5) Or (bGioitinh = "nam") Then
    thuong83 = 0
    ElseIf (sChucvu = "gd") And (iNgaycong > 30) Then
        Thuong83 = 10 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong > 20) Then
        Thuong83 = 8 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong >= 15) Then
        Thuong83 = 5 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong >= 6) Then
        Thuong83 = 3 * tr * 2
    
    ElseIf (sChucvu = "tp") And (iNgaycong > 30) Then
        Thuong83 = 10 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong > 20) Then
        Thuong83 = 8 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong >= 15) Then
        Thuong83 = 5 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong >= 6) Then
        Thuong83 = 3 * tr * 1.5
                        
    ElseIf (sChucvu = "nv") And (iNgaycong > 30) Then
        Thuong83 = 10 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong > 20) Then
        Thuong83 = 8 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong >= 15) Then
        Thuong83 = 5 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong >= 6) Then
        Thuong83 = 3 * tr
                        
End If
End Function
 
Lần chỉnh sửa cuối:
Không biết đề bài như thế nào, nhưng nhìn qua cách trình bày thuật toán của Bạn VuMinh, Em cũng có bài giải theo bài của Bạn VuMinh như sau. Mong các Thầy và các Anh xem góp ý nhé!

Tạm thời thầy giáo đang ra đề bài rạng mở. Nên các bạn ai nghĩ ra cái gì làm cái đó.
Bạn NH_DK thích hiện vật hơn (Xe máy) thì ra đề theo kiểu hiện vật, còn em thích tiền thưỏng hơn ra đề theo kiểu tiền thưỏng. (hơn nữa thưởng 8/3) he he :))
Một số bạn khác thích trẻ con thì lấy tiêu thức thưỏng là số con (chắc khuyến khích tăng dân số) (?)
Buổi tới nếu thầy giáo ra đề gói gọn vào khuôn khổ nhất định, thì mọi nguời sẽ phải cùng tìm ra lời giải tối ưu nhất. Nhưng nếu ai "dùng công cụ mạnh" vượt trội ngoài phạm vi lớp học sẽ phạm quy
 
Lần chỉnh sửa cuối:
PHP:
Option Explicit
Const Tr As Long = 10 ^ 6
Function Thuong83(ByVal sChucvu As String, ByVal iNgaycong As Integer, ByVal bGioitinh As String)
 1     
 If (iNgaycong < 5) And (bGioitinh <> "nu") Or (bGioitinh = "nam") Then
    Thuong83 = 0
    EXit Function
 End If
 Dim dHSChucVu As Double, bHSNgayCong As Byte 
 If iNgaycong > 30) Then
        bHSNgayCong=  10 
 ElseIf  iNgaycong > 20 Then
        bHSNgayCong = 8 
 ElseIf (iNgaycong >= 15) Then
        bHSNgayCong  = 5 
 ElseIf  (iNgaycong >= 6) Then
        bHSNgayCong = 3 
 End If 
  dHSChucVu = 1
 If sChucVu="GD" Then
     dHSChucVu = 2
 ElseIf (sChucvu = "tp") Then
       dHSChucVu = 1.5
 End If
 2
  Thuong83 = dHSChucVu * bHSNgayCong * Tr                        

End Function
Nếu ta chưa học lệnh Exit Function thì hàm trên có thể viết thêm 2 dòng lệnh như sau:

Tại dòng lệnh 1 ta Viết Thuong83 = 1

Và Tại dòng lệnh mang số 2 ta viết If Thuong83=1 Then _
 
Thầy ơi! Em cho gọn hơn thế này có được không ah.

Mã:
Option Explicit
Const tr As Long = 10 ^ 6
Function Thuong83(ByVal sChucvu As String, ByVal iNgaycong As Integer, ByVal bGioitinh As String)

If (iNgaycong < 5) Or (bGioitinh = "nam") Then
    thuong83 = 0
    ElseIf (sChucvu = "gd") And (iNgaycong > 30) Then
        Thuong83 = 10 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong > 20) Then
        Thuong83 = 8 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong >= 15) Then
        Thuong83 = 5 * tr * 2
    ElseIf (sChucvu = "gd") And (iNgaycong >= 6) Then
        Thuong83 = 3 * tr * 2
    
    ElseIf (sChucvu = "tp") And (iNgaycong > 30) Then
        Thuong83 = 10 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong > 20) Then
        Thuong83 = 8 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong >= 15) Then
        Thuong83 = 5 * tr * 1.5
    ElseIf (sChucvu = "tp") And (iNgaycong >= 6) Then
        Thuong83 = 3 * tr * 1.5
                        
    ElseIf (sChucvu = "nv") And (iNgaycong > 30) Then
        Thuong83 = 10 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong > 20) Then
        Thuong83 = 8 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong >= 15) Then
        Thuong83 = 5 * tr
    ElseIf (sChucvu = "nv") And (iNgaycong >= 6) Then
        Thuong83 = 3 * tr
                        
End If
End Function

Tốt lắm, trình độ lên nhanh quá ha!

Mặc dù Minh đã là ngắn lại và khác rõ ràng với cách lợp luận logic khi nói. Nhưng tối ưu hơn trong tính toán nên làm thế này.
Mã:
Option Explicit
Const tr As Long = 10 ^ 6

Function Thuong83(ByVal sChucvu As String, ByVal iNgaycong As Integer, ByVal bGioitinh As String)
    If (iNgaycong < 5) And (bGioitinh <> "nu") Or (bGioitinh = "nam") Then
        Thuong83 = 0
    ElseIf (sChucvu = "gd") Then
        If (iNgaycong > 30) Then
            Thuong83 = 10 * tr * 2
        ElseIf (iNgaycong > 20) Then
            Thuong83 = 8 * tr * 2
        ElseIf (iNgaycong >= 15) Then
            Thuong83 = 5 * tr * 2
        ElseIf (iNgaycong >= 6) Then
            Thuong83 = 3 * tr * 2
        End If
    ElseIf (sChucvu = "tp") Then
        If (iNgaycong > 30) Then
            Thuong83 = 10 * tr * 1.5
        ElseIf (iNgaycong > 20) Then
            Thuong83 = 8 * tr * 1.5
        ElseIf (iNgaycong >= 15) Then
            Thuong83 = 5 * tr * 1.5
        ElseIf (iNgaycong >= 6) Then
            Thuong83 = 3 * tr * 1.5
        End If
    ElseIf (sChucvu = "nv") Then
        If (iNgaycong > 30) Then
            Thuong83 = 10 * tr
        ElseIf (iNgaycong > 20) Then
            Thuong83 = 8 * tr
        ElseIf (iNgaycong >= 15) Then
            Thuong83 = 5 * tr
        ElseIf (iNgaycong >= 6) Then
            Thuong83 = 3 * tr
        End If
    End If
End Function

Trong lập trình, không quan trọng là viết ngắn hay dài mà là tối ưu về tính tính toán hay không!
 
Em làm một ví dụ cho bài tập về nhà ạ, các thầy và các bạn kiểm tra giúp ạ! Mà em không biết kiểm tra xem đúng sai thế nào ạ, các thầy chỉ cho em với, em cám ơn!
Mã:
Function ThuongCuoiNam(ByVal sChucvu As String, ByVal iNgaydimuon As Integer, ByVal sGiaykhen As String)
    Const tr As Long = 5 * 10 ^ 6
If (iNgaydimuon > 10) Then
    ThuongCuoiNam = 0
ElseIf (5 < iNgaydimuon =< 10) And (sGiaykhen = "co") Then
    If (sChucvu = "GD") Then
        ThuongCuoiNam = 2 * 1.5 * 0.5 * tr
    ElseIf (sChucvu = "TP") Then
        ThuongCuoiNam = 1.5 * 1.5 * 0.5 * tr
    ElseIf (sChucvu = "NV") Then
        ThuongCuoiNam = 1 * 1.5 * 0.5 * tr
    End If
ElseIf (5 < iNgaydimuon =< 10) And (sGiaykhen = "khong") Then
    If (sChucvu = "GD") Then
        ThuongCuoiNam = 2 * 1 * 0.5 * tr
    ElseIf (sChucvu = "TP") Then
        ThuongCuoiNam = 1.5 * 1 * 0.5 * tr
    ElseIf (sChucvu = "NV") Then
        ThuongCuoiNam = 1 * 1 * 0.5 * tr
    End If
ElseIf (iNgaydimuon =< 5) And (sGiaykhen = "co") Then
    If (sChucvu = "GD") Then
        ThuongCuoiNam = 2 * 1.5 * 1 * tr
    ElseIf (sChucvu = "TP") Then
        ThuongCuoiNam = 1.5 * 1.5 * 1 * tr
    ElseIf (sChucvu = "NV") Then
        ThuongCuoiNam = 1 * 1.5 * 1 * tr
    End If
ElseIf (iNgaydimuon =< 5) And (sGiaykhen = "khong") Then
    If (sChucvu = "GD") Then
        ThuongCuoiNam = 2 * 1 * 1 * tr
    ElseIf (sChucvu = "TP") Then
        ThuongCuoiNam = 1.5 * 1 * 1 * tr
    ElseIf (sChucvu = "NV") Then
        ThuongCuoiNam = 1 * 1 * 1 * tr
    End If
End If
End Function
 
Lần chỉnh sửa cuối:
Mà em không biết kiểm tra xem đúng sai thế nào ạ,
Muốn vậy bạn cần lập 1 bảng như vầy:
Ma|HoTen|MaCVu|SoNgayMuon|Khen|TThuongCN
GPE00|Ho Ba|GD|9|Co|
GPE03|Ha Sy|TP|2|Khong|
GPE09|To By|NV|9|Co|
GPE37|La Sy|NV|12|Co|
GPE05|Ca Ha|NV|9|Khong|
GPE73|Ma Vy|TP|32|Co|
Tại cột tiền thưởng CN bạn nhập cú fáp hàm & kiểm theo kết quả; Nếu đúng í đồ là được;


(2) Trong hàm bạn có thấy các dòng có chứa tên hàm có quá nhiều fép tính lặp lại không đấy?

Cũng có người sẽ làm vầy bạn à:

Khai báo 1 biến tạm, chắc ăn là kiểu Double, như

Dim Temp As Double;

Sau đó ta có thể viết gọn lại như sau:

PHP:
Function ThuongCuoiNam(ByVal sChucvu As String, ByVal iNgaydimuon As Integer, ByVal sGiaykhen As String)
    Const tr As Long = 5 * 10 ^ 6
 Dim Temp As Double 
If (iNgaydimuon > 10) Then
    ThuongCuoiNam = 0
ElseIf (5 < iNgaydimuon =< 10) And (sGiaykhen = "co") Then

    If (sChucvu = "GD") Then
        Temp = 2                                                        ' * 1.5 * 0.5 * tr'
    ElseIf (sChucvu = "TP") Then
        Temp = 1.5                                                     '      * 1.5 * 0.5 * tr'
    ElseIf (sChucvu = "NV") Then
        Temp = 1                                                        ' * 1.5 * 0.5 * tr'
    End If
    ThuongCuoiNam=Temp * 1.5 * .5 * Tr
ElseIf (5 < iNgaydimuon =< 10) And (sGiaykhen = "khong") Then
    If (sChucvu = "GD") Then
        Temp = 2                                                       ' * 1 * 0.5 * tr'
    ElseIf (sChucvu = "TP") Then
        Temp = 1.5                                                    ' * 1 * 0.5 * tr '
    ElseIf (sChucvu = "NV") Then
        Temp = 1                                                       ' * 1 * 0.5 * tr'
    End If
    
    ThuongCuoiNam=Temp * 1 * .5 * Tr

ElseIf (iNgaydimuon =< 5) And (sGiaykhen = "co") Then
' . . . .  . '
ElseIf (iNgaydimuon =< 5) And (sGiaykhen = "khong") Then
 '. . . . . . . '

End If
End Function
 
Em dùng biến Boolean để đặt nhưng tại sao công thức không cho kết quả đúng vậy? Thầy và AC xem dùm em nha!

PHP:
Option Explicit
Function Thuong(ByVal sChucVu As String, ByVal lNgayCong As Long, ByVal bGiaDinh As Boolean) As String
  With WorksheetFunction
    If (lNgayCong >= 20) And (bGiaDinh = "Co") Then
      Thuong = .Index(Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", _
       "Bo hoa tuoi"), .Match(sChucVu, Array("GD", "PGD", "TP", "NV")))
       Else
     Thuong = "That dang tiec!"
    End If
  End With
End Function
Câu hỏi cụ thể hơn trong file đính kèm.
 

File đính kèm

Ở đây biến bGiaDinh Là String mối được vì căn cứ dữ liệu đầu vào là String. Muốn có kết quả theo dạng này dữ liệu Cột E phải là có gia đình=True hay 1 và chưa gia đình là False hay 0. Code cũng phải sửa 1 chút

Mã:
Function Thuong(ByVal sChucVu As String, ByVal lNgayCong As Long, ByVal bGiaDinh As Boolean) As String
  With WorksheetFunction
    [B][COLOR=red]If (lNgayCong >= 20) And (bGiaDinh=True) Then[/COLOR][/B]  'Có thể viét gọn If (lNgayCong >= 20) And (bGiaDinh) Then
      Thuong = .Index(Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", _
       "Bo hoa tuoi"), .Match(sChucVu, Array("GD", "PGD", "TP", "NV")))
       Else
     Thuong = "That dang tiec!"
    End If
  End With
End Function


 
Mình cũng có 1 bài đưa lên để các bạn tham khảo
 

File đính kèm

[Em dùng biến Boolean để đặt nhưng tại sao công thức không cho kết quả đúng vậy? Thầy và AC xem dùm em nha!

PHP Code:
Option Explicit
Function Thuong(ByVal sChucVu As String, ByVal lNgayCong As Long, ByVal bGiaDinh As Boolean) As String
With WorksheetFunction
If (lNgayCong >= 20) And (bGiaDinh = "Co") Then
Thuong
= .Index(Array("Xe may Attila", "Xe may Jupiter", "Xe may Wave anpha", _
"Bo hoa tuoi"), .Match(sChucVu, Array("GD", "PGD", "TP", "NV")))
Else
Thuong = "That dang tiec!"
End If
End With
End
Function]


anh ơi. cái này em đã nói với thầy 1 lần trên diễn đàn rùi. tại kiểu gán boolean nó chỉ nhận 2 giá trị là True hoặc False. nên khi anh gán kiểu này anh phải đặt "có" = True, và "không" = False. vì nếu anh để là "có" hoặc "không" thì nó ko hiểu đâu.
 
violetdylan:''
Mình cũng có 1 bài đưa lên để các bạn tham khảo

Như thế này:

ElseIf (iSo_Tiet_Sang < 16) And (iSo_Tiet_Chieu < 12) Then
TroCap = 2000000
Thì mọi trường hợp đều được trợ cấp, chắc ý đồ của tác giả là như vậy.

Và cứ có thêm một dấu "x" là được + 500,000

If (sNu = "x") Then
TroCap = TroCap + 500000
End If
If (sChu_Nhiem = "x") Then
TroCap = TroCap + 500000
End If
If (sGia_Dinh = "x") Then
TroCap = TroCap + 500000
End If

Như vậy mức trợ cấp ở đây được tinh trước theo điều kiện các biến.
iSo_Tiet_Sang
iSo_Tiet_Chieu

Sau khi tính toán mức trợ cấp trên, rồi mới xét mức tăng thêm 500,000 cho mỗi dấu "x"

E "ti toe" vay co dung y bac violetdylan ko (loi Font TV chut)
 
Lần chỉnh sửa cuối:
anh ơi. cái này em đã nói với thầy 1 lần trên diễn đàn rùi. tại kiểu gán boolean nó chỉ nhận 2 giá trị là True hoặc False. nên khi anh gán kiểu này anh phải đặt "có" = True, và "không" = False. vì nếu anh để là "có" hoặc "không" thì nó ko hiểu đâu.

Cám ơn Hương! Bài này anh đã hiểu rồi. Kiểu Boolean nó chỉ nhận giá trị là TRUE hoặc FALSE thôi. Nên trong bài của anh đã thay đổi cột bGiaDinh = 1 và 0 rồi. Và tất nhiên KQ là đúng!!
 
Mình đã làm ví dụ này ("Hơi nâng cao chút" - có ít kiến thức chưa học), nếu ai muốn tham khảo thêm hãy xem nhé!
(Buổi tối rảnh nên làm cho vui thôi. Hi..........!)

PHP:
Option Explicit
Sub TinhTong()
 Dim Ham
 Dim rngVung As Range
 Dim eRw As Long
 Const a = "Cong"
 eRw = [I65500].End(xlUp).Row
 Set rngVung = Range([I5], Cells(eRw, "I"))
 Set Ham = Application.WorksheetFunction
 If Ham.Sum(rngVung) = 2 * Cells(eRw, "I") Then
   MsgBox "Da cong roi!"
 Else
   Cells(eRw + 1, "I").Value = Ham.Sum(rngVung)
   Cells(eRw + 1, "I").NumberFormat = "_(* #,##0_);_(* (#,##0);"""""
   Cells(eRw + 1, "I").Font.Bold = True
   Cells(eRw + 1, "I").Offset(, -4).Value = a
   Cells(eRw + 1, "I").Offset(, -4).Font.Bold = True
 End If
End Sub
Có file đính kèm.
 

File đính kèm

Mình đã làm ví dụ này ("Hơi nâng cao chút" - có ít kiến thức chưa học), nếu ai muốn tham khảo thêm hãy xem nhé!
(Buổi tối rảnh nên làm cho vui thôi. Hi..........!)

PHP:
Option Explicit
Sub TinhTong()
Dim Ham
Dim rngVung As Range
Dim eRw As Long
Const a = "Cong"
eRw = [I65500].End(xlUp).Row
Set rngVung = Range([I5], Cells(eRw, "I"))
Set Ham = Application.WorksheetFunction
If Ham.Sum(rngVung) = 2 * Cells(eRw, "I") Then
MsgBox "Da cong roi!"
Else
Cells(eRw + 1, "I").Value = Ham.Sum(rngVung)
Cells(eRw + 1, "I").NumberFormat = "_(* #,##0_);_(* (#,##0);"""""
Cells(eRw + 1, "I").Font.Bold = True
Cells(eRw + 1, "I").Offset(, -4).Value = a
Cells(eRw + 1, "I").Offset(, -4).Font.Bold = True
End If
End Sub
Có file đính kèm.


Sub bạn tạo ra cũng khá sáng tạo, tôi chưa nói là đúng hay sai, tuy nhiên nhìn vào code tôi có vài điểm cần nói:

1) Nếu Conts a = "Cong" chỉ dùng 1 lần duy nhất, thì không cần thiết phải dùng hằng số làm gì

2) Nếu vùng nào, lệnh nào lặp đi lặp lại liên tục, bạn chuyển sang With ... End With cho gọn gàng và sáng câu lệnh.

Mạn phép điều chỉnh lại Code của bạn chút xíu đây:

PHP:
Option Explicit
Sub TinhTong()
 Dim Ham
 Dim rngVung As Range
 Dim eRw As Long
 eRw = [I65500].End(xlUp).Row
 Set rngVung = Range([I5], Cells(eRw, "I"))
 Set Ham = Application.WorksheetFunction
 If Ham.Sum(rngVung) = 2 * Cells(eRw, "I") Then
   MsgBox "Da cong roi!"
 Else
   With Cells(eRw + 1, "I")
    .Value = Ham.Sum(rngVung)
    .NumberFormat = "_(* #,##0_);_(* (#,##0);"""""
    .Font.Bold = True
    .Offset(, -4).Value = "Cong"
    .Offset(, -4).Font.Bold = True
   End With
 End If
End Sub
 
PHP:
   Cells(eRw + 1, "I").Value = Ham.Sum(rngVung)
   Cells(eRw + 1, "I").NumberFormat = "_(* #,##0_);_(* (#,##0);"""""
   Cells(eRw + 1, "I").Font.Bold = True
   Cells(eRw + 1, "I").Offset(, -4).Value = a
   Cells(eRw + 1, "I").Offset(, -4).Font.Bold = True
Đoạn này của Bạn có thể thay bằng
Mã:
With Cells(eRw + 1, "I")
   .Value = Ham.Sum(rngVung)
   .NumberFormat = "_(* #,##0_);_(* (#,##0);"""""
   .Font.Bold = True
   .Offset(, -4).Value = a
   .Offset(, -4).Font.Bold = True
End With
 
Sub bạn tạo ra cũng khá sáng tạo, tôi chưa nói là đúng hay sai, tuy nhiên nhìn vào code tôi có vài điểm cần nói:

1) Nếu Conts a = "Cong" chỉ dùng 1 lần duy nhất, thì không cần thiết phải dùng hằng số làm gì

2) Nếu vùng nào, lệnh nào lặp đi lặp lại liên tục, bạn chuyển sang With ... End With cho gọn gàng và sáng câu lệnh.

Mạn phép điều chỉnh lại Code của bạn chút xíu đây:

PHP:
Option Explicit
Sub TinhTong()
Dim Ham
Dim rngVung As Range
Dim eRw As Long
eRw = [I65500].End(xlUp).Row
Set rngVung = Range([I5], Cells(eRw, "I"))
Set Ham = Application.WorksheetFunction
If Ham.Sum(rngVung) = 2 * Cells(eRw, "I") Then
MsgBox "Da cong roi!"
Else
With Cells(eRw + 1, "I")
.Value = Ham.Sum(rngVung)
.NumberFormat = "_(* #,##0_);_(* (#,##0);"""""
.Font.Bold = True
.Offset(, -4).Value = "Cong"
.Offset(, -4).Font.Bold = True
End With
End If
End Sub

Cám ơn Learning_Excel nhiều! Vì mục đích của em làm như vậy để lớp em tham khảo dần dần thôi. Còn sử dụng With...End With thì em cũng biết. Nhưng tại vì lớp chưa học đến anh ah.
Một lần nữa cám ơn những góp ý của anh!
 
Bài tập1 buổi học thứ 3

Em nộp bài buổi học thứ 3
PHP:
Option Explicit
Const mil = 10 ^ 6
'Chu y: Tinh thue TNCN SAU KHI da giam tru (*)gia canh ban than va (**) nguoi phu thuoc
'(*)Gia canh ban than - 4.000.000
'(**)Giam tru nguoi phu thuoc moi nguoi 1.600.000
'Thông tư 84/2008/TT-BTC ngày 30..9.2008 
Function Tncn(sTn As Single)
    Select Case sTn
        Case Is <= 0
            Tncn = 0
        Case 0 To 5 * mil
             Tncn = sTn * 0.05
        Case 5 * mil To 10 * mil
            Tncn = 250000 + (sTn - 5 * mil) * 0.1
        Case 10 * mil To 18 * mil
            Tncn = 750000 + (sTn - 10 * mil) * 0.15
        Case 18 * mil To 32 * mil
            Tncn = 1.95 * mil + (sTn - 18 * mil) * 0.2
        Case 32 * mil To 52 * mil
            Tncn = 4.75 * mil + (sTn - 32 * mil) * 0.25
        Case 52 * mil To 80 * mil
            Tncn = 9.75 * mil + (sTn - 52 * mil) * 0.3
        Case Is > 80 * mil
            Tncn = 18.15 * mil + (sTn - 80 * mil) * 0.35
    End Select
End Function
''==============================================================
Function Mytncn(tntt)
''Tinh thue TNCN SAU KHI da giam tru (*)gia canh ban than va (**) nguoi phu thuoc
''(*)Gia canh ban than - 4.000.000
''(**)Giam tru nguoi phu thuoc moi nguoi 1.600.000
    If (tntt > 0) And (tntt <= 5 * mil) Then
        Mytncn = tntt * 0.05
        ElseIf (tntt > 5 * mil) And (tntt <= 10 * mil) Then
            Mytncn = 250000 + (tntt - 5 * mil) * 0.1
        ElseIf (tntt > 10 * mil) And (tntt <= 18 * mil) Then
            Mytncn = 750000 + (tntt - 10 * mil) * 0.15
        ElseIf (tntt > 18 * mil) And (tntt <= 32 * mil) Then
            Mytncn = 1.95 * mil + (tntt - 18 * mil) * 0.2
        ElseIf (tntt > 32 * mil) And (tntt <= 52 * mil) Then
            Mytncn = 4.75 * mil + (tntt - 32 * mil) * 0.25
        ElseIf (tntt > 52 * mil) And (tntt <= 80 * mil) Then
            Mytncn = 9.75 * mil + (tntt - 52 * mil) * 0.3
        ElseIf (tntt > 80 * mil) Then
            Mytncn = 18.15 * mil + (tntt - 80 * mil) * 0.35
    End If
End Function


Trong bài Em dùng Case để tính thuế TNCN theo quy định
E không lồng hàm Round và các phần giảm trừ trong cách tính, cho các bạn cùng lớp dễ xem.
Mong thầy giáo và các bạn cho ý kiến
 

File đính kèm

Lần chỉnh sửa cuối:
Bài nộp thuế TNCN

Đây là bài về thuế TNCN của em
Mong các thầy và AC nhận xét
Mã:
Option Explicit
  Const tr As Long = 10 ^ 6
  Function ThueTNCN(TN As Long, SNPhuThuoc As Integer)
  Dim TN1 As Long, a As Integer
  a = SNPhuThuoc
  TN1 = TN - 4 * tr - a * 1.6 * tr
  If TN1 > 0 Then
      If TN1 >= 0 And TN1 <= 5 * tr Then
      ThueTNCN = TN * 0.05
      ElseIf TN1 > 5 * tr And TN1 <= 10 * tr Then
      ThueTNCN = 5 * tr * 0.05 + (TN1 - 5 * tr) * 0.1
      ElseIf TN1 > 10 * tr And TN1 <= 18 * tr Then
      ThueTNCN = 5 * tr * 0.05 + 5 * tr * 0.1 + (TN1 - 10 * tr) * 0.15
      ElseIf TN1 > 18 * tr And TN1 <= 32 * tr Then
      ThueTNCN = 5 * tr * 0.05 + (10 - 5) * tr * 0.1 + (18 - 10) * tr * 0.15 + (TN1 - 18 * tr) * 0.2
      ElseIf TN1 > 32 * tr And TN1 <= 52 * tr Then
      ThueTNCN = 5 * tr * 0.05 + (10 - 5) * tr * 0.1 + (18 - 10) * tr * 0.15 + (32 - 18) * tr * 0.2 + (TN1 - 32 * tr) * 0.25
      ElseIf TN1 > 52 * tr And TN1 <= 80 * tr Then
      ThueTNCN = 5 * tr * 0.05 + (10 - 5) * tr * 0.1 + (18 - 10) * tr * 0.15 + (32 - 18) * tr * 0.2 + (52 - 32) * tr * 0.25 + (TN1 - 52 * tr) * 0.3
      Else
      ThueTNCN = 5 * tr * 0.05 + (10 - 5) * tr * 0.1 + (18 - 10) * tr * 0.15 + (32 - 18) * tr * 0.2 + (52 - 32) * tr * 0.25 + (80 - 52) * tr * 0.3 + (TN1 - 80 * tr) * 0.35
      End If
  Else
  ThueTNCN = 0
  End If
  End Function
 

File đính kèm

Hãy lấy giấy viết ra & làm những fép cộng trừ nhân chia trước

Sau đó hẵn bắt tay vô viết hàm người dùng;

Ta quan sát bảng sau:

ThuNhap|TiLeNop|FaiNopTruocDo(Triệu)|NopTrongKhoan
<=5 Triệu|0%|0||
<=10 Triệu|5%|0.5|
<=18 Triệu|10%|0.5 + 0.8|0.5Tr +(TNh-10 Tr) * 10%
. . . .||1.3+. . .|
(Dòng thứ ba có nghĩa là Thu nhập anh/chi nào đó 12 triệu thì 5 Tr đầu thuế suất =0; 5 Tr kế tiếp thuế xuất là 5% (~ 0.5 Tr) ; Như vậy 10 Tr đầu chịu mức thuế 0.5Tr (=0 + 0.5) & 2 triệu còn lại chịu mứa thuế 10%

Ta sẽ có công thức tổng quát tính thuế như sau: TTNh = A0 + (TNh - MCH*Ts)

A0 là tổng các mức chịu thuế trước mức thué đó;
Ts - Thuế suất của mức thu nhập của người chịu thuế.
MCH - Mức chịu thuế liền kề trước đó

Chuyện này là mình viết lại của anh em trên diễn đàn mà thôi & cũng đúng trong trường hợp tính tiền điện lũy tiến.

Rất vui nếu được các bạn tham khảo
 
Lần chỉnh sửa cuối:
Đây là bài về thuế TNCN của em
Mong các thầy và AC nhận xét


Tôi thử code của bạn:
Cho thu nhập là 8 tr người phụ thuộc là 1 người
Thu nhập tính thuế là: 8tr - 4tr -1*1,6tr = 2,4tr
Thuế TNCN phải nộp là: 2,4tr * 0,05 = 120,000
Còn công thức của bạn là một số khác. Bạn xem lại nhé
Code của bạn cần sửa lại cách trình bày, đồng cấp cùng một tab và biểu thức thực hiện cho thụt vào 1 tab cho dễ nhìn.
Còn lại mọi người tiếp tục cho ý kiến.
 
To Khanh Khoan:

Hi, đừng tự ái nha, may mà mình không làm nổi thày giáo chứ không chắc bạn ăn 0 điểm số học quá. Các phép số học chắc mấy bà buôn nhẩm nhanh hơn bạn viết biểu thức vài lần. 18-10 thì viết luôn là 8 chứ ai lại viết (18-10)
 
To Khanh Khoan:

Hi, đừng tự ái nha, may mà mình không làm nổi thày giáo chứ không chắc bạn ăn 0 điểm số học quá. Các phép số học chắc mấy bà buôn nhẩm nhanh hơn bạn viết biểu thức vài lần. 18-10 thì viết luôn là 8 chứ ai lại viết (18-10)
Thuế TNCN là tính chia khoảng lỹ tiến từng phần
Bạn ý để như vậy để mọi người dễ hình dung thôi. Nhưng có điều hoi dài
Có thể làm ngắn biểu thức bằng cách đặt tên cho nó dưới dạng name duoc không ? Các bác ơi.
 
Đây làm hàm tính thuế TNCN đã trừ phần gia cảnh (chỉ bản thân: 4.000.000):
Mình đã sửa lại chút của anh vuminh1601: (Case và If)
Đây là code hàm Case:

PHP:
Option Explicit
Const Tr1 = 10 ^ 6
Public Function Tncn(ByVal dLuong As Double) As Double
'Ham tinh nay da tru phan Giam tru ban than roi (la 4 trieu)
'Ham nay chua tinh Giam tru nguoi phu thuoc va cac khoan khac
    Dim dTnhap As Double
    dTnhap = dLuong - 4 * Tr1
    Select Case dTnhap
        Case Is <= 0
            Tncn = 0
        Case 0 To 5 * Tr1
            Tncn = dTnhap * 0.05
        Case 5 * Tr1 To 10 * Tr1
            Tncn = 0.25 * Tr1 + (dTnhap - 5 * Tr1) * 0.1
        Case 10 * Tr1 To 18 * Tr1
            Tncn = 0.75 * Tr1 + (dTnhap - 10 * Tr1) * 0.15
        Case 18 * Tr1 To 32 * Tr1
            Tncn = 1.95 * Tr1 + (dTnhap - 18 * Tr1) * 0.2
        Case 32 * Tr1 To 52 * Tr1
            Tncn = 4.75 * Tr1 + (dTnhap - 32 * Tr1) * 0.25
        Case 52 * Tr1 To 80 * Tr1
            Tncn = 9.75 * Tr1 + (dTnhap - 52 * Tr1) * 0.3
        Case Is > 80 * Tr1
            Tncn = 18.15 * Tr1 + (dTnhap - 80 * Tr1) * 0.35
    End Select
End Function
Còn hàm If (xem thêm trong file đính kèm nha).
 

File đính kèm

Lần chỉnh sửa cuối:
Đây làm hàm tính thuế TNCN đã trừ phần gia cảnh (chỉ bản thân: 4.000.000):
Mình đã sửa lại chút của anh vuminh1601: (Case và If)
Đây là code hàm Case:

PHP:
Option Explicit
Const Tr1 = 10 ^ 6
Public Function Tncn(ByVal dLuong As Double) As Double
'Ham tinh nay da tru phan Giam tru ban than roi (la 4 trieu)
'Ham nay chua tinh Giam tru nguoi phu thuoc va cac khoan khac
    Dim dTnhap As Double
    dTnhap = dLuong - 4 * Tr1
    Select Case dTnhap
        Case Is <= 0
            Tncn = 0
        Case 0 To 5 * Tr1
            Tncn = dTnhap * 0.05
        Case 5 * Tr1 To 10 * Tr1
            Tncn = 0.25 * Tr1 + (dTnhap - 5 * Tr1) * 0.1
        Case 10 * Tr1 To 18 * Tr1
            Tncn = 0.75 * Tr1 + (dTnhap - 10 * Tr1) * 0.15
        Case 18 * Tr1 To 32 * Tr1
            Tncn = 1.95 * Tr1 + (dTnhap - 18 * Tr1) * 0.2
        Case 32 * Tr1 To 52 * Tr1
            Tncn = 4.75 * Tr1 + (dTnhap - 32 * Tr1) * 0.25
        Case 52 * Tr1 To 80 * Tr1
            Tncn = 9.75 * Tr1 + (dTnhap - 52 * Tr1) * 0.3
        Case Is > 80 * Tr1
            Tncn = 18.15 * Tr1 + (dTnhap - 80 * Tr1) * 0.35
    End Select
End Function
Còn hàm If (xem thêm trong file đính kèm nha).

Mình chưa test nên không biết có lỗi không nhưng cũng khá khen chú em có thày lên tay nhanh thật.
Anh chỉ tam gia 1 chút, cái Const Tr1 trông nó rối quá. Sao em không làm đầu vào em chia thu nhập cho Tr1 và kết quả en nhân với Tr1. Vậy là phần thân em bỏ hết Tr1 được rồi
 
Tôi thử code của bạn:
Cho thu nhập là 8 tr người phụ thuộc là 1 người
Thu nhập tính thuế là: 8tr - 4tr -1*1,6tr = 2,4tr
Thuế TNCN phải nộp là: 2,4tr * 0,05 = 120,000
Còn công thức của bạn là một số khác. Bạn xem lại nhé
Code của bạn cần sửa lại cách trình bày, đồng cấp cùng một tab và biểu thức thực hiện cho thụt vào 1 tab cho dễ nhìn.
Còn lại mọi người tiếp tục cho ý kiến.
Em đã sửa lại code, sai lệch đó là em nhầm TN1 thành TN ở đoạn thu nhập nhỏ hơn 5 triệu sau khi giảm trừ gia cảnh. Hôm nay em vội viết xong đi học luôn nên chưa test kỹ. Giờ em gửi lại code đã test. Cám ơn các AC đã nhận xét và mong các AC đóng góp cho bài của em xem ở đâu cần sửa không.
Mã:
Option Explicit
Const tr As Long = 10 ^ 6
Function ThueTNCN(ByVal TN As Long,ByVal SNPhuThuoc As Integer)
Dim TN1 As Long, ThueTNCN1 As Long
Select Case SNPhuThuoc
Case 0
TN1 = TN
Case Is >= 1
TN1 = TN - 4 * tr - SNPhuThuoc * 1.6 * tr
End Select

    If TN1 >= 0 And TN1 <= 5 * tr Then
        ThueTNCN = TN1 * 0.05
    ElseIf TN1 > 5 * tr And TN1 <= 10 * tr Then
        ThueTNCN = 0.25 * tr + (TN1 - 5 * tr) * 0.1
    ElseIf TN1 > 10 * tr And TN1 <= 18 * tr Then
        ThueTNCN = 0.75 * tr + (TN1 - 10 * tr) * 0.15
    ElseIf TN1 > 18 * tr And TN1 <= 32 * tr Then
        ThueTNCN = 1.95 * tr + (TN1 - 18 * tr) * 0.2
    ElseIf TN1 > 32 * tr And TN1 <= 52 * tr Then
        ThueTNCN = 4.75 * tr + (TN1 - 32 * tr) * 0.25
    ElseIf TN1 > 52 * tr And TN1 <= 80 * tr Then
        ThueTNCN = 9.75 * tr + (TN1 - 52 * tr) * 0.3
    ElseIf TN1 >= 80 * tr Then
        ThueTNCN = 18.15 * tr + (TN1 - 80 * tr) * 0.35
    Else
    ThueTNCN = 0
    End If
End Function
 

File đính kèm

Lần chỉnh sửa cuối:
Đây làm hàm tính thuế TNCN đã trừ phần gia cảnh (chỉ bản thân: 4.000.000):
Mình đã sửa lại chút của anh vuminh1601: (Case và If)
Đây là code hàm Case:

PHP:
Option Explicit
Const Tr1 = 10 ^ 6
Public Function Tncn(ByVal dLuong As Double) As Double
'Ham tinh nay da tru phan Giam tru ban than roi (la 4 trieu)
'Ham nay chua tinh Giam tru nguoi phu thuoc va cac khoan khac
    Dim dTnhap As Double
    dTnhap = dLuong - 4 * Tr1
    Select Case dTnhap
        Case Is <= 0
            Tncn = 0
        Case 0 To 5 * Tr1
            Tncn = dTnhap * 0.05
        Case 5 * Tr1 To 10 * Tr1
            Tncn = 0.25 * Tr1 + (dTnhap - 5 * Tr1) * 0.1
        Case 10 * Tr1 To 18 * Tr1
            Tncn = 0.75 * Tr1 + (dTnhap - 10 * Tr1) * 0.15
        Case 18 * Tr1 To 32 * Tr1
            Tncn = 1.95 * Tr1 + (dTnhap - 18 * Tr1) * 0.2
        Case 32 * Tr1 To 52 * Tr1
            Tncn = 4.75 * Tr1 + (dTnhap - 32 * Tr1) * 0.25
        Case 52 * Tr1 To 80 * Tr1
            Tncn = 9.75 * Tr1 + (dTnhap - 52 * Tr1) * 0.3
        Case Is > 80 * Tr1
            Tncn = 18.15 * Tr1 + (dTnhap - 80 * Tr1) * 0.35
    End Select
End Function
Còn hàm If (xem thêm trong file đính kèm nha).
Code của Ngọc Tốt lắm, tuy nhiên cần rút gọn lại ở các điều kiện Case (những dòng Mình tô chữ màu xanh) và IF như sau:
Mã:
Option Explicit
Const Tr1 = 10 ^ 6

Public Function Tncn(ByVal dLuong As Double) As Double
'Ham tinh nay da tru phan Giam tru ban than roi (la 4 trieu)
'Ham nay chua tinh Giam tru nguoi phu thuoc va cac khoan khac
    Dim dTnhap As Double
    dTnhap = dLuong - 4 * Tr1
    Select Case dTnhap
        Case Is <= 0
            Tncn = 0
        Case Is <= 5 * Tr1
            Tncn = dTnhap * 0.05
        Case Is <= 10 * Tr1
            Tncn = 0.25 * Tr1 + (dTnhap - 5 * Tr1) * 0.1
        Case 18 * Tr1
            Tncn = 0.75 * Tr1 + (dTnhap - 10 * Tr1) * 0.15
        Case Is <= 32 * Tr1
            Tncn = 1.95 * Tr1 + (dTnhap - 18 * Tr1) * 0.2
        Case Is <= 52 * Tr1
            Tncn = 4.75 * Tr1 + (dTnhap - 32 * Tr1) * 0.25
        Case Is <= 80 * Tr1
            Tncn = 9.75 * Tr1 + (dTnhap - 52 * Tr1) * 0.3
        Case Is > 80 * Tr1
            Tncn = 18.15 * Tr1 + (dTnhap - 80 * Tr1) * 0.35
    End Select
End Function
Mã:
Public Function Tncn1(ByVal dLuong As Double) As Double
'Ham tinh nay da tru phan Giam tru ban than roi (la 4 trieu)
'Ham nay chua tinh Giam tru nguoi phu thuoc va cac khoan khac
        Dim dTnhap As Double
        dTnhap = dLuong - 4 * Tr1
        If dTnhap <= 0 Then
            Tncn1 = 0
        ElseIf dTnhap <= 5 * Tr1 Then
            Tncn1 = dTnhap * 0.05
        ElseIf dTnhap <= 10 * Tr1 Then
            Tncn1 = 0.25 * Tr1 + (dTnhap - 5 * Tr1) * 0.1
        ElseIf dTnhap <= 18 * Tr1 Then
            Tncn1 = 0.75 * Tr1 + (dTnhap - 10 * Tr1) * 0.15
        ElseIf dTnhap <= 32 * Tr1 Then
            Tncn1 = 1.95 * Tr1 + (dTnhap - 18 * Tr1) * 0.2
        ElseIf dTnhap <= 52 * Tr1 Then
            Tncn1 = 4.75 * Tr1 + (dTnhap - 32 * Tr1) * 0.25
        ElseIf dTnhap <= 80 * Tr1 Then
            Tncn1 = 9.75 * Tr1 + (dTnhap - 52 * Tr1) * 0.3
        Else
            Tncn1 = 18.15 * Tr1 + (dTnhap - 80 * Tr1) * 0.35
        End If
End Function

To VuMinh: Tương tự bài của Bạn Vuminh cũng rút gọn lại các điều kiện ElseIf (Vì đã có điều kiện dòng phía trên rồi thì không cần nhập thêm khoảng điều kiện ở dòng phía dưới, Lập điều kiện giống như trong bài toán đánh giá học sinh Giỏi, Khá, Trung bình...)
 
Lần chỉnh sửa cuối:
Không biết có gì ngược với bài giảng của các thày không chứ với mình thì hàm này mình sẽ viết:

Mã:
Public Function Tncn1(ByVal dLuong As Double) As Double
    Dim dTnhap As Double
    dTnhap = dLuong / 10 ^ 6 - 4
    Select Case dTnhap
        Case Is <= 0
            Tncn1 = 0
        Case Is <= 5
            Tncn1 = dTnhap * 0.05
        Case Is <= 10
            Tncn1 = 0.1 * dTnhap - 0.25
        Case 18
            Tncn1 = 0.15 * dTnhap - 0.75
        Case Is <= 32
            Tncn1 = 0.2 * dTnhap - 1.65
        Case Is <= 52
            Tncn1 = 0.25 * dTnhap - 3.25
        Case Is <= 80
            Tncn1 = 0.3 * dTnhap - 5.85
        Case Is > 80
            Tncn1 = 0.35 * dTnhap - 18.15
    End Select
    Tncn1 = Tncn1 * 10 ^ 6
End Function
Như vậy, thoáng và gọn gàng hơn.
 
Lần chỉnh sửa cuối:
Không biết có gì ngược với bài giảng của các thày không chứ với mình thì hàm này mình sẽ viết:

Mã:
Public Function Tncn1(ByVal dLuong As Double) As Double
Dim dTnhap As Double
dTnhap = dLuong / 10 ^ 6 - 4
Select Case dTnhap
Case Is <= 0
Tncn1 = 0
Case Is <= 5
Tncn1 = dTnhap * 0.05
Case Is <= 10
Tncn1 = 0.1 * dTnhap - 0.25
Case 18
Tncn1 = 0.15 * dTnhap - 0.75
Case Is <= 32
Tncn1 = 0.2 * dTnhap - 1.65
Case Is <= 52
Tncn1 = 0.25 * dTnhap - 3.25
Case Is <= 80
Tncn1 = 0.3 * dTnhap - 5.85
Case Is > 80
Tncn1 = 0.35 * dTnhap - 18.15
End Select
Tncn1 = Tncn1 * 10 ^ 6
End Function
Như vậy, thoáng và gọn gàng hơn.

Cách này của anh gọn thật đó. Em xin sửa lại chút chỗ này cho thành số dương:

PHP:
Tncn1 = Tncn1 * 10 ^ 6
Thành:
PHP:
Tncn1 = -(Tncn1 * 10 ^ 6)
 
Cách này của anh gọn thật đó. Em xin sửa lại chút chỗ này cho thành số dương:

PHP:
Tncn1 = Tncn1 * 10 ^ 6
Thành:
PHP:
Tncn1 = -(Tncn1 * 10 ^ 6)
Sao lại có dấu - phía trước nhỉ? (Kết quả của Ngọc và anh Việt khác nhau ở thu nhập >85 triệu)
 
Em đã sửa lại code, sai lệch đó là em nhầm TN1 thành TN ở đoạn thu nhập nhỏ hơn 5 triệu sau khi giảm trừ gia cảnh. Hôm nay em vội viết xong đi học luôn nên chưa test kỹ. Giờ em gửi lại code đã test. Cám ơn các AC đã nhận xét và mong các AC đóng góp cho bài của em xem ở đâu cần sửa không.
Mã:
Tôi test bài của bạn vẫn bị sai. 
Tôi ví dụ : 
a,Thu nhập 8.000.000 có 1 phụ thuộc, thuế tính được	          = 120.000
b,Thu nhập 6.400.000 không người phụ thuộc, thuế tính được	 = 390.000 

Xét hai khoản thu nhập trên số thuế nộp bằng nhau mới đúng.
Vi 8tr – 1,6tr = 6,4 tr Tại sao số thuế phải nộp lại khác nhau?
 
Lần chỉnh sửa cuối:
Sao lại có dấu - phía trước nhỉ? (Kết quả của Ngọc và anh Việt khác nhau ở thu nhập >85 triệu)

Chết thật! Em cũng sơ xuất quá, em lại không test mức >85 triệu chứ!!? Giờ em test lại mới thấy không đúng rồi.
Bác Công phát hiện đúng rồi đó.
 
[/QUOTE]
Tôi test bài của bạn vẫn bị sai.
Tôi ví dụ :
a,Thu nhập 8.000.000 có 1 phụ thuộc, thuế tính được = 120.000
b,Thu nhập 6.400.000 không người phụ thuộc, thuế tính được = 390.000

Xét hai khoản thu nhập trên số thuế nộp bằng nhau mới đúng.
Vi 8tr – 1,6tr = 6,4 tr Tại sao số thuế phải nộp lại khác nhau?


Còn theo thự tế. Nhân tiện đây trích TT Số: 84/2008/TT-BTC ngày 30 tháng 9 năm 2008
của bộ tài chính
[/QUOTE]
Đó là anh chưa tính khoản giảm trừ cho bản thân người nộp thuế 4 triệu. Nếu không có người phụ thuộc thì không được trừ gì hết, nhưng nếu có người phụ thuộc sẽ được giảm 2 khoản:
- 4 tr cho bản thân người nộp thuế
- 1.6 tr cho mỗi người phụ thuộc
Cho nên người phải nộp không có người phụ thuộc phải nộp: 5.000.000*0.05+1.400.000*0.1=390.000
Còn người kia tính khoản giảm trừ thì thu nhập thực chịu thuế là 8.000.000-4.000.000-1*1.600.000=240.000
Do đó thực nộp chỉ là 2400000*0.05=120.000 thôi.
 
Tôi test bài của bạn vẫn bị sai.
Tôi ví dụ :
a,Thu nhập 8.000.000 có 1 phụ thuộc, thuế tính được = 120.000
b,Thu nhập 6.400.000 không người phụ thuộc, thuế tính được = 390.000

Xét hai khoản thu nhập trên số thuế nộp bằng nhau mới đúng.
Vi 8tr – 1,6tr = 6,4 tr Tại sao số thuế phải nộp lại khác nhau?
Đó là anh chưa tính khoản giảm trừ cho bản thân người nộp thuế 4 triệu. Nếu không có người phụ thuộc thì không được trừ gì hết, nhưng nếu có người phụ thuộc sẽ được giảm 2 khoản:
- 4 tr cho bản thân người nộp thuế
- 1.6 tr cho mỗi người phụ thuộc
Cho nên người phải nộp không có người phụ thuộc phải nộp: 5.000.000*0.05+1.400.000*0.1=390.000
Còn người kia tính khoản giảm trừ thì thu nhập thực tính thuế là 8.000.000-4.000.000-1*1.600.000=2.400.000
Do đó thực nộp chỉ là 2.400.000*0.05=120.000 thôi.
Bài trên em viết nhầm, anh nào là mod xóa hộ nhé, em không biết tự xóa bài của mình thế nào.
 
Lần chỉnh sửa cuối:

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

Back
Top Bottom