根据预定义的分隔符提取前n个字符

时间:2018-06-13 17:08:29

标签: vba ms-word word-vba

我目前有一个cope片段,允许我提取文件名的前6个字符,以插入文档页脚的右侧和页脚左侧的文件标题(不包括扩展名)。这一切都基于人物的立场,并达到了目的。但是,引入了复杂性。

我们之前的文件命名结构仅为"###### - [Title]"(我们有6位数字,空格,短划线,空格,标题)。我们现在有其他格式"######.## - [TITLE]"的文件名。我不相信我可以完全依靠角色位置来实现提取和插入。我正在寻找一些帮助,我可以设置代码以确定第7个字符是小数还是空格,并相应地将###########.##插入页脚。另一方面也是如此,我需要确定实际的标题(不依赖于位置,因为它取决于第一种情况。

感谢任何帮助。以下是当前代码。它可能不是最干净的,但它完成了工作:

Sub FooterFields(myFooterHL, myTotalPageCount, myFooterBold)

    sTitle = ActiveDocument.Name
    J = InStrRev(sTitle, ".")
    If J > 0 Then
        sTitle = Left(sTitle, J - 9)
        If Len(sTitle) > 5 Then
            sTitle = Left(sTitle, 9)
        End If

        Dim specTitle As String
        Dim specTitle2 As String
        Dim specTitleInt As String

        specTitle = ActiveDocument.Name
        If Right(specTitle, 5) = ".docx" Then
            specTitleInt = Left(specTitle, Len(specTitle) - 5)
            specTitle2 = Right(specTitleInt, Len(specTitleInt) - 9)
        ElseIf Right(specTitle, 4) = ".doc" Then
            specTitleInt = Left(specTitle, Len(specTitle) - 4)
            specTitle2 = Right(specTitleInt, Len(specTitleInt) - 9)
        Else
        End If

        sDiv = ActiveDocument.Name
        K = InStrRev(sDiv, ".")
        If K > 0 Then
            sDivIntermediate = Right(sDiv, K - 6)
            sDivFinal = specTitle2
            If Len(sDiv) > 5 Then
                sDivIntermediate = Right(sDiv, K - 6)
                sDivFinal = specTitle2
            End If

            If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
                ActiveWindow.Panes(2).Close
            End If
            If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
               ActivePane.View.Type = wdOutlineView Then
                ActiveWindow.ActivePane.View.Type = wdPrintView
            End If
            ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageFooter
            Selection.WholeStory
            Selection.Delete
            Selection.Font.AllCaps = True

            With Selection
                .Range.Text = sTitle
                .Range.InsertAlignmentTab wdRight, wdMargin
                .EndKey Unit:=wdLine
                .Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:="PAGE  ",
                PreserveFormatting:=True

                If myTotalPageCount = vbYes Then
                    .TypeText Text:="/"
                    .Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty,
                    Text:="NUMPAGES  ", PreserveFormatting:=True
                Else
                End If

                .HomeKey Unit:=wdLine
                .Range.Text = sDivFinal

            End With

            PageNumberAlignment:=wdAlignPageNumberRight, FirstPage:=True


            ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
        Else
            MsgBox "Document has no filename extension."
        End If
    End If

End Sub

1 个答案:

答案 0 :(得分:-1)

我建议您考虑using regular expressions。 (该链接用于在Excel下托管的VBA中使用正则表达式,但大多数信息也适用于在Word下托管的VBA。)

正则表达式的简短介绍:

  • 定义模式
  • 在字符串
  • 中找到与模式匹配的一个或多个匹配项

您可以使用以下模式匹配所有变体:

^\d{6}(?:\.\d{2}) - .*(?:\.doc|\.docx)$

Microsoft VBScript正则表达式5.5 库中添加引用(工具 - &gt; 引用... )。然后你可以使用以下内容:

Sub FooterFields2(myFooterHL, myTotalPageCount, myFooterBold)
    Dim re As New RegExp
    re.Pattern = "^(\d{6}(?:\.\d{2})) - (.*)(?:\.doc|\.docx)$"
    re.IgnoreCase = True

    Dim matches As MatchCollection
    Set matches = re.Execute(ActiveDocument.Name)
    If matches.Count = 0 Then
        MsgBox "Document name doesn't match"
        Exit Sub
    End If

    Dim match As match
    Set match = matches(0)

    Dim code As String, title As String
    code = match.SubMatches(0)
    title = match.SubMatches(1)

    'insert code and title in the appropriate location


End Sub

解释

Output of Expresso

\d - 匹配单个数字字符
\d{6} - 正好匹配6位数

\. - 匹配.。由于.是正则表达式语法的一部分,因此必须使用\进行转义 \.\d{2} - 匹配.后跟(如前所述)正好两位数 (?:\.\d{2}) - 群组\.\d{2},因此我们可以申请运营商。使用(?:(与(相对)进行分组不会将值存储在要单独引用的组中。 (?:\.\d{2})? - 匹配(?:\.\d{2})的零个或一个实例,因为标题可能包含小数和两个连续数字,或者它可能不是

- .* - 匹配空格,短划线和空格,后跟任意字符(*)的任意数字(.

\.doc|\.docx - 匹配.doc.docx
(?:\.doc|\.docx) - 将扩展的不同变体组合在一起,但不保存扩展名以供进一步使用

为了在我们与常规表现进行匹配后提取数字和标题,我们需要使用由括号表示的捕获组 - ()。在这种情况下,我们需要数字代码(第一个捕获组)和标题(第二个捕获组):

(\d{6}(?:\.\d{2})) - (.*)(?:\.doc|\.docx)

Output of Expresso, with capturing groups