Hàm tính tiền điện sinh hoạt

Liên hệ QC

Nguoiay

Thành viên hoạt động
Tham gia
24/11/10
Bài viết
139
Được thích
34
Chào cả nhà!
Lâu lâu rồi mình mới động đến VBA. Hôm nay mình viết 1 hàm tính tiền điện sinh hoạt nhưng nó lại chưa có kết quả đúng. Bí quá nên mình đưa lên đây nhờ mọi người hoàn thiện thêm cho mình nhé!
Mã:
Function TienDien(ByVal ChiSo As Double)
    If ChiSo > 0 And ChiSo <= 50 Then
        TienDien = ChiSo * 1678
    ElseIf ChiSo > 50 And ChiSo <= 100 Then
        TienDien = ChiSo * 1734
    ElseIf ChiSo > 100 And ChiSo <= 200 Then
        TienDien = ChiSo * 2014
    ElseIf ChiSo > 200 And ChiSo <= 300 Then
        TienDien = ChiSo * 2536
    ElseIf ChiSo > 300 And ChiSo <= 400 Then
       TienDien = ChiSo * 2834
    Else
        TienDien = ChiSo * 2927
    End If
End Function
 

File đính kèm

  • TienDien2019.rar
    14.8 KB · Đọc: 12
Chỉnh sửa lần cuối bởi điều hành viên:
Chào cả nhà!
Lâu lâu rồi mình mới động đến VBA. Hôm nay mình viết 1 hàm tính tiền điện sinh hoạt nhưng nó lại chưa có kết quả đúng. Bí quá nên mình đưa lên đây nhờ mọi người hoàn thiện thêm cho mình nhé!
Mã:
Function TienDien(ByVal ChiSo As Double)
    If ChiSo > 0 And ChiSo <= 50 Then
        TienDien = ChiSo * 1678
    ElseIf ChiSo > 50 And ChiSo <= 100 Then
        TienDien = ChiSo * 1734
    ElseIf ChiSo > 100 And ChiSo <= 200 Then
        TienDien = ChiSo * 2014
    ElseIf ChiSo > 200 And ChiSo <= 300 Then
        TienDien = ChiSo * 2536
    ElseIf ChiSo > 300 And ChiSo <= 400 Then
       TienDien = ChiSo * 2834
    Else
        TienDien = ChiSo * 2927
    End If
End Function
Bạn làm như vậy là sai.Bạn phải tách chiso ra chứ.Ví dụ lớn hơn 100 thì phải tách chỉ số thành 3 loại chứ.
 
Upvote 0
Chào cả nhà!
Lâu lâu rồi mình mới động đến VBA. Hôm nay mình viết 1 hàm tính tiền điện sinh hoạt nhưng nó lại chưa có kết quả đúng. Bí quá nên mình đưa lên đây nhờ mọi người hoàn thiện thêm cho mình nhé!
Mã:
Function TienDien(ByVal ChiSo As Double)
    If ChiSo > 0 And ChiSo <= 50 Then
        TienDien = ChiSo * 1678
    ElseIf ChiSo > 50 And ChiSo <= 100 Then
        TienDien = ChiSo * 1734
    ElseIf ChiSo > 100 And ChiSo <= 200 Then
        TienDien = ChiSo * 2014
    ElseIf ChiSo > 200 And ChiSo <= 300 Then
        TienDien = ChiSo * 2536
    ElseIf ChiSo > 300 And ChiSo <= 400 Then
       TienDien = ChiSo * 2834
    Else
        TienDien = ChiSo * 2927
    End If
End Function
Bạn thử hàm này xem sao
Mã:
Function TienDien(ByVal ChiSo As Double)
Dim DinhMuc(6) As Double
Dim DonGia(1 To 6) As Double
Dim i, k
DonGia(1) = 1678: DonGia(2) = 1734: DonGia(3) = 2014: DonGia(4) = 2536: DonGia(5) = 2834: DonGia(6) = 2927
DinhMuc(1) = 50: DinhMuc(2) = 100: DinhMuc(3) = 200: DinhMuc(4) = 300: DinhMuc(5) = 400
If ChiSo <= 400 Then
    DinhMuc(6) = 0
Else
    DinhMuc(6) = ChiSo
End If
If ChiSo <= 50 Then
    TienDien = ChiSo * 1678
Else
    For i = 1 To 6
        If ChiSo >= DinhMuc(i) Then
            TienDien = TienDien + (DinhMuc(i) - DinhMuc(i - 1)) * DonGia(i)
        Else
            TienDien = TienDien + (ChiSo - DinhMuc(i - 1)) * DonGia(i)
            Exit For
        End If
    Next i
End If
End Function
 
Upvote 0
Chào cả nhà!
Lâu lâu rồi mình mới động đến VBA. Hôm nay mình viết 1 hàm tính tiền điện sinh hoạt nhưng nó lại chưa có kết quả đúng. Bí quá nên mình đưa lên đây nhờ mọi người hoàn thiện thêm cho mình nhé!
Mã:
Function TienDien(ByVal ChiSo As Double)
    If ChiSo > 0 And ChiSo <= 50 Then
        TienDien = ChiSo * 1678
    ElseIf ChiSo > 50 And ChiSo <= 100 Then
        TienDien = ChiSo * 1734
    ElseIf ChiSo > 100 And ChiSo <= 200 Then
        TienDien = ChiSo * 2014
    ElseIf ChiSo > 200 And ChiSo <= 300 Then
        TienDien = ChiSo * 2536
    ElseIf ChiSo > 300 And ChiSo <= 400 Then
       TienDien = ChiSo * 2834
    Else
        TienDien = ChiSo * 2927
    End If
End Function
Bạn xem cấu trúc bảng biểu và cách tính của Excel rồi vận dụng viết VBA xem sao.
 

File đính kèm

  • TienDien2019.xlsm
    19.8 KB · Đọc: 18
Upvote 0
Chào cả nhà!
Lâu lâu rồi mình mới động đến VBA. Hôm nay mình viết 1 hàm tính tiền điện sinh hoạt nhưng nó lại chưa có kết quả đúng. Bí quá nên mình đưa lên đây nhờ mọi người hoàn thiện thêm cho mình nhé!
Mã:
Function TienDien(ByVal ChiSo As Double)
    If ChiSo > 0 And ChiSo <= 50 Then
        TienDien = ChiSo * 1678
    ElseIf ChiSo > 50 And ChiSo <= 100 Then
        TienDien = ChiSo * 1734
    ElseIf ChiSo > 100 And ChiSo <= 200 Then
        TienDien = ChiSo * 2014
    ElseIf ChiSo > 200 And ChiSo <= 300 Then
        TienDien = ChiSo * 2536
    ElseIf ChiSo > 300 And ChiSo <= 400 Then
       TienDien = ChiSo * 2834
    Else
        TienDien = ChiSo * 2927
    End If
End Function
Với bài toán lũy tiến thì chuyện này viết bằng công thức đơn giản hơn viết code "khủng" nhiều. :cool:

Xem file kèm.

Thân
 

File đính kèm

  • TienDien2019.xlsm
    17.1 KB · Đọc: 16
Upvote 0

File đính kèm

  • TienDien2019.xlsm
    20.9 KB · Đọc: 14
Upvote 0
Code cũng đâu cần khủng đâu! Khỏi phải dùng thêm cột E.
"Thằng em" cũng đang chờ anh nói câu này! /-*+/

1/ Không dùng cột E:
Mã:
=SUMPRODUCT((H4>SUMIF(OFFSET($C$4,,,ROW($1:$6)),">0"))*(H4-SUMIF(OFFSET($C$4,,,ROW($1:$6)),">0"))*(D5:D10-D4:D9))
Chỉ Enter.
Mã:
=SUM(IFERROR(((H4-SUMIF(OFFSET($C$4,,,ROW($1:$6)),">0"))^0.5)^2,)*(D5:D10-D4:D9))
Kết thúc Ctrl+Shift+Enter.

Chơi luôn câu "Không cần cả cái bảng luôn" (nếu có) Khà khà khà /-*+//-*+//-*+/
2/ Không cần bảng ghi các mức:
Mã:
=SUM((H4>{0,50,100,200,300,400})*(H4-{0,50,100,200,300,400})*({1678,1734,2014,2536,2834,2927}-{0,1678,1734,2014,2536,2834}))
Chỉ Enter.

Thân
 

File đính kèm

  • TienDien2019.xlsm
    17.6 KB · Đọc: 19
Upvote 0
"Thằng em" cũng đang chờ anh nói câu này! /-*+/

1/ Không dùng cột E:
Mã:
=SUMPRODUCT((H4>SUMIF(OFFSET($C$4,,,ROW($1:$6)),">0"))*(H4-SUMIF(OFFSET($C$4,,,ROW($1:$6)),">0"))*(D5:D10-D4:D9))
Chỉ Enter.
Mã:
=SUM(IFERROR(((H4-SUMIF(OFFSET($C$4,,,ROW($1:$6)),">0"))^0.5)^2,)*(D5:D10-D4:D9))
Kết thúc Ctrl+Shift+Enter.

Chơi luôn câu "Không cần cả cái bảng luôn" (nếu có) Khà khà khà /-*+//-*+//-*+/
2/ Không cần bảng ghi các mức:
Mã:
=SUM((H4>{0,50,100,200,300,400})*(H4-{0,50,100,200,300,400})*({1678,1734,2014,2536,2834,2927}-{0,1678,1734,2014,2536,2834}))
Chỉ Enter.

Thân
Xin copy file của anh. Đúng chỉ cần nhập chỉ số công tơ vào và úm ba la hiện ra số tiền. Thank anh
 
Upvote 0
"Thằng em" cũng đang chờ anh nói câu này! /-*+/

1/ Không dùng cột E:
------------------------------------
Chơi luôn câu "Không cần cả cái bảng luôn" (nếu có) Khà khà khà /-*+//-*+//-*+/
2/ Không cần bảng ghi các mức:
Mã:
=SUM((H4>{0,50,100,200,300,400})*(H4-{0,50,100,200,300,400})*({1678,1734,2014,2536,2834,2927}-{0,1678,1734,2014,2536,2834}))
Chỉ Enter.

Thân
Có cái bảng, coi thấy "dzô dziêng" nhưng trực quan, dễ chỉnh sửa nếu giá thay đổi.
Khi cần chỉ sửa cái bảng mà không cần chỉnh công thức. Dấu nó ở "phương trời" nào đó nếu thấy ghét.
 
Upvote 0
"Thằng em" cũng đang chờ anh nói câu này! /-*+/

......
2/ Không cần bảng ghi các mức:
Mã:
=SUM((H4>{0,50,100,200,300,400})*(H4-{0,50,100,200,300,400})*({1678,1734,2014,2536,2834,2927}-{0,1678,1734,2014,2536,2834}))
Chỉ Enter.

Thân
Nói "Không cần bảng ghi các mức" là chưa chính xác, chỉ có vấn đề là nhét cái bảng vào chỗ nào thôi.
Dùng công thức thì .....đưa nó vào công thức
Dùng code thì.........cũng đưa nó vào code thôi. Híc
Thân
 
Upvote 0
Chào cả nhà!
Lâu lâu rồi mình mới động đến VBA. Hôm nay mình viết 1 hàm tính tiền điện sinh hoạt nhưng nó lại chưa có kết quả đúng. Bí quá nên mình đưa lên đây nhờ mọi người hoàn thiện thêm cho mình nhé!
Mã:
Function TienDien(ByVal ChiSo As Double)
    If ChiSo > 0 And ChiSo <= 50 Then
        TienDien = ChiSo * 1678
    ElseIf ChiSo > 50 And ChiSo <= 100 Then
        TienDien = ChiSo * 1734
    ElseIf ChiSo > 100 And ChiSo <= 200 Then
        TienDien = ChiSo * 2014
    ElseIf ChiSo > 200 And ChiSo <= 300 Then
        TienDien = ChiSo * 2536
    ElseIf ChiSo > 300 And ChiSo <= 400 Then
       TienDien = ChiSo * 2834
    Else
        TienDien = ChiSo * 2927
    End If
End Function
Cách code này không liên quan đến "lâu rồi" hay "mới đây". Lô gic là chuyện khong thể quên.
1. tất cả các IF's đều dò số dương. Như vậy cái Else cuói cùng áp dụng luôn cho số âm?
2. đã không phải <= 50 thì đương nhiên là > 50 rồi, cần gì phải dò lại?
If ChiSo <= 0 Then ' ai biết làm gì?
ElseIf ChiSo <= 50 Then
TienDien = ChiSo * 1678
ElseIf ChiSo <= 100 Then
TienDien = ChiSo * 1734
ElseIf ChiSo <= 200 Then
TienDien = ChiSo * 2014
ElseIf ChiSo <= 300 Then
TienDien = ChiSo * 2536
ElseIf ChiSo <= 400 Then
TienDien = ChiSo * 2834
Else
TienDien = ChiSo * 2927
End If

Tôi chỉ sửa lô gic hiển nhiên của code thôi. Việc code có đáp ứng yêu cầu hay không thì tôi chưa coi file, không biết.
 
Upvote 0
Bài này đã giải rồi trên diễn đàn. Tìm theo từ khóa "tiền nước" hoặc "tiền điện".

Bằng VBA thì có hai giải thuật. Cả hai đều theo nguyên tắc tương tự nhau.

Giải thuật thứ nhất là căn bản của lập trình. Học môn này đến khoảng bài thứ 10 thì gặp:
- Lập một hàm tính tiền của từng khoảng
- Gọi hàm này theo từng khoảng và cộng lại
code:
Private Function TienTheoKhoang(ByVal tieuThu As Double, ByVal chanDuoi As Double, ByVal chanTren As Double, ByVal donGia As Double) As Double
' calculates the amount according to the quantity within the range determined by chanDuoi and chanTren
If tieuThu <= chanDuoi Then Exit Function ' no consumption within this range
If tieuThu > chanTren Then tieuThu = chanTren ' disregard consumption outside range
TienTheoKhoang = donGia * (tieuThu - chanDuoi)
End Function

Function TongTien(ByVal tieuThu As Double) As Double
Dim dinhMuc, donGia
Dim i As Integer
dinhMuc = Array(0, 50, 100, 200, 300, 400, 90000000000#)
donGia = Array(1678, 1734, 2014, 2536, 2834, 2927)
For i = LBound(donGia) To UBound(donGia)
TongTien = TongTien + TienTheoKhoang(tieuThu, dinhMuc(i), dinhMuc(i + 1), donGia(i))
Next i
End Function


Giải thuật thứ hai hơi khác một chút, giành cho bảng tính (tức là dùng cách tính lũy tiến):
- Tính tiền theo giá nhỏ nhất
- Lần lượt tính phần phải lấy thêm theo tùng khoảng giá cao hơn.
code:
Function TinhTien(ByVal tieuThu As Double) As Double
' caculates cost of consumption according to pricing steps
Dim dinhMuc, donGia
Dim i As Integer
dinhMuc = Array(0, 50, 100, 200, 300, 400, 90000000000#)
donGia = Array(0, 1678, 1734, 2014, 2536, 2834, 2927)
For i = LBound(donGia) + 1 To UBound(donGia)
If tieuThu > dinhMuc(i - 1) Then
TinhTien = TinhTien + (donGia(i) - donGia(i - 1)) * (tieuThu - dinhMuc(i - 1))
End If
Next i
End Function
 
Upvote 0
Function TinhTien(ByVal tieuThu As Double) As Double
' caculates cost of consumption according to pricing steps
Dim dinhMuc, donGia
Dim i As Integer
dinhMuc = Array(0, 50, 100, 200, 300, 400, 90000000000#)
donGia = Array(0, 1678, 1734, 2014, 2536, 2834, 2927)
For i = LBound(donGia) + 1 To UBound(donGia)
If tieuThu > dinhMuc(i - 1) Then
TinhTien = TinhTien + (donGia(i) - donGia(i - 1)) * (tieuThu - dinhMuc(i - 1))
End If
Next i
End Function
Dựa theo cái này, em làm bằng QueryTable thử.

Mã:
Sub TinhTienDien()
    Dim strSQL As String
    strSQL = "SELECT A.KhachHang as [Khách Hàng], Sum(SoDien * B.Gia) as [Thành Tièn]" & _
             "From (Select *, iif(B.Muc2 >= A.SoDienSD,A.SoDienSD - B.Muc1,B.Muc2 - B.Muc1) as SoDien From [MucSuDung$] as A " & _
                    "Left Join [BangGia$] as B on A.SoDienSD > B.Muc1) " & _
                    "Group by A.KhachHang"
    With Sheet4.QueryTables.Add("OLEDB;Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & _
                ";Extended Properties=Excel 12.0", _
                Sheet4.Range("A1"), _
                strSQL)
        .RefreshStyle = xlOverwriteCells
        .Refresh False
    End With
   
End Sub
 

File đính kèm

  • TienDien2019.xlsm
    22.9 KB · Đọc: 27
Upvote 0
Web KT
Back
Top Bottom