You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET餐厅项目:如何从文本框计算折扣百分比?

餐厅订单折扣计算解决方案

问题概述

这是一个高中课业的餐厅订单程序,核心功能包括:

  • 选择菜品(当前仅Button1可添加单价1.45€的面包)
  • 点击保存按钮将订单内容保存至C:\Mesa1.txt,窗体加载时自动读取文件内容并显示
  • 需实现从文本框获取折扣百分比,正确计算并显示折扣后的最终总金额

现有代码核心问题

  1. Total变量未指定类型,默认是Object类型,易引发精度和类型错误
  2. 折扣计算按钮(Button13)中,错误执行TextBoxTeclado1.Text = percentagem,直接覆盖用户输入的折扣值,导致无法获取有效百分比
  3. 折扣计算公式错误:Total = Total * (100 - percentagem)会将总金额放大100倍,不符合实际折扣逻辑
  4. 数字按钮点击时直接覆盖文本框内容,无法输入多位数折扣(如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

关键修改说明

  1. 变量类型规范:将Total声明为Decimal类型,彻底避免浮点运算的精度丢失问题,适合货币计算场景。
  2. 修复折扣值获取逻辑:删除覆盖用户输入的错误代码,确保能正确读取文本框中的折扣百分比。
  3. 修正折扣计算公式:使用Total * (1 - percentagem / 100)计算折扣后金额,符合实际业务逻辑(如10%折扣即支付90%的金额)。
  4. 优化数字输入:将数字按钮的赋值逻辑改为追加输入,支持多位数折扣(如输入15表示15%折扣)。
  5. 安全解析与边界处理:用Decimal.TryParse安全解析输入值,并用Math.Clamp限制折扣范围在0-100之间,避免非法值导致计算错误。
  6. 货币格式化显示:用$"{Total:C2}"将总金额格式化为带两位小数的货币格式,适配欧洲地区显示习惯。

内容的提问来源于stack exchange,提问作者Airton Aguiar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 20:50:55