存储来自用户表单的变量 VBA
Storing Variables from userforms VBA
我想将 ComboBox1 和 ComboBox2 的值保存为我可以在模块 I return 中使用的变量,一旦用户正确完成了用户表单,但我不确定如何执行此操作。
Option Explicit
Private isCancelled As Boolean
Public Property Get Cancelled() As Boolean
Cancelled = isCancelled
End Property
Private Sub CancelButton1_Click()
isCancelled = True
Me.Hide
End Sub
Public Property Get Benefit() As String
Benefit = IIf(Me.ComboBox1.ListIndex = -1, vbNullString, Me.ComboBox1.Text)
End Property
Public Property Get Costdelivery() As String
Costdelivery = IIf(Me.ComboBox2.ListIndex = -1, vbNullString, Me.ComboBox2.Text)
End Property
Private Sub ComboBox1_Change()
ValidateForm
End Sub
Private Sub ComboBox2_Change()
ValidateForm
End Sub
Private Sub ValidateForm()
Me.Okbutton1.Enabled = (Benefit <> vbNullString And Costdelivery <> vbNullString)
End Sub
Private Sub UserForm_Activate()
ValidateForm
End Sub
Private Sub UserForm_Initialize()
'populate "Combo-Box with Boards
With Me.ComboBox1
.Clear ' clear previous items (not to have "doubles")
.AddItem "Very High"
.AddItem "High"
.AddItem "Medium"
.AddItem "Low"
End With
With Me.ComboBox2
.Clear ' clear previous items (not to have "doubles")
.AddItem "Very High"
.AddItem "High"
.AddItem "Medium"
.AddItem "Low"
End With
End Sub
Private Sub Okbutton1_Click()
Dim Ben As Long
Ben = Me.ComboBox1.Value ***ERROR
Dim Cost As Long
Cost = Me.ComboBox2.Value **** ERROR
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
isCancelled = True
Me.Hide
End If
End Sub
理想情况下,我想将低、中、高或非常高的值存储为值 9、10、11、12,因为我将在模块 I return 之后将这些用作单元格引用用户窗体已关闭。
我知道我需要说明 public 属性 我的尝试无效,如下所示;
Public Function ConfidenceChart()
Dim ben As Long, costd As Long
ben = UserForm4.ComboBox1.Text
If ben = "Low" Then ben = 9
If ben = "Medium" Then ben = 8
If ben = "High" Then ben = 7
If ben = "Very High" Then ben = 6
costd = UserForm4.ComboBox2.Text
If costd = "Low" Then costd = 12
If costd = "Medium" Then costd = 13
If costd = "High" Then costd = 14
If costd = "Very High" Then costd = 15
End Function
Excel 控件允许您对单元格进行 link 控件。这样,您可以存储控件的值以备后用。
用户窗体控件使用 ControlSource
属性 来建立此 link。在下面的演示中,我在设置页面上创建了两个命名范围(以控件名称命名以便于参考)并将控件 ControlSource
属性 设置为命名范围。
附录
@Mat'sMug 指出 OP 需要根据 ComboBox 中的选择来存储查找列表中的值。这也可以使用命名范围来实现。
Private Sub UserForm_Initialize()
'populate "Combo-Box with Boards
With Me.ComboBox1
.RowSource = "List1"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
End With
With Me.ComboBox2
.RowSource = "List2"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
End With
End Sub
您将需要更改组合框的一些属性。
Private Sub UserForm_Initialize()
'populate "Combo-Box with Boards
With Me.ComboBox1
.RowSource = "List1"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
.ControlSource = "ComboBox1"
End With
With Me.ComboBox2
.RowSource = "List2"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
.ControlSource = "ComboBox2"
End With
End Sub
Ben
和 Cost
是 locals,它们仅在 Click
处理程序中可见。
知道这些值需要在哪里结束不是表单的工作 - 表单只是用来收集用户输入。
您已经具有调用者能够访问的Benefit
和CostDelivery
属性。
使用它们!
With New UserForm1 'whatever the name of that form is
.Show
If Not .Cancelled Then
Sheet1.Range("A1").Value = .Benefits
Sheet1.Range("B1").Value = .CostDelivery
End If
End With
如果您需要它们是数值,那么您没有正确填充组合框。
您没有将 "Very High"
映射到 12
,组合框只知道字符串。
为此,您需要更改此设置:
With Me.ComboBox1
.Clear ' clear previous items (not to have "doubles")
.AddItem "Very High"
.AddItem "High"
.AddItem "Medium"
.AddItem "Low"
End With
并将Me.ComboBox1.List
分配给一个二维数组。或者一个 Range
,如果你有一个看起来像这样的:
A B
15 Very High
14 High
13 Medium
12 Low
你可以有一个这样的辅助方法:
Private Sub PopulateFromRange(ByVal control As MSForms.ComboBox, ByVal source As Range, Optional ByVal valueColumn As Long = 1, Optional ByVal hasHeader As Boolean = True)
With control
.ColumnCount = source.Columns.Count
.ColumnWidths = GetColumnWidths(source)
.ListWidth = IIf(control.Width > source.Width, control.Width, source.Width)
.List = source.Range(source.Rows(IIf(hasHeader, 2, 1)).EntireRow, source.Rows(source.Rows.Count).EntireRow).Value
.BoundColumn = valueColumn
End With
End Sub
Private Function GetColumnWidths(ByVal source As Range) As String
Dim cols As Long
cols = source.Columns.Count
Dim widths()
ReDim widths(1 To cols)
Dim col As Long
For col = 1 To cols
widths(col) = source(, col).Width
Next
GetColumnWidths = Join(widths, ",")
End Function
(取自this post specifically about populating combobox and listbox controls from ranges)
并像这样填充您的组合框:
PopulateFromRange Me.ComboBox1, DataSheet.Range("A1:B5")
PopulateFromRange Me.ComboBox2, DataSheet.Range("D1:E5")
假设您有一个 DataSheet
工作表,范围 [A1:B5]
和 [D1:E5]
分别包含每个项目的文本和相应的数值。
我想将 ComboBox1 和 ComboBox2 的值保存为我可以在模块 I return 中使用的变量,一旦用户正确完成了用户表单,但我不确定如何执行此操作。
Option Explicit
Private isCancelled As Boolean
Public Property Get Cancelled() As Boolean
Cancelled = isCancelled
End Property
Private Sub CancelButton1_Click()
isCancelled = True
Me.Hide
End Sub
Public Property Get Benefit() As String
Benefit = IIf(Me.ComboBox1.ListIndex = -1, vbNullString, Me.ComboBox1.Text)
End Property
Public Property Get Costdelivery() As String
Costdelivery = IIf(Me.ComboBox2.ListIndex = -1, vbNullString, Me.ComboBox2.Text)
End Property
Private Sub ComboBox1_Change()
ValidateForm
End Sub
Private Sub ComboBox2_Change()
ValidateForm
End Sub
Private Sub ValidateForm()
Me.Okbutton1.Enabled = (Benefit <> vbNullString And Costdelivery <> vbNullString)
End Sub
Private Sub UserForm_Activate()
ValidateForm
End Sub
Private Sub UserForm_Initialize()
'populate "Combo-Box with Boards
With Me.ComboBox1
.Clear ' clear previous items (not to have "doubles")
.AddItem "Very High"
.AddItem "High"
.AddItem "Medium"
.AddItem "Low"
End With
With Me.ComboBox2
.Clear ' clear previous items (not to have "doubles")
.AddItem "Very High"
.AddItem "High"
.AddItem "Medium"
.AddItem "Low"
End With
End Sub
Private Sub Okbutton1_Click()
Dim Ben As Long
Ben = Me.ComboBox1.Value ***ERROR
Dim Cost As Long
Cost = Me.ComboBox2.Value **** ERROR
Me.Hide
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
isCancelled = True
Me.Hide
End If
End Sub
理想情况下,我想将低、中、高或非常高的值存储为值 9、10、11、12,因为我将在模块 I return 之后将这些用作单元格引用用户窗体已关闭。
我知道我需要说明 public 属性 我的尝试无效,如下所示;
Public Function ConfidenceChart()
Dim ben As Long, costd As Long
ben = UserForm4.ComboBox1.Text
If ben = "Low" Then ben = 9
If ben = "Medium" Then ben = 8
If ben = "High" Then ben = 7
If ben = "Very High" Then ben = 6
costd = UserForm4.ComboBox2.Text
If costd = "Low" Then costd = 12
If costd = "Medium" Then costd = 13
If costd = "High" Then costd = 14
If costd = "Very High" Then costd = 15
End Function
Excel 控件允许您对单元格进行 link 控件。这样,您可以存储控件的值以备后用。
用户窗体控件使用 ControlSource
属性 来建立此 link。在下面的演示中,我在设置页面上创建了两个命名范围(以控件名称命名以便于参考)并将控件 ControlSource
属性 设置为命名范围。
附录
@Mat'sMug 指出 OP 需要根据 ComboBox 中的选择来存储查找列表中的值。这也可以使用命名范围来实现。
Private Sub UserForm_Initialize()
'populate "Combo-Box with Boards
With Me.ComboBox1
.RowSource = "List1"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
End With
With Me.ComboBox2
.RowSource = "List2"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
End With
End Sub
您将需要更改组合框的一些属性。
Private Sub UserForm_Initialize()
'populate "Combo-Box with Boards
With Me.ComboBox1
.RowSource = "List1"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
.ControlSource = "ComboBox1"
End With
With Me.ComboBox2
.RowSource = "List2"
.ColumnCount = 2
.ColumnWidths = "0 pt;49.95 pt"
.ControlSource = "ComboBox2"
End With
End Sub
Ben
和 Cost
是 locals,它们仅在 Click
处理程序中可见。
知道这些值需要在哪里结束不是表单的工作 - 表单只是用来收集用户输入。
您已经具有调用者能够访问的Benefit
和CostDelivery
属性。
使用它们!
With New UserForm1 'whatever the name of that form is
.Show
If Not .Cancelled Then
Sheet1.Range("A1").Value = .Benefits
Sheet1.Range("B1").Value = .CostDelivery
End If
End With
如果您需要它们是数值,那么您没有正确填充组合框。
您没有将 "Very High"
映射到 12
,组合框只知道字符串。
为此,您需要更改此设置:
With Me.ComboBox1
.Clear ' clear previous items (not to have "doubles")
.AddItem "Very High"
.AddItem "High"
.AddItem "Medium"
.AddItem "Low"
End With
并将Me.ComboBox1.List
分配给一个二维数组。或者一个 Range
,如果你有一个看起来像这样的:
A B
15 Very High
14 High
13 Medium
12 Low
你可以有一个这样的辅助方法:
Private Sub PopulateFromRange(ByVal control As MSForms.ComboBox, ByVal source As Range, Optional ByVal valueColumn As Long = 1, Optional ByVal hasHeader As Boolean = True)
With control
.ColumnCount = source.Columns.Count
.ColumnWidths = GetColumnWidths(source)
.ListWidth = IIf(control.Width > source.Width, control.Width, source.Width)
.List = source.Range(source.Rows(IIf(hasHeader, 2, 1)).EntireRow, source.Rows(source.Rows.Count).EntireRow).Value
.BoundColumn = valueColumn
End With
End Sub
Private Function GetColumnWidths(ByVal source As Range) As String
Dim cols As Long
cols = source.Columns.Count
Dim widths()
ReDim widths(1 To cols)
Dim col As Long
For col = 1 To cols
widths(col) = source(, col).Width
Next
GetColumnWidths = Join(widths, ",")
End Function
(取自this post specifically about populating combobox and listbox controls from ranges)
并像这样填充您的组合框:
PopulateFromRange Me.ComboBox1, DataSheet.Range("A1:B5")
PopulateFromRange Me.ComboBox2, DataSheet.Range("D1:E5")
假设您有一个 DataSheet
工作表,范围 [A1:B5]
和 [D1:E5]
分别包含每个项目的文本和相应的数值。