VB.NET餐厅项目:如何从文本框计算折扣百分比?
餐厅订单折扣计算解决方案
问题概述
这是一个高中课业的餐厅订单程序,核心功能包括:
- 选择菜品(当前仅Button1可添加单价1.45€的面包)
- 点击保存按钮将订单内容保存至
C:\Mesa1.txt,窗体加载时自动读取文件内容并显示 - 需实现从文本框获取折扣百分比,正确计算并显示折扣后的最终总金额
现有代码核心问题
Total变量未指定类型,默认是Object类型,易引发精度和类型错误- 折扣计算按钮(Button13)中,错误执行
TextBoxTeclado1.Text = percentagem,直接覆盖用户输入的折扣值,导致无法获取有效百分比 - 折扣计算公式错误:
Total = Total * (100 - percentagem)会将总金额放大100倍,不符合实际折扣逻辑 - 数字按钮点击时直接覆盖文本框内容,无法输入多位数折扣(如15%)
修正后的完整代码
Imports System.IO Public Class Form1 ' 使用Decimal类型存储总金额,避免浮点精度丢失,适配货币计算场景 Dim Total As Decimal = 0D Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim filePath As String = "C:\Mesa1.txt" If File.Exists(filePath) Then Dim lines() As String = File.ReadAllLines(filePath) ListBoxConsumo.Items.Clear() For Each line As String In lines ListBoxConsumo.Items.Add(line) Next End If End Sub Public Sub BtnConta_Click(sender As Object, e As EventArgs) Handles BtnConta.Click Total = 0D ' 每次计算前重置总金额,避免累计错误 Dim quoteArray As String() = File.ReadAllLines("C:\Mesa1.txt") For Each Item As String In quoteArray Dim parts As String() = Strings.Split(Item, "€__") Dim number As Decimal ' 适配欧洲地区逗号作为小数分隔符的格式解析 If Decimal.TryParse(parts(0), Globalization.NumberStyles.Currency, Globalization.CultureInfo.GetCultureInfo("pt-PT"), number) Then Total += number End If Next ' 格式化货币显示,保留两位小数 TxtBoxTotal.Text = $"{Total:C2}" End Sub Private Sub BtnSaveLstBox_Click(sender As Object, e As EventArgs) Handles BtnSaveLstBox.Click Dim filePath As String = "C:\Mesa1.txt" Using writer As New StreamWriter(filePath) For Each item As Object In ListBoxConsumo.Items writer.WriteLine(item.ToString()) Next End Using MessageBox.Show("订单已保存至文件。") End Sub Private Sub BtnDesconto_Click(sender As Object, e As EventArgs) Handles BtnDesconto.Click PanelDesconto.Show() TextBoxTeclado1.Clear() ' 显示折扣面板时清空输入框 End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ListBoxConsumo.Items.Add("1,45€__Pão") End Sub ' 数字按钮改为追加输入,支持多位数折扣输入 Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click TextBoxTeclado1.Text &= "1" End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click TextBoxTeclado1.Text &= "2" End Sub Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click TextBoxTeclado1.Text &= "3" End Sub Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click TextBoxTeclado1.Text &= "4" End Sub Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click TextBoxTeclado1.Text &= "5" End Sub Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click TextBoxTeclado1.Text &= "6" End Sub Private Sub Button8_Click(sender As Object, e As EventArgs) Handles Button8.Click TextBoxTeclado1.Text &= "7" End Sub Private Sub Button9_Click(sender As Object, e As EventArgs) Handles Button9.Click TextBoxTeclado1.Text &= "8" End Sub Private Sub Button10_Click(sender As Object, e As EventArgs) Handles Button10.Click TextBoxTeclado1.Text &= "9" End Sub Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click TextBoxTeclado1.Text &= "0" End Sub Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click ' 退格处理,避免文本框为空时报错 If TextBoxTeclado1.Text.Length > 0 Then TextBoxTeclado1.Text = TextBoxTeclado1.Text.Remove(TextBoxTeclado1.Text.Length - 1, 1) End If End Sub Private Sub Button13_Click(sender As Object, e As EventArgs) Handles Button13.Click Dim percentagem As Decimal = 0D ' 安全解析用户输入的折扣值 If Decimal.TryParse(TextBoxTeclado1.Text, percentagem) Then ' 限制折扣范围在0-100之间,避免非法值 percentagem = Math.Clamp(percentagem, 0D, 100D) End If ' 正确计算折扣后金额:总金额 × (1 - 折扣百分比/100) Dim totalDesconto As Decimal If percentagem >= 100 Then totalDesconto = 0D ' 100%及以上折扣直接免单 Else totalDesconto = Total * (1 - percentagem / 100) End If ' 更新显示折扣后的金额 TxtBoxTotal.Text = $"{totalDesconto:C2}" MessageBox.Show($"折扣后金额:{totalDesconto:C2}") PanelDesconto.Hide() ' 计算完成后隐藏折扣面板 End Sub Private Sub BtnSair_Click(sender As Object, e As EventArgs) Handles BtnSair.Click PanelDesconto.Hide() End Sub End Class
关键修改说明
- 变量类型规范:将
Total声明为Decimal类型,彻底避免浮点运算的精度丢失问题,适合货币计算场景。 - 修复折扣值获取逻辑:删除覆盖用户输入的错误代码,确保能正确读取文本框中的折扣百分比。
- 修正折扣计算公式:使用
Total * (1 - percentagem / 100)计算折扣后金额,符合实际业务逻辑(如10%折扣即支付90%的金额)。 - 优化数字输入:将数字按钮的赋值逻辑改为追加输入,支持多位数折扣(如输入15表示15%折扣)。
- 安全解析与边界处理:用
Decimal.TryParse安全解析输入值,并用Math.Clamp限制折扣范围在0-100之间,避免非法值导致计算错误。 - 货币格式化显示:用
$"{Total:C2}"将总金额格式化为带两位小数的货币格式,适配欧洲地区显示习惯。
内容的提问来源于stack exchange,提问作者Airton Aguiar
相关产品推荐
相关产品推荐

