使用前缀生成顺序代码的代码

时间:2016-12-26 09:07:30

标签: excel-vba vba excel

我有一个小的用户表单,包含1个组合框,2个文本框和1个命令按钮。图片已附上。enter image description here

下面还附有工作表的图像。 enter image description here

初始化Userform时,组合框中填充了表1中列出的帐户头。

从组合框中选择项目将使用表1中列出的帐户代码填充文本框。

将手动输入Group Head文本框。

以下是我的代码......

Private Sub ComboBox1_Change()
Dim ws As Worksheet, tbl As ListObject, rng As Range, cmb As ComboBox
Dim accountcode As String, rng1 As Range

Set ws = Sheets("Sheet1")
Set tbl = ws.ListObjects("Table1")
Set rng = tbl.ListColumns(1).DataBodyRange
Set rng1 = tbl.ListColumns(2).DataBodyRange


Me.TextBox1.Value = Application.WorksheetFunction.Index(rng, Application.WorksheetFunction.Match(Me.ComboBox1.Value, rng1, 0))


End Sub

Private Sub CommandButton1_Click()
Dim ws As Worksheet, tbl As ListObject, row As ListRow

Set ws = Sheets("Sheet1")
Set tbl = ws.ListObjects("Table2")
Set row = tbl.ListRows.Add

prefix = Me.TextBox1.Value & "-"

Dim NextNum As Long
Dim LastRow As Long, lRow As Long
Dim myArr() As Long

With Sheets("Sheet1")
'Find Last Row in Group Head Code Column
LastRow = .Cells(.Rows.Count, "E").End(xlUp).row

ReDim myArr(1 To LastRow)
' read all cells contents and convert them to array of numbers
For lRow = 5 To LastRow
    If Mid(.Cells(lRow, 5), 4) <> "" Then
        myArr(lRow) = CLng(Mid(.Cells(lRow, 5), 4))
    End If
Next lRow

' find maximum value in array
NextNum = WorksheetFunction.Max(myArr)

End With
row.Range(1, 1).Value = Me.ComboBox1.Value
row.Range(1, 2).Value = prefix & NextNum + 1
row.Range(1, 3).Value = Me.TextBox2.Value

End Sub

Private Sub UserForm_Initialize()
Dim ws As Worksheet, tbl As ListObject, rng As Range, cmb As ComboBox

Set ws = Sheets("Sheet1")
Set tbl = ws.ListObjects("Table1")
Set rng = tbl.ListColumns(2).DataBodyRange
Set cmb = Me.ComboBox1

For Each rng In rng
cmb.AddItem rng.Value
Next rng

End Sub

命令按钮读取表2中的值,COlumn和2,生成序列号并在表中发布值。

我想要的命令按钮是,如果我从组合框中选择任何其他头部,代码应该读取与该前缀相关联的值,然后生成下一个序列号。目前它没有读取前缀。

请告知我需要在命令按钮代码中进行哪些更改才能实现此目的。

由于 萨勒曼

1 个答案:

答案 0 :(得分:0)

我认为您遇到的问题是您尝试将Sheet1用作输出显示和数据存储系统。通常这不是问题,但在您的情况下,每次输入时都必须搜索Table2

最好在VBA中使用模块级变量来跟踪每个代码的递增数。每次进行选择时也无需查找Table 1。您可以将代码存储在另一个模块级变量中,也可以利用ComboBoxes具有多个列的功能。在下面的示例中,我已经选择了后者,因为很容易将ListObject直接读入组合框List属性 - 如果您想要使用相同的路径,那么您需要更改组合框ColumnCount属性为2,如果您希望代码不可见,请将ColumnWidths属性更改为0 pt;130 pt

然后,您的代码可能如下所示:

Option Explicit
Private mNextInc() As Long

Private Function IndexOf(val As String, arr As Variant) As Long
    Dim i As Long

    'Get array index of lookup item
    For i = 1 To UBound(arr, 1)
        If arr(i, 1) = val Then
            IndexOf = i
            Exit Function
        End If
    Next
End Function

Private Sub ComboBox1_Change()
    Me.TextBox1.Text = Me.ComboBox1.Value
End Sub

Private Sub CommandButton1_Click()
    Dim tbl As ListObject
    Dim rng As Range
    Dim v As Variant

    With Me.ComboBox1
        'Create the output array
        v = Array(.Text, _
                  .Value & "-" & mNextInc(.ListIndex), _
                  Me.TextBox2.Text)

        'Write new row to table
        Set tbl = ThisWorkbook.Worksheets("Sheet1") _
                 .ListObjects("Table2")
        tbl.Range.Activate
        If tbl.InsertRowRange Is Nothing Then
            Set rng = tbl.HeaderRowRange.Offset(tbl.ListRows.Count + 1)
        Else
            Set rng = tbl.InsertRowRange
        End If
        rng.Value = v

        'Increment the digit of code
        mNextInc(.ListIndex) = mNextInc(.ListIndex) + 1
    End With

End Sub

Private Sub UserForm_Initialize()
    Dim tbl As ListObject
    Dim lRow As ListRow
    Dim rng As Range
    Dim inc As Long
    Dim i As Long

    'Populate the combobox
    Set rng = ThisWorkbook.Worksheets("Sheet1") _
              .ListObjects("Table1").DataBodyRange
    Me.ComboBox1.List = rng.Value

    'Set the increment values to 1
    ReDim mNextInc(rng.Rows.Count - 1)
    For i = 1 To UBound(mNextInc)
        mNextInc(i) = 1
    Next

    'Find current max value for each group head code
    Set tbl = ThisWorkbook.Worksheets("Sheet1") _
              .ListObjects("Table2")
    For Each lRow In tbl.ListRows
        With lRow.Range
            i = IndexOf(.Cells(1), rng.Value)
            inc = CLng(Mid(.Cells(2), 4, Len(.Cells(2)) - 3)) + 1
        End With
        If inc > mNextInc(i) Then mNextInc(i) = inc
    Next

    'Set the combo box to first item
    Me.ComboBox1.ListIndex = 0
End Sub