我使用的是Excel 2013(64位)。
我目前正在开发一个用于记录事件的Userform。但是,我一直无法在VBA中找到如何生成代码,该代码将导致上一行中的下一个可用数字填充用户表单中的INC数字文本框(ADD_txtSEC_INC_No)(然后相应地更新电子表格)。
结束格式应显示为IncYYYYMM-00000-示例:Inc201603-00456(这正是我所需要的)
我现在有一个代码(下面),它会显示下一个数字,但它不是所需的格式。开发中的新形式示例
Private Sub UserForm_Initialize()
'** SECURITY INCIDENT NUMBER IN TEXTBOX
'**WORKS
Me.ADD_txtSEC_INC_No.Enabled = True
Dim irow As Long
Dim ws As sw_SecIncidentDetails
Set ws = sw_SecIncidentDetails
'find last data row from database'
irow = ws.Cells(Rows.Count, 1).End(xlUp).Row
Me.ADD_txtSEC_INC_No.Text = ws.Cells(irow, 1).value + 1
End Sub
其他信息当此表格上线时,我需要将其从上一个编号继续使用,例如,如果我们当前工作表A行的公司编号为Inc201603-00456,则当表格初始化时,我将需要您的代码转到下一个公司编号,例如Inc201603-00457我们不能从0000开始编号,因为这会将序列从以前的条目中丢弃。如果这听起来令人困惑,很抱歉。
在B列中,我用一个名为ADD_Date_Recorded_TXT的文本框填充单元格,该文本框编码为:
Me.ADD_Date_Recorded_TXT.value = Format(Now, "dd/mm/yyyy")
我之所以提到这一点,是因为David下面的解决方案似乎将日期格式更改为mm/dd/yyyy(不明白为什么要这样做)-我需要所有日期都保持dd/mm/yyyy格式。
我只是觉得我应该在"附加信息"中解决这些问题,而不是单独回复每个
我发现使用最后一行来构建新的id是非常危险的。如果第一列未排序,那么可能会出现重复的标识符。因此,我将首先在第一列中搜索最大数字,然后递增该数字,最后格式化一个新的标识符:
Private Sub UserForm_Initialize()
'** SECURITY INCIDENT NUMBER IN TEXTBOX
'**WORKS
Me.ADD_txtSEC_INC_No.Enabled = True
Dim nextNumber As Long
Dim nextId As String
Dim ws As sw_SecIncidentDetails
Set ws = sw_SecIncidentDetails
' get the next record number from the first column
nextNumber = GetNextRecordNumber(ws.UsedRange.Columns(1))
' build the new record id
nextId = "Inc" & Format(Now, "yyyymm") & Format(nextNumber, "-00000")
Me.ADD_txtSEC_INC_No.text = nextId
End Sub
Private Function GetNextRecordNumber(source As Range) As Long
Dim max$, v
For Each v In source.value
If InStr(1, v, "Inc") = 1 And v > max Then max = v
Next
If max <> Empty Then GetNextRecordNumber = Split(max, "-")(1) + 1
End Function
据我所知,您的前一行有一个类似Inc201603-00455的事件编号,您需要为新的事件生成Inc201603-00456吗?如果是这样,请尝试将最后一行替换为:
Me.ADD_txtSEC_INC_No.Text = "Inc" & Year(Date) & Format(Month(Date), "00") & "-" & Format(Split(ws.Cells(irow, 1).value, "-")(1) + 1, "00000")
这将以您需要的格式组装您需要的所有片段。但这是假设您想要今天的日期,而不是从上一行中取消日期。如果你真的想复制前一行的日期,那么你应该使用这个:
Me.ADD_txtSEC_INC_No.Text = Split(ws.Cells(irow, 1).value, "-")(0) & "-" & Format(Split(ws.Cells(irow, 1).value, "-")(1) + 1, "00000")
我们使用Split函数来分割旧的事件编号,使用连字符作为分隔符。因此,第(0)部分是"Inc201603",第(1)部分是作为文本字符串的数字"00456"。但一旦你用它(+1)做数学运算,这个值就会变成一个纯数字,"456",所以这就是为什么我们使用Format函数再次给它一个五位数的掩码。
为了保证下一个可用数字,您应该在A列中COUNTIF上一个IncYYYYMM-nnnnn数字。
Private Sub UserForm_Initialize()
'** SECURITY INCIDENT NUMBER IN TEXTBOX
'**WORKS
Me.ADD_txtSEC_INC_No.Enabled = True
Dim i As Long, str As String
Dim ws As sw_SecIncidentDetails
Set ws = sw_SecIncidentDetails
'find last data row from database'
str = Format(Date, "Incyyyymm")
i = Application.CountIf(ws.Columns(1), str & Chr(42))
Me.ADD_txtSEC_INC_No.Text = str & Format(i, "-00000")
End Sub
这将动态工作。下个月,计数将在Inc201604-00000重新开始。