使用当前行的记录填充用户表单
Populate userform with records from current row
我有一个包含多个文本框、单选按钮、下拉列表等的用户表单。当用户创建新条目时,数据保存在数据 sheet 中,一条记录占据一行。现在我希望能够单击 A 列中的 "edit" 按钮,该按钮允许加载预加载了该行数据的用户表单。
问题是加载表单时,初始化宏将所有表单字段重置为“”,我还没有想出如何告诉VBA加载调用行的数据。
关于如何解决这个问题有什么建议吗?
这里是我目前的代码:
单击“新建条目”按钮时调用用户表单
Sub call_userform()
Details.Show
End Sub
用户窗体初始化时:
Private Sub UserForm_Initialize()
IC_logo.BackColor = RGB(81, 81, 73) ' ash grey
'Empty all fields
status.Value = "Open"
serial = Evaluate("randbetween(10000,30000)")
priority.Value = ""
created_on.Value = Format(Date, "dd/mm/yyyy")
created_by.Value = ""
department.Value = ""
floor.Value = ""
area.Value = ""
subarea.Value = ""
details.Value = ""
fu_name.Value = ""
fu_department = ""
Me.status.RowSource = "lst_status" 'Fill Status
Me.priority.RowSource = "lst_priority" 'Fill Priorities
created_by = Sheets("Settings").Range("B24") 'Fill Created By with Logon Username
department = Sheets("Settings").Range("B25") 'Fill Created By with Logon Department
Me.floor.RowSource = "lst_floor" 'Fill Floor
Me.area.RowSource = "lst_area" 'Fill Area
Me.subarea.RowSource = "lst_subarea" 'Fill Subarea
'Set follow up to construction company as per default
'fu_2.Value = True
'Set Focus on NameTextBox
priority.SetFocus
End Sub
单击“保存”按钮时
Private Sub btn_save_Click()
Dim emptyRow As Long
'Activate Data sheet
Sheets("Data").Activate
'Determine emptyRow
emptyRow = WorksheetFunction.CountA(Range("B:B")) + 1
'Transfer information
Cells(emptyRow, 2).Value = serial.Value
Cells(emptyRow, 4).Value = created_on.Value
Cells(emptyRow, 5).Value = created_by.Value
Cells(emptyRow, 6).Value = priority.Value
Cells(emptyRow, 7).Value = floor.Value
Cells(emptyRow, 8).Value = area.Value
Cells(emptyRow, 9).Value = subarea.Value
Cells(emptyRow, 10).Value = details.Value
If fu_1.Value = True Then
Cells(emptyRow, 11).Value = fu_1.Caption
End If
If fu_2.Value = True Then
Cells(emptyRow, 11).Value = fu_2.Caption
End If
If fu_3.Value = True Then
Cells(emptyRow, 11).Value = fu_3.Caption
End If
If fu_4.Value = True Then
Cells(emptyRow, 11).Value = fu_4.Caption
End If
If fu_name.Value > 0 Or fu_department.Value > 0 Then
Cells(emptyRow, 12).Value = fu_name.Value & " " & fu_department.Value
End If
Cells(emptyRow, 13).Value = status.Value
End Sub
如前所述,现在的问题是如何将当前行的数据加载到用户窗体?那还是通过 details.show
吗?
如果您的 sheet 上有一个按钮来调用表单,那么只需使用如下内容:
me.TextBox1.value = Cells(ActiveCell.Row, 2).Value 'ActiveCell.Row returns the row number of the current cell
所以按钮的唯一命令是 UserForm1.Show
您可以编写一个像 loadDataIntoForm(rowNum As Long)
这样的子程序,根据您的喜好填写表单的字段,并将其放入用户表单的代码中。
例如
Public Sub loadDataIntoForm(rowNum As Long)
me.somecontrol.Value = Sheets("Data").cells(rowNum,1).Value
'...
End Sub
然后如果点击编辑按钮执行
Details.loadDataIntoForm(rowNum) 'where rowNum is something like ActiveCell.Row. This calls UserForm_Initialize and THEN loadDataIntoForm
Details.Show 'UserForm_Initialize won't get executed again
UserForm_Initialize
在 loadDataIntoForm
之前执行,因此字段首先由 UserForm_Initialize
函数清除,然后由 loadDataIntoForm
重新填充。为确保您也可以先加载表单
Load Details
Details.loadDataIntoForm(ActiveCell.Row)
Details.Show
所以你可以确定 UserForm_Initialize
没有在 loadDataIntoForm
之后调用。
当您可以使用 F8 逐行浏览代码时,了解调用的内容。
编辑:更好的方法可能是编写两个子程序,一个用于为编辑初始化表单(填充字段),一个用于为新记录初始化表单(清除字段)
它可能看起来像
Public Sub ShowNew()
'clear all the controls
me.Show
End Sub
Public Sub ShowEdit(rowNum As Long)
'populate the controls
me.Show
End Sub
然后使用 Details.ShowNew
和 Details.ShowNew(rowNum)
而不是 Details.Show
我会像下面这样:
使用 UserForm
对象的 Tag
属性 来存储一个 "calling parameter" ,它将告诉用户窗体是否要 运行 一个 InitializeValues()
子或 FillValues()
一个
使用 UserForm_Activate
事件处理程序让用户窗体决定要采取的操作
所以,假设您将 Edit()
sub 附加到 sheet "edit" 按钮,前者将是
Sub Edit()
With UserForm3
.Tag = ActiveSheet.Shapes(Application.Caller).TopLeftCell.Row '<~~ tell the UserForm there's something to bring in so that it'll fill controls from the sheet instead of initializing them
.Show
.Tag = "" '<~~ bring Tag property back to its "null" value
End With
Unload UserForm3
End Sub
然后在您的用户窗体代码窗格中放置这个
Private Sub UserForm_Activate()
If Me.Tag = "" Then '<~~ if there's no info from Tag property...
InitializeValues '<~~ ... then Initialize controls values
Else
FillValues '<~~ ...otherwise fill controls with sheet values
End If
End Sub
Private Sub InitializeValues()
With Me
.ComboBox1.RowSource = "initRange"
.serial.Value = "actText1"
.created_on.Value = "actText2"
.created_by.Value = "actText3"
' and so on...
End With
End Sub
Private Sub FillValues()
With Me
.serial.Value = Cells(.Tag, 2).Value
.created_on.Value = Cells(.Tag, 4).Value
.created_by.Value = Cells(.Tag, 5).Value
'.. and so on
End With
End Sub
我有一个包含多个文本框、单选按钮、下拉列表等的用户表单。当用户创建新条目时,数据保存在数据 sheet 中,一条记录占据一行。现在我希望能够单击 A 列中的 "edit" 按钮,该按钮允许加载预加载了该行数据的用户表单。
问题是加载表单时,初始化宏将所有表单字段重置为“”,我还没有想出如何告诉VBA加载调用行的数据。
关于如何解决这个问题有什么建议吗?
这里是我目前的代码: 单击“新建条目”按钮时调用用户表单
Sub call_userform()
Details.Show
End Sub
用户窗体初始化时:
Private Sub UserForm_Initialize()
IC_logo.BackColor = RGB(81, 81, 73) ' ash grey
'Empty all fields
status.Value = "Open"
serial = Evaluate("randbetween(10000,30000)")
priority.Value = ""
created_on.Value = Format(Date, "dd/mm/yyyy")
created_by.Value = ""
department.Value = ""
floor.Value = ""
area.Value = ""
subarea.Value = ""
details.Value = ""
fu_name.Value = ""
fu_department = ""
Me.status.RowSource = "lst_status" 'Fill Status
Me.priority.RowSource = "lst_priority" 'Fill Priorities
created_by = Sheets("Settings").Range("B24") 'Fill Created By with Logon Username
department = Sheets("Settings").Range("B25") 'Fill Created By with Logon Department
Me.floor.RowSource = "lst_floor" 'Fill Floor
Me.area.RowSource = "lst_area" 'Fill Area
Me.subarea.RowSource = "lst_subarea" 'Fill Subarea
'Set follow up to construction company as per default
'fu_2.Value = True
'Set Focus on NameTextBox
priority.SetFocus
End Sub
单击“保存”按钮时
Private Sub btn_save_Click()
Dim emptyRow As Long
'Activate Data sheet
Sheets("Data").Activate
'Determine emptyRow
emptyRow = WorksheetFunction.CountA(Range("B:B")) + 1
'Transfer information
Cells(emptyRow, 2).Value = serial.Value
Cells(emptyRow, 4).Value = created_on.Value
Cells(emptyRow, 5).Value = created_by.Value
Cells(emptyRow, 6).Value = priority.Value
Cells(emptyRow, 7).Value = floor.Value
Cells(emptyRow, 8).Value = area.Value
Cells(emptyRow, 9).Value = subarea.Value
Cells(emptyRow, 10).Value = details.Value
If fu_1.Value = True Then
Cells(emptyRow, 11).Value = fu_1.Caption
End If
If fu_2.Value = True Then
Cells(emptyRow, 11).Value = fu_2.Caption
End If
If fu_3.Value = True Then
Cells(emptyRow, 11).Value = fu_3.Caption
End If
If fu_4.Value = True Then
Cells(emptyRow, 11).Value = fu_4.Caption
End If
If fu_name.Value > 0 Or fu_department.Value > 0 Then
Cells(emptyRow, 12).Value = fu_name.Value & " " & fu_department.Value
End If
Cells(emptyRow, 13).Value = status.Value
End Sub
如前所述,现在的问题是如何将当前行的数据加载到用户窗体?那还是通过 details.show
吗?
如果您的 sheet 上有一个按钮来调用表单,那么只需使用如下内容:
me.TextBox1.value = Cells(ActiveCell.Row, 2).Value 'ActiveCell.Row returns the row number of the current cell
所以按钮的唯一命令是 UserForm1.Show
您可以编写一个像 loadDataIntoForm(rowNum As Long)
这样的子程序,根据您的喜好填写表单的字段,并将其放入用户表单的代码中。
例如
Public Sub loadDataIntoForm(rowNum As Long)
me.somecontrol.Value = Sheets("Data").cells(rowNum,1).Value
'...
End Sub
然后如果点击编辑按钮执行
Details.loadDataIntoForm(rowNum) 'where rowNum is something like ActiveCell.Row. This calls UserForm_Initialize and THEN loadDataIntoForm
Details.Show 'UserForm_Initialize won't get executed again
UserForm_Initialize
在 loadDataIntoForm
之前执行,因此字段首先由 UserForm_Initialize
函数清除,然后由 loadDataIntoForm
重新填充。为确保您也可以先加载表单
Load Details
Details.loadDataIntoForm(ActiveCell.Row)
Details.Show
所以你可以确定 UserForm_Initialize
没有在 loadDataIntoForm
之后调用。
当您可以使用 F8 逐行浏览代码时,了解调用的内容。
编辑:更好的方法可能是编写两个子程序,一个用于为编辑初始化表单(填充字段),一个用于为新记录初始化表单(清除字段)
它可能看起来像
Public Sub ShowNew()
'clear all the controls
me.Show
End Sub
Public Sub ShowEdit(rowNum As Long)
'populate the controls
me.Show
End Sub
然后使用 Details.ShowNew
和 Details.ShowNew(rowNum)
Details.Show
我会像下面这样:
使用
UserForm
对象的Tag
属性 来存储一个 "calling parameter" ,它将告诉用户窗体是否要 运行 一个InitializeValues()
子或FillValues()
一个使用
UserForm_Activate
事件处理程序让用户窗体决定要采取的操作
所以,假设您将 Edit()
sub 附加到 sheet "edit" 按钮,前者将是
Sub Edit()
With UserForm3
.Tag = ActiveSheet.Shapes(Application.Caller).TopLeftCell.Row '<~~ tell the UserForm there's something to bring in so that it'll fill controls from the sheet instead of initializing them
.Show
.Tag = "" '<~~ bring Tag property back to its "null" value
End With
Unload UserForm3
End Sub
然后在您的用户窗体代码窗格中放置这个
Private Sub UserForm_Activate()
If Me.Tag = "" Then '<~~ if there's no info from Tag property...
InitializeValues '<~~ ... then Initialize controls values
Else
FillValues '<~~ ...otherwise fill controls with sheet values
End If
End Sub
Private Sub InitializeValues()
With Me
.ComboBox1.RowSource = "initRange"
.serial.Value = "actText1"
.created_on.Value = "actText2"
.created_by.Value = "actText3"
' and so on...
End With
End Sub
Private Sub FillValues()
With Me
.serial.Value = Cells(.Tag, 2).Value
.created_on.Value = Cells(.Tag, 4).Value
.created_by.Value = Cells(.Tag, 5).Value
'.. and so on
End With
End Sub