我一直在处理客户物料清单,其中包含用破折号分隔的编号,而不是完整的参考序列,例如。C1-4而不是C1、C2、C3、C4或C1 C2 C3 C4
有些客户会用逗号来分隔引用,有些只用空格,有时也会有两者混用的情况。有时客户会在引用的部分之间留下一个空行,这也会使事情变得复杂。空单元格在输出中应保持为空。下面是一个例子:
CR161-169
(blank line)
R2, R5, 7-11
R103-7
R26 R28-30 R42, R45-46, R62-65, R70-71, R92-102, R113-114
R31-35 R40-41 R56-61 R72-79 R86-91
(blank line)
LED1-4, 6-8
我正在尝试创建一个VBA宏,它将为references列的选定部分自动生成完整的引用集,并在它旁边的列中生成完整的引用集。
因此,我正在寻找的输出是:
CR161 CR162 CR163 CR164 CR165 CR166 CR167 CR168 CR169
(Blank line)
R2 R5 R7 R8 R9 R10 R11
R103 R104 R105 R106 R107
etc.
我遇到了一些(我认为相关的)问题。
1.在输出中,任何空行都不会保持空白,它们将填充来自其上方单元格的引用。
1.如果我选择整个列,它将进入一个无限循环,并使用最后一个单元格中的引用将整个列填充到引用末尾以下的无穷远处。我试图用End If来阻止它这样做,但显然我没有做对。
另一个让我抓狂的问题是R2,R5,7-11的情况,它输出为R2 R5 7 8 9 10 11,而不是R前缀。如果这个问题无法解决,那么对于我正在做的事情来说,这是可以接受的,但是在每个数字前面都有前缀是更可取的。
我不是伟大的VBA,但我得到了下面的代码运行没有抛出任何错误时,我只运行宏的选择参考,除了我上面提到的问题。任何帮助将不胜感激。
Sub ParseCell()
' Set the input range where your values are
Dim inputRange As Range, outputCell As Range, inputArea As Range
Dim inputCell As Variant
Dim startNum As Long, endNum As Long
Dim i As Long
Dim resList As String
Debug.Print "Selection_change"
Set inputRange = Selection ' Use the selected range as input
' Set the output range where you want the split references
Set outputCell = inputRange.Offset(0, 1).Cells(1) ' Output in the column next to the input
' Loop through each area in the input range
resList = ""
For Each inputArea In inputRange.Areas
' Loop through each cell in the area
For Each inputCell In inputArea
Set outputCell = inputCell.Offset(0, 1).Cells(1)
' Split the value by dash
Dim parts() As String
If Len(inputCell.Value) > 0 Then
resList = ""
ElseIf Len(inputCell.Value) = 0 Then ' blank cell
Debug.Print "blank"
'the same as previous
'resList = resList
ElseIf IsEmpty(inputCell) Then
Debug.Print "empty"
resList = ""
End If
If Len(inputCell.Value) > 0 Then
parts = Split(Replace(inputCell.Value, ",", " "), " ")
For i = LBound(parts) To UBound(parts)
If Len(Trim(parts(i))) > 0 Then
resList = resList & ExpandCellsList(Trim(parts(i))) & " "
End If
Next i
If Len(resList) > 0 Then resList = Left(resList, Len(resList) - 1)
End If
Debug.Print outputCell.Address, resList
outputCell.Value = resList
Next inputCell
Next inputArea
End Sub
Public Function ExpandCellsList(cl As String) As String
Dim i As Long
Dim sH As String, sv1 As String, sv2 As String
Dim startNum As Long, endNum As Long
Dim res As String
i = InStr(1, cl, "-")
If i > 0 Then
sv2 = Trim(Mid(cl, i + 1))
sH = Trim(Left(cl, i - 1))
For i = 1 To Len(sH)
If InStr(1, "01234567890", Mid(sH, i, 1)) > 0 Then
sv1 = Trim(Mid(sH, i))
sH = Trim(Left(sH, i - 1))
Exit For
End If
Next i
If Len(sv2) < Len(sv1) Then
sv2 = Left(sv1, Len(sv1) - Len(sv2)) & sv2
End If
startNum = Val(sv1)
endNum = Val(sv2)
If endNum > startNum Then
For i = startNum To endNum
res = res & sH & CStr(i) & " "
Next i
End If
If Len(res) > 0 Then res = Left(res, Len(res) - 1)
ExpandCellsList = res
Else
ExpandCellsList = cl
End If
End Function
2条答案
按热度按时间xytpbqjk1#
只有一些更正,请。检查。标记更改和添加。
gudnpqoy2#
这里的总体思路是首先得到字母(s),然后分别处理数字。然后,在结果字符串中,将在数字之前添加字母。让我们看看它是如何完成的。
首先在VB编辑器中添加一些引用。转到“工具”-“参考”并添加这些:
“ConvertReferences”过程首先填充客户端可能使用的分隔符字典:这可以是逗号、空格、分号等。但不是破折号。这是一本名为《替代品》的词典。
接下来,我们创建一个匹配第一个字母的RegEx模式。我们存储字母并继续数字。
现在“ParseOneCell”函数用于遍历选区中的每个单元格。我们去掉空格,标准化分隔符(使用“替换”字典),并使用标准分隔符(空格)得到数组“Arr”。“Arr”的值将进一步向下分析。我们将使用此数组中的项目来填充“Numbaz”集合。
在“Arr”数组中,我们可以有两种情况:1)带连字符的数字,2)单个数字。在第一种情况下,我们将使用“RangeFromNumbers”函数来创建一个很好的值范围,然后将其添加到“Numbaz”集合中。如果这是情况2,我们只需将数字转储到“Numbaz”集合。
在“RangeFromNumbers”函数中,特别注意处理缩短的数字,如7-11或103-7。对于像“7-11”这样的情况,我们创建了一个从第一个到最后一个数字的临时集合。对于像103-7这样的情况,我们使用“GetNumEndFromShortened”函数,将数字转换为字符串,反转它们并获得107作为最后一个数字,然后在“RangeFromNumbers”中使用它来生成所需的范围。
一旦“Numbaz”被填充了数字范围,我们就可以在它们前面加上字母代码,从而创建“Result”字符串。