#vb.net
#vb.net
Вопрос:
Я создаю программу, которая вычисляет счет пользователя за электроэнергию. Однако есть проблема, мне удается вычислять их только по одному, но когда я пытаюсь их суммировать, это не сработало, отображается только общая сумма одной переменной вместо суммирования обеих.
Вот код, это не полный код, так как он очень длинный, так как мне нужно рассчитать с марта по декабрь, поэтому я взял только март и апрель.
(Это для определения цены на основе использования)
Налог на обслуживание составляет 6%, я уже ввел его в переменную налога на обслуживание.
Select Case True
Case mar >= 1 To mar <= 200
unitsConsumedMar = mar
marTotalAmount = (unitsConsumedMar * 0.109)
serviceTax = marTotalAmount * serviceTax
marTotalAmount = serviceTax
TextBox16.Text = marTotalAmount.ToString("C2")
Case apr >= 1 To apr <= 200
unitsConsumedApr = apr
aprTotalAmount = (unitsConsumedApr * 0.109)
serviceTax = aprTotalAmount * serviceTax
aprTotalAmount = serviceTax
TextBox16.Text = aprTotalAmount.ToString("C2")
End Select
Select Case True
Case mar > "200" And mar <= "300"
unitsConsumedMar = mar
marTotalAmount = (unitsConsumedMar * 0.153)
serviceTax = marTotalAmount * serviceTax
marTotalAmount = serviceTax
TextBox16.Text = marTotalAmount.ToString("C2")
Case apr > "200" And apr <= "300"
unitsConsumedApr = apr
aprTotalAmount = (unitsConsumedApr * 0.153)
serviceTax = aprTotalAmount * serviceTax
aprTotalAmount = serviceTax
TextBox16.Text = aprTotalAmount.ToString("C2")
End Select
totalBill = Val(marTotalAmount) Val(aprTotalAmount)
textbox20.Text = totalBill.ToString("C2")
Все это работает, если в марте 200, а в апреле 201, но тогда textbox16 возвращает какую-то странную сумму, похоже, что она суммирует как сумму за март, так и за апрель, вместо того, чтобы добавлять ее к textbox20.
по какой-то причине, если я помещаю 200 в одно текстовое поле и 201 в другое, оно вычисляется правильно, поскольку 70.98 23.11 равно 94.09, но общая сумма за месяц не должна составлять 70.98, поскольку 23.11 32.60 даже близко не 70…
Комментарии:
1. Вам нужно отладить свой код, т. Е. Установить точку останова вверху, а затем пошагово просмотреть код построчно, проверяя состояние на каждом шаге. Вы знаете, что, как вы ожидаете, произойдет перед каждым шагом, и вы можете сравнить это с тем, что на самом деле происходит впоследствии. Как только они не совпадают, вы нашли свою проблему и можете исследовать ее конкретно, а не соглашаться на «по какой-то причине» . Даже если вы все еще не можете решить проблему, по крайней мере, вы можете предоставить нам всю необходимую информацию.
2. Вы имеете в виду, что за первые 200 единиц будет выставлен счет в размере $ 0,109, а за все, что превышает 200 единиц, будет выставлен счет в размере $ 0,153? Или все использование оплачивается по более высокой ставке, когда оно превышает 200 единиц?
3. правильно. но 1 единица = 0,109, а если оно превышает 200, то 1 единица = 0,153
Ответ №1:
Я бы предложил создать пользовательскую функцию для расчета ежемесячной суммы:
Function GetMonthlyAmount(energyUsage As Double) As Double
Dim discount As Double = 0.0
Dim serviceTax As Double = 0.06
Dim total As Double = 0.0
Select Case energyUsage
Case 1.0 To 200.00
discount = 0.109
Case 200.01 To 300.0
discount = 0.153
Case > 300.00
discount = 0.169
Case Else
discount = 0.0100
End Select
total = energyUsage * discount
total = (total * serviceTax)
Return total
End Function
Но приведенная выше функция возвращает только ежемесячную сумму. Насколько я вижу, вы хотите получить (и отобразить) другие значения, такие как: скидка, налог на обслуживание и т.д. Итак, я бы предложил создать пользовательский класс:
Public Class BillOfEnergyUsage
Private st As Double = 0.06
Private eu As Double = 0.0
Private di AS Double = 0.0
Private dia AS Double = 0.0
Private ta As Double = 0.0
Public Sub New(energyUsage As Double)
eu = energyUsage
di = Discount
dia = DiscountAmount
ta = TotalAmount
End Sub
Public ReadOnly Property ServiceTax As Double
Get
Return st
End Get
End Property
Public Property EnergyUsage As Double
Get
Return eu
End Get
Set (value As Double)
eu = value
End Set
End Property
Public ReadOnly Property Discount As Double
Get
Select Case eu
Case 1.0 To 200.00
di = 0.109
Case 200.01 To 300.0
di = 0.153
Case > 300.00
di = 0.169
Case Else
di = 0.0
End Select
Return di
End Get
End Property
Public ReadOnly Property DiscountAmount As Double
Get
dia = eu * di
Return dia
End Get
End Property
Public ReadOnly Property TotalAmount As Double
Get
ta = dia
ta = (ta * st)
Return ta
End Get
End Property
Public Overrides Function ToString() AS String
Return $"Usage: {eu.ToString("C2")}, Service Tax: {st.ToString("P2")}, Discount: {di.ToString("P2")} - {dia.ToString("C2")}, Total: {ta.ToString("C2")}"
End Function
End Class
Использование:
Sub Main
Dim usages As Double() = {120.00, 200.00, 252.00, 300.00, 305.00} 'you have to init your data from textboxes
Dim beulist As List(Of BillOfEnergyUsage) = New List(Of BillOfEnergyUsage)
For Each usage As Double In usages
Dim beu As BillOfEnergyUsage = New BillOfEnergyUsage(usage)
beulist.Add(beu)
Console.WriteLine(beu.ToString())
Next
Dim totalAmount = beulist.Sum(Function(x) x.TotalAmount)
Console.WriteLine($"Total amount: {totalAmount.ToString("C2")}")
End Sub
Результат:
Usage: RM120.00, Service Tax: 6.00%, Discount: 10.90% - RM13.08, Total: RM13.86
Usage: RM200.00, Service Tax: 6.00%, Discount: 10.90% - RM21.80, Total: RM23.11
Usage: RM252.00, Service Tax: 6.00%, Discount: 15.30% - RM38.56, Total: RM40.87
Usage: RM300.00, Service Tax: 6.00%, Discount: 15.30% - RM45.90, Total: RM48.65
Usage: RM305.00, Service Tax: 6.00%, Discount: 16.90% - RM51.55, Total: RM54.64
Total amount: RM181.13
Обратите внимание, что вы можете получить любой счет из списка и получить доступ к его свойствам следующим образом:
Dim bb As BillOfEnergyUsage = beulist(0) 'get first bill from list
Console.WriteLine("{0} | {1} | {2} | {3}", bb.EnergyUsage, bb.ServiceTax, bb.Discount, bb.TotalAmount)
Удачи!
Комментарии:
1. Проблема в том, что я считаю ежемесячно и с помощью кнопки. У меня есть только одно текстовое поле для хранения значения текущей переменной, которое является месячным итогом. Допустим, что март равен textbox5, а апрель равен textbox6, если я введу число в textbox5, оно вычислит все в месячную сумму, но когда я введу число в апрель, число будет складываться, и если я сделаю для любого из них значение только для чтения = true, то как я смогучтобы суммировать их…
2. Извините, я вас не понимаю… Количество текстовых полей, размещенных в форме, и их статус «включено» не важны! Я предполагаю, что вы не знаете, как перебирать коллекцию текстовых полей. Я прав?
Ответ №2:
Я создал класс для данных, связанных с энергетическим полем. Общие поля содержат значения, используемые во всех экземплярах класса. Эти значения устанавливаются в Form.Load
методе путем вызова SetRates
метода. Поскольку это общий метод, вам не нужно создавать экземпляр класса. Используется MonthNumber
для упорядочения списка счетов за электроэнергию. Возможно, вам потребуется изменить CalculateGrossMonthlyBill
метод, потому что я предполагал градуированную скорость. Этот ToString
метод используется полем со списком для определения отображения.
В дизайне формы я назвал каждое из текстовых полей в группе MonthlyEnergyUse месяцем, который они представляют. Вероятно, вы хотите начать со .Text
свойства 0. .Tag
Свойство каждого месяца — это число, представляющее месяц. Март — 3, апрель — 4 и т.д. Это число будет использоваться для упорядочения списка.
В Form.Load
Shared
задаются ставки. Хотя я жестко запрограммировал значения, они могут быть извлечены из текстового файла или базы данных. Если их нужно изменить, вам не придется перекомпилировать программу.
После заполнения текстовых полей месяца нажимается кнопка 1. Сначала ввод пользователя проверяется с .TryParse
помощью функции. Мы создаем список EnergyBill
, затем перебираем каждое текстовое поле, вызывая конструктор of EnergyBill
, передавая значения из свойств текстового поля. Конструктор устанавливает Read Only
свойства класса. Затем это новое EnergyBill
добавляется в список.
Далее список упорядочивается MonthNumber
с помощью магии Linq. Затем оно привязывается к выпадающему списку (это заменяет текстовое поле, которое вы отметили Месяц в правой части вашей формы.
Общий итог вычисляется с использованием .Sum
метода списка и отображается в текстовом поле.
Вы можете просмотреть данные за каждый месяц, выбрав месяц в поле со списком. Элементы выпадающего списка являются объектами, но базовый тип таков EnergyBill
, что мы можем привести элемент и получить доступ ко всем свойствам.
Public Class EnergyBill
Private _MonthlyChargeWithTax As Decimal
Private _DiscountAmount As Decimal
Private _TotalAmount As Decimal
Private Shared LowUsageRate As Decimal
Private Shared HighUsageRate As Decimal
Private Shared DiscountRate As Decimal
Private Shared TaxRate As Decimal
Public Property Month As String
Public Property MonthNumber As Integer
Public Property EnergyUsage As Double
Public ReadOnly Property MonthChargeWithTax As Decimal
Get
Return _MonthlyChargeWithTax
End Get
End Property
Public ReadOnly Property DiscountAmount As Decimal
Get
Return _DiscountAmount
End Get
End Property
Public ReadOnly Property TotalAmount As Decimal
Get
Return _TotalAmount
End Get
End Property
Public Sub New(BillingMonth As String, MonthNum As Integer, Usage As Integer)
Month = BillingMonth
EnergyUsage = Usage
MonthNumber = MonthNum
_MonthlyChargeWithTax = CalculateGrossMonthlyBill(Usage)
_DiscountAmount = _MonthlyChargeWithTax * DiscountRate
_TotalAmount = _MonthlyChargeWithTax - _DiscountAmount
End Sub
Private Function CalculateGrossMonthlyBill(usage As Integer) As Decimal
Dim MonthCharge As Decimal
Select Case usage
Case <= 200
MonthCharge = usage * LowUsageRate
Case Else
MonthCharge = 200 * LowUsageRate
MonthCharge = (usage - 200) * HighUsageRate
End Select
Return MonthCharge * 1.06D
End Function
Public Shared Sub SetRates(LowUsage As Decimal, HighUsage As Decimal, Discount As Decimal, Tax As Decimal)
LowUsageRate = LowUsage
HighUsageRate = HighUsage
DiscountRate = Discount
TaxRate = Tax
End Sub
Public Overrides Function ToString() As String
Return Month
End Function
End Class
Форма…
Public Class UtilityBills
Private Sub UtilityBills_Load(sender As Object, e As EventArgs) Handles MyBase.Load
EnergyBill.SetRates(0.109D, 0.153D, 0.5D, 0.06D)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Not ValidateUsage() Then
MessageBox.Show("All text boxes must have a valid number.")
Exit Sub
End If
Dim lst As New List(Of EnergyBill)
For Each tb In GroupBox1.Controls.OfType(Of TextBox)
Dim eb As New EnergyBill(tb.Name, CInt(tb.Tag), CInt(tb.Text))
lst.Add(eb)
Next
Dim orderedList = (lst.OrderBy(Function(eb) eb.MonthNumber)).ToList
ComboBox1.DataSource = orderedList
Dim TotalMonths = lst.Sum(Function(eb) eb.TotalAmount)
TextBox5.Text = TotalMonths.ToString("C2")
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim eb = DirectCast(ComboBox1.SelectedItem, EnergyBill)
TextBox1.Text = eb.MonthChargeWithTax.ToString("C2")
TextBox2.Text = eb.DiscountAmount.ToString("C2")
TextBox3.Text = eb.TotalAmount.ToString("C2")
End Sub
Private Function ValidateUsage() As Boolean
Dim usage As Integer
For Each tb In GroupBox1.Controls.OfType(Of TextBox)
If Not Integer.TryParse(tb.Text, usage) Then
Return False
End If
Next
Return True
End Function
End Class