VBA 循环问题

VBA do loop issue

我正在努力完成一个学校项目。它使用用户表单并要求输入以创建三明治。我的问题是在循环完成一次后我无法让变量增加一个。 每次用户输入子项时,我都希望用户表单返回空白,并且他们的选择将在 excel sheet 上输入。这是我目前所拥有的

Private Sub btnAdd_Click()
Dim m As Integer

m = 1

    Do

        Select Case True

            Case optBreadRye.Value
                Range("C2").Offset(m, 0).Value = FormatCurrency(6)
                Range("D2").Offset(m, 0).Value = FormatCurrency(0)
                Range("E2").Offset(m, 0).Value = FormatCurrency(0)

            Case optBreadWheat.Value
                Range("D2").Offset(m, 0).Value = FormatCurrency(5)
                Range("C2").Offset(m, 0).Value = FormatCurrency(0)
                Range("E2").Offset(m, 0).Value = FormatCurrency(0)

            Case optBreadWhite.Value
               Range("E2").Offset(m, 0).Value = FormatCurrency(4)
               Range("C2").Offset(m, 0).Value = FormatCurrency(0)
               Range("D2").Offset(m, 0).Value = FormatCurrency(0)

        End Select

        If chkRoastBeef = True Then
             Range("F2").Offset(m, 0).Value = FormatCurrency(0.5)
                ElseIf chkRoastBeef = False Then
                    Range("F2").Offset(m, 0).Value = FormatCurrency(0)
        End If

        If chkChickenBreast = True Then
             Range("G2").Offset(m, 0).Value = FormatCurrency(0.5)
                ElseIf chkChickenBreast = False Then
                    Range("G2").Offset(m, 0).Value = FormatCurrency(0)
        End If

        If chkTurkeyBreast = True Then
             Range("H2").Offset(m, 0).Value = FormatCurrency(0.5)
                ElseIf chkTurkeyBreast = False Then
                    Range("h2").Offset(m, 0).Value = FormatCurrency(0)
        End If

        If chkHam = True Then
             Range("I2").Offset(m, 0).Value = FormatCurrency(0.5)
                ElseIf chkHam = False Then
                    Range("I2").Offset(m, 0).Value = FormatCurrency(0)
        End If

        If chkCheese = True Then
             Range("J2").Offset(m, 0).Value = FormatCurrency(0.5)
                ElseIf chkCheese = False Then
                    Range("j2").Offset(m, 0).Value = FormatCurrency(0)
        End If

        If chkVeggie = True Then
             Range("K2").Offset(m, 0).Value = FormatCurrency(0.5)
                ElseIf chkVeggie = False Then
                    Range("k2").Offset(m, 0).Value = FormatCurrency(0)
        End If

      Range("l2").Offset(m, 0).Value = lblPrice.Caption

    With frmOrder
        .chkCheese.Value = False
        .chkChickenBreast.Value = False
        .chkHam.Value = False
        .chkRoastBeef.Value = False
        .chkTurkeyBreast.Value = False
        .chkVeggie.Value = False
        .optBreadRye.Value = False
        .optBreadWheat.Value = False
        .optBreadWhite.Value = False
        .lblPrice.Caption = Format(0, "[=11=].00")

    End With


m = m + 1
Exit Do
Loop

End Sub

我知道这不是最好的格式或最有效的方法,但我的教授无论如何都帮不上忙。我一直在通过我们的 class 书和 google 学习一切。

我就是不能让 m 每次都上升一个。我认为这与 "Exit Do" "Loop" 或 "m = m + 1"

的位置有关

形式:

作品sheet:

更新电子表格是表单关注的 none。表单的工作是收集用户输入,句号。

你的循环没有退出条件,在第一次迭代结束时无条件退出:没用,去掉。

您需要一种方法让表单告诉其调用者 "hey, I have new data for you"。最好的方法是通过事件:

Public Event NewOrderLine(ByVal bread As BreadType, ByVal contents As Stuffing)

...和枚举:

Public Enum BreadType
    BreadType_None
    BreadType_Rye
    BreadType_Wheat
    BreadType_White
End Enum

Public Enum Stuffing
    Stuffing_None = 0
    Stuffing_RoastBeef = 2 ^ 0
    Stuffing_ChickenBreast = 2 ^ 1
    Stuffing_TurkeyBreast = 2 ^ 2
    Stuffing_Ham = 2 ^ 3
    Stuffing_Cheese = 2 ^ 4
    Stuffing_Veggie = 2 ^ 5
End Enum

现在,当单击表单的 [添加] 按钮时,它 运行 引发事件 并将参数传递给调用者:

Private Sub AddButton_Click()

    Dim bread As BreadType
    bread = SelectedBreadType

    Dim contents As Stuffing
    contents = SelectedStuffings

    RaiseEvent NewOrderLine(bread, contents)
    ClearFormFields

End Sub

Private Property Get SelectedBreadType() As BreadType
    Select Case True
        Case optBreadRye.Value
            SelectedBreadType = BreadType_Rye
        Case optBreadWheat.Value
            SelectedBreadType = BreadType_Wheat
        Case optBreadWhite.Value
            SelectedBreadType = BreadType_White
        Case Else
            SelectedBreadType = BreadType_None
    End Select
End Property

Private Property Get SelectedStuffings() As Stuffing
    Dim result As Stuffing
    If chkRoastBeef.Value Then result = result + Stuffing_RoastBeef
    If chkChickenBreast.Value Then result = result + Stuffing_ChickenBreast
    If chkTurkeyBreast.Value Then result = result + Stuffing_TurkeyBreast
    If chkHam.Value Then result = result + Stuffing_Ham
    If chkCheese.Value Then result = result + Stuffing_Cheese
    If chkVeggie.Value Then result = result + Stuffing_Veggie
    SelectedStuffings = result
End Property

请注意,Stuffing 值是累积的;它们的基础值是 2 的幂。这被称为 标志枚举 ,因为它像位掩码一样工作:您使用按位逻辑来确定 "flag" 是否包含在值:

Private Function HasFlag(ByVal value As Long, ByVal flag As Long) As Boolean
    HasFlag = (value And flag) = flag
End Function

回到工作表的代码隐藏,您可以这样做:

Option Explicit
Private WithEvents orderForm As frmOrder
Private currentOrderLine As Long

并处理 NewOrderLine 事件:

Private Sub orderForm_NewOrderLine(ByVal bread As BreadType, ByVal contents As Stuffing)
    'update the worksheet at currentOrderLine accordingly
End Sub

[Order] 按钮将负责分配 orderForm 对象引用:

Private Sub OrderButton_Click()
    Set orderForm = New frmOrder
    orderForm.Show
End Sub

我会制作一个专门用于计算价格的标准程序模块:

Option Explicit

Public Function GetBreadPrice(ByVal bread As BreadType)
    'you figure that out
End Function

Public Function GetContentsPrice(ByVal contents As Stuffing)
    'you figure that out
End Function

然后表单可以调用这些函数来"preview"订单的价格,工作表可以调用这些函数来计算实际的总订单金额。假设模块名为 Prices:

Private Sub UpdatePriceLabel()
    breadPrice = Prices.GetBreadPrice(bread)
    contentsPrice = Prices.GetContentsPrice(contents)
    totalPrice = breadPrice + contentsPrice
    lblPrice.Caption = Format(totalPrice, "[=18=].00")
End Sub