遍历段落并修剪MS Word中的空格

时间:2019-03-05 12:26:13

标签: vba ms-word

我需要创建一个宏,该宏将删除空白并在活动MS Word文档中的所有段落之前缩进。我尝试了以下操作:

For Each p In ActiveDocument.Paragraphs
    p.Range.Text = Trim(p.range.Text)
Next p

将宏设置为永恒循环。如果我尝试将字符串文字分配给段落,则vba始终仅创建1个段落:

For Each p In ActiveDocument.Paragraphs
    p.Range.Text = "test"
Next p

我认为我对段落对象有一个普遍的误解。对于这个问题的任何启发,我将不胜感激。

4 个答案:

答案 0 :(得分:1)

问题中的代码循环的原因是,用处理过的(修剪过的)文本替换一个段落会更改段落集合。因此,代码将在某个时刻连续处理同一段。

这是“在幕后”删除和重新创建对象的正常行为。解决该问题的方法是将集合从头到尾循环:

For i = ActiveDocument.Paragraphs.Count To 1 Step -1
    Set p = ActiveDocument.Paragraphs(i)
    p.Range.Text = Trim(p.Range.Text)
Next

也就是说,如果文档中的段落包含任何格式,则将会丢失。字符串处理不保留格式。

一种替代方法是检查每个段落的第一个字符,以查看您认为是“空白”的字符的种类。如果存在,请扩大范围,直到不再检测到这些字符,然后删除。这将保持格式不变。 (因为这不会更改整个段落,所以“正常”循环有效。)

Sub TestTrimParas()
    Dim p As Word.Paragraph
    Dim i As Long
    Dim rng As Word.Range

    For Each p In ActiveDocument.Paragraphs
        Set rng = p.Range.Characters.First
        'Test for a space or TAB character
        If rng.Text = " " Or rng.Text = Chr(9) Then
            i = rng.MoveEndWhile(" " + Chr(9))
            Debug.Print i
            rng.Delete
        End If
    Next p
End Sub

答案 1 :(得分:1)

当然,您可以在短时间内无循环地执行此操作,而无需使用查找/替换。例如:

Find = ^p^w
Replace = ^p

Find = ^w^p
Replace = ^p

作为宏,它变为:

Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
  .InsertBefore vbCr
  With .Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .Forward = True
    .Wrap = wdFindContinue
    .Format = False
    .MatchWildcards = False
    .Text = "^p^w"
    .Replacement.Text = "^p"
    .Execute Replace:=wdReplaceAll
    .Text = "^w^p"
    .Execute Replace:=wdReplaceAll
  End With
  .Characters.First.Text = vbNullString
End With
Application.ScreenUpdating = True
End Sub

还请注意,按照您的方式修剪文本可能会破坏所有段落内格式,交叉引用字段等;它也不会更改缩进。缩进可以通过选择整个文档并更改段落格式来删除;更好的是,修改基础样式(假设它们已正确使用)。

答案 2 :(得分:0)

进入“永恒”循环有点不愉快。只有查克·诺里斯(Chuck Norris)可以退出。无论如何,请尝试在修整之前进行检查,并且它不会输入:

Sub TestMe()

    Dim p As Paragraph
    For Each p In ThisDocument.Paragraphs
        If p.Range <> Trim(p.Range) Then p.Range = Trim(p.Range)
    Next p

End Sub

答案 3 :(得分:0)

我看到了很多解决方案,这些对我来说很有效。注意我关闭了跟踪更改,然后恢复为原始文档跟踪状态。

我希望这对某些人有帮助。

SELECT t1.*, IFNULL(t2.TotalUnits,0) AS TotalUnits, ROUND(IFNULL(t2.totalRevenue,0),0) AS TotalRevenue FROM (SELECT BranchDept, ForPeriod, SUM(SysGen) AS Gen, SUM(UserInput) as Live, SUM(PrevYear) AS LastYr, SUM(SysGen) - SUM(UserInput) AS Input FROM tbl_demand_forecast_details WHERE BranchDept='" + req.body.branchdept + "' AND ForPeriod >= '" + fystart + "' " +
        "AND ForPeriod <= '" + fyend + "' GROUP BY BranchDept, ForPeriod " +
        "ORDER BY ForPeriod) AS t1 " +
        "LEFT OUTER JOIN " +
        "(SELECT BranchDept, AsOfPeriod, SUM(UnitSales) AS totalUnits, SUM(PesoSales) AS totalRevenue FROM tbl_sales_history " + 
        "WHERE BranchDept='" + req.body.branchdept + "' AND AsOfPeriod >= '" + fystart + "' AND AsOfPeriod <= '" + fyend + "' GROUP BY AsOfPeriod) AS t2 " +
        "ON t1.BranchDept = t2.BranchDept AND t1.ForPeriod = t2.AsOfPeriod