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
我正在努力完成一个学校项目。它使用用户表单并要求输入以创建三明治。我的问题是在循环完成一次后我无法让变量增加一个。 每次用户输入子项时,我都希望用户表单返回空白,并且他们的选择将在 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