在Excel 2010中将单元格内容划分为不同的行

我试图将长度大于72的单元格内容分割成长度不超过72个字符的单独行。 我无法通过这个逻辑来解决问题,需要帮助。 这里的特别挑战是每个单元格的内容是一个完整的句子,没有分隔符,所以我只需要在单词结束时划分语句,并且为每个单元格保留72个字符并且不超过这个长度。

有什么build议么?

谢谢

你可以使用正则expression式来做到这点。 试着将这个我刚才写的这个macros调整为符合你的具体要求:如果一个单词的长度超过了w字符,它就会溢出 – 对于72个字符的长度来说可能不是问题; 但您可以通过更改正则expression式来更改该行为。

正如所写的,macros将把分割文本写入原始单元格的下面。


 Sub WordWrap() 'requires reference to Microsoft VBScript Regular Expressions 5.5 'Wraps at W characters, but will allow overflow if a word is longer than W Dim RE As RegExp, MC As MatchCollection, m As Match Dim str As String Dim w As Long Dim rSrc As Range, C As Range Dim mBox As Long Dim I As Long 'with offset as 1, split data will be below original data 'with offset = 0, split data will replace original data Const lDestOffset As Long = 1 Set rSrc = Selection If rSrc.Rows.Count <> 1 Then MsgBox ("You may only select" & vbLf & " Data in One (1) Row") Exit Sub End If Set RE = New RegExp RE.Global = True w = InputBox("Maximum characters in a Line: ", , 72) If w < 1 Then w = 79 For Each C In rSrc str = C.Value 'remove all line feeds and nbsp RE.Pattern = "[\xA0\r\n\s]+" str = RE.Replace(str, " ") RE.Pattern = "\S.{0," & w - 1 & "}(?=\s|$)|\S{" & w & ",}" If RE.Test(str) = True Then Set MC = RE.Execute(str) 'see if there is enough room I = lDestOffset + 1 Do Until I > MC.Count + lDestOffset If Len(C(I, 1)) <> 0 Then mBox = MsgBox("Data in " & C(I, 1).Address & " will be erased if you contine", vbOKCancel) If mBox = vbCancel Then Exit Sub End If I = I + 1 Loop I = lDestOffset For Each m In MC C.Offset(I, 0).Value = m I = I + 1 Next m End If Next C Set RE = Nothing End Sub 

将原始post用作一个单元格中的数据的示例:

在这里输入图像说明

这里是一个解释和链接分解正则expression式的解释,因为它将以72个字符的行长度呈现。

。\ S {0,71}(= \ S |?$)| \ S {72,}

 \S.{0,71}(?=\s|$)|\S{72,} 

选项:区分大小写; 换行符($在这种情况下不相关)

  • 匹配这个替代 \S.{0,71}(?=\s|$)
    • 匹配不是“空白字符” \S 的单个字符
    • 匹配任何不是换行符的单个字符 .{0,71}
      • 在零次和71次之间,尽可能多的次数,根据需要给予(贪婪) {0,71}
    • 断言下面的正则expression式可以匹配,从这个位置开始(正向) (?=\s|$)
      • 匹配这个替代 \s
        • 匹配一个“空白字符” \s 的单个字符
      • 或者匹配这个替代 $
        • $ 行的末尾处声明位置
  • 或者匹配这个替代scheme \S{72,}
    • 匹配不是“空白字符”的单个字符 \S{72,}
      • 在72和无限次之间,尽可能多地按需要给予(贪婪) {72,}

用RegexBuddy创build

编辑应原始海报的要求,添加了一个例程,它将循环通过列A中的单元格,将分割的结果放到列B中。一些原始代码允许select行长度和源select,这是很难的-coded。


 Option Explicit Sub WordWrap2() 'requires reference to Microsoft VBScript Regular Expressions 5.5 'Wraps at W characters, but will allow overflow if a word is longer than W Dim RE As RegExp, MC As MatchCollection, M As Match Dim str As String Const W As Long = 72 Dim rSrc As Range, C As Range Dim vRes() As Variant Dim I As Long 'Set source to column A Set rSrc = Range("A1", Cells(Rows.Count, "A").End(xlUp)) Set RE = New RegExp RE.Global = True I = 0 For Each C In rSrc str = C.Value 'remove all line feeds and nbsp RE.Pattern = "[\xA0\r\n\s]+" str = RE.Replace(str, " ") RE.Pattern = "\S.{0," & W - 1 & "}(?=\s|$)|\S{" & W & ",}" If RE.Test(str) = True Then Set MC = RE.Execute(str) ReDim Preserve vRes(1 To MC.Count + I) For Each M In MC I = I + 1 vRes(I) = M Next M Else 'Allow preservation of blank lines in source data I = I + 1 End If Next C 'if ubound(vres) > 16384 then will need to transpose in a loop vRes = WorksheetFunction.Transpose(vRes) With Range("B1").Resize(UBound(vRes, 1)) .EntireColumn.Clear .Value = vRes .EntireColumn.AutoFit End With Set RE = Nothing End Sub 

这个怎么样:

 Sub Demo() Dim str As String Dim i As Long, rowIdx As Long Dim myString As Variant str = " " myString = Split(Range("A1").Value) rowIdx = 5 '-->row number from where data will be displayed For i = LBound(myString) To UBound(myString) If (Len(str) + Len(myString(i)) + 1) > 72 Then '-->check for length > 72 Range("A" & rowIdx).Value = Trim(str) '-->if > 72 display in cell rowIdx = rowIdx + 1 '-->increment row index str = "" 'set str="" to countinue for new line End If str = str & myString(i) & " " Next If Len(str) > 0 Then Range("A" & rowIdx).Value = Trim(str) 'display remiaing words End Sub 

在这里输入图像说明