Извлечение ТОЛЬКО ПЕРВОГО совпадения из Word do c с использованием RegEx, запущенного из Excel VBA - PullRequest
0 голосов
/ 16 февраля 2020

Существует такой документ, как этот. Каждый день я обрабатываю 20 таких документов, и все они выглядят одинаково (структура, я имею в виду, очень последовательная).

enter image description here

Цель этого макрос предназначен для извлечения ТОЛЬКО ПЕРВОГО совпадения шаблона RegEx из .ActiveDocument.Content. В целом до c есть еще много совпадений, но мне нужен только первый. Обрабатываемый документ будет открыт перед запуском макроса вручную.

Я всего лишь новичок в VBA, поэтому, если есть возможность написать его без использования массивов, сборников или некоторых словарей, я был бы очень признателен. Извлечь можно только один элемент, поэтому лучше всего загрузить его внутри строковой переменной repNmbr, а оттуда просто ws.Range("G30").Value = repNmbr. Чем проще, тем лучше.

Я использовал эти ресурсы Учебник по регулярным выражениям Excel (регулярные выражения) , что очень полезно, но я до сих пор не знаю, как загрузить ПЕРВЫЙ МАТЧ в мое repNmbr строковая переменная. Я хотел бы сделать это без использования l oop, потому что я просто хочу загрузить одну строку в эту переменную repNmbr.

В настоящее время у меня есть такой код:

Sub ExtractRepertor03()
    'Application.ScreenUpdating = False
    Dim WordApp As Word.Application
    Dim WordDoc As Word.Document
    Dim ExcelApp As Excel.Application
    Dim rng As Word.Range
    Dim ws As Worksheet
    Dim regEx As Object
    Dim matches As MatchCollection
    Dim match As String
    Dim repNmbr As String

    'Assigning object variables
    Set WordApp = GetObject(, "Word.Application")      'ActiveX can't create object is when
    Set ExcelApp = GetObject(, "Excel.Application")    'there is no Word document open;
    Set regEx = CreateObject("VBScript.RegExp")
    Set WordDoc = WordApp.ActiveDocument
    Set rng = WordApp.ActiveDocument.Content

    'Create the regular expression object
    regEx.Global = False    'because I need only the first match instead of all occurences;
    regEx.IgnoreCase = True
    regEx.Pattern = "([0-9]{1,5})([ ]{0,4})([/])([0-9]{4})"
    'regEx.Pattern = "([0-9]{1,5})([\s]{0,4})(/[0-9]{4})"

    repNmbr = regEx.Execute(rng.text)      'here is something wrong but I don't know what;
                            'I'm trying to assign the first RegEx match to repNmbr variable;
    Debug.Print repNmbr
    repNmbr = Replace(repNmbr, " ", "") 
'    Set matches = regEx.Execute(rng.text)
'    Debug.Print regEx.Test(rng)
'    'Debug.Print regEx.Value
'        For Each match In matches    'I just want this macro run without the loop
'           Debug.Print match.Value   'Result: 9042 /2019
'           repNmbr = match.Value
'        Next match

    ExcelApp.Application.Visible = True
    ws.Range("G30").Value = repNmbr
End Sub

И такая ошибка:

enter image description here

Может кто-то объяснит мне, почему Set matches = regEx.Execute(rng.text) работает нормально, но repNmbr = regEx.Execute(rng.text) возвращает ошибку: «Неверное количество аргументов или неправильное присвоение свойства» ??

После установки regEx.Global = False RegEx находит только одно значение Так почему же VBA отказывается присваивать эту строку строковой переменной repNmbr ??

1 Ответ

1 голос
/ 17 февраля 2020

Как я уже сказал в вашем другом вопросе, вам не нужна библиотека RegEx для этого. Придерживайтесь подстановочных знаков Word ! Попробуйте:

Sub Demo()
Application.ScreenUpdating = False
Dim WordApp As Word.Application
Set WordApp = GetObject(, "Word.Application")
With WordApp.ActiveDocument.Range
  With .Find
    .Text = "<[0-9 ]{1,7}/[0-9]{4}>"
    .MatchWildcards = True
    .Wrap = wdFindStop
    .Forward = True
    .Execute
  End With
  If .Find.Found = True Then ActiveSheet.Range("G30").Value = Replace(.Text, " ", "")
End With
Application.ScreenUpdating = True
End Sub

Примечание : я не беспокоился ни о одном из:

Dim ExcelApp As Excel.Application
Dim rng As Word.Range
Dim ws As Worksheet
Dim regEx As Object
Dim matches As MatchCollection
Dim match As String
Dim repNmbr As String

, поскольку все это излишне - даже ваш собственный код никогда ничего не назначает WS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...