使用当前行的记录填充用户表单

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_InitializeloadDataIntoForm 之前执行,因此字段首先由 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.ShowNewDetails.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