Я пытаюсь удалить (определяемое пользователем) количество абзацев после того, как найдена строка - PullRequest
1 голос
/ 22 июня 2019

Я написал этот код в попытке сначала найти строку или набор строк, указанных конечным пользователем.После нахождения строки код спросит, хочет ли пользователь на самом деле изменить содержимое.Если пользователь выберет «да», то ему будет предложено задать вопрос о том, сколько абзацев, включая текущие абзацы и после найденной строки, хочет ли пользователь удалить.

Я не могу заставить его просто не удалятьабзацы с начала документа.Могу ли я что-нибудь сделать для достижения нужной мне функции?

Заранее спасибо!

Это код MS Word VBA.

Sub DeleteParagraphs_INPROCESS()
  Dim strFindTexts As String
  Dim strButtonValue As String
  Dim nSplitItem As Long
  Dim objDoc As Document
  Dim pcnt As Long


  strFindTexts = InputBox("Enter texts to be found here, and use commas to 
separate them: ", "Texts to be found", "SNP, POS")
  nSplitItem = UBound(Split(strFindTexts, ","))
  With Selection
    .HomeKey Unit:=wdStory

    ' Find the entered texts one by one.
    For nSplitItem = 0 To nSplitItem
      With Selection.Find
        .ClearFormatting
        .Text = Split(strFindTexts, ",")(nSplitItem)
        .Replacement.Text = ""
        .Forward = True
    .Wrap = wdFindContinue
    .Format = False
    .MatchWholeWord = False
    .MatchCase = False
    .MatchSoundsLike = False
    .MatchWildcards = False
    .MatchAllWordForms = False
    .Execute
  End With

  Do While .Find.Found = True
    strButtonValue = MsgBox("Delete the content?", vbYesNoCancel)
    If strButtonValue = vbYes Then
    pcnt = InputBox("How many paragraphs need to be deleted?", "Number of subsequent paragraphs:", "")
   ActiveDocument.Paragraphs(pcnt).Range.Select
   Selection.Delete

    End If
    .Collapse wdCollapseEnd
    .Find.Execute
  Loop
Next
  End With


      MsgBox ("Finished finding all entered texts.")
      Set objDoc = Nothing
    End Sub

Ожидаемый результат: удаление абзацеввключая строку и последующие абзацы в соответствии с тем, что пользователь указывает в поле ввода, а не просто удаляя абзацы в начале документа.

Ответы [ 2 ]

0 голосов
/ 22 июня 2019

Проблема, о которой вы упоминаете в своем вопросе, вызвана этим утверждением:

ActiveDocument.Paragraphs(pcnt).Range.Select

Это абсолютное утверждение, говорящее о выборе конкретного абзаца в документе. Если значение pcnt равно 2, он выберет 2-й абзац в документе. Вам следует выбрать абзацы, следующие за абзацем, в котором была найдена текстовая строка.

В вашем коде есть еще две проблемы.

Первое - это размещение команды .HomeKey Unit:=wdStory. Поскольку вы хотите выполнить поиск по всему документу для каждой отдельной текстовой строки, вы должны вернуться к началу документа для каждого поиска новой строки.

Другая проблема заключается в том, что ваш код предполагает, что пользователь всегда хочет удалить дополнительные абзацы. Что если они хотят удалить только абзац, содержащий текстовую строку? У вас нет резервов на этот случай.

Ниже ваш код исправлен, и я добавил несколько комментариев. Вы можете изучить то, что я сделал.

Sub DeleteParagraphs_INPROCESS()
    Dim strFindTexts As String
    Dim strButtonValue As String
    Dim nSplitItem As Long
    Dim objDoc As Document
    Dim pcnt As Long

    strFindTexts = InputBox("Enter texts to be found here, and use commas to separate them: ", "Texts to be found", "SNP, POS")
    nSplitItem = UBound(Split(strFindTexts, ","))
    With Selection
'        .HomeKey Unit:=wdStory 'moved this down
        ' Find the entered texts one by one.
        For nSplitItem = 0 To nSplitItem
            .HomeKey Unit:=wdStory 'must be here in order to search the entire document for each text string
            With Selection.Find
                .ClearFormatting
                .Text = Split(strFindTexts, ",")(nSplitItem)
                .Replacement.Text = ""
                .Forward = True
                .Wrap = wdFindContinue
                .Format = False
                .MatchWholeWord = False
                .MatchCase = False
                .MatchSoundsLike = False
                .MatchWildcards = False
                .MatchAllWordForms = False
                .Execute
            End With
            Do While .Find.found = True
                strButtonValue = MsgBox("Delete the content?", vbYesNoCancel)
                If strButtonValue = vbYes Then
                    Selection.Range.Paragraphs(1).Range.Select
                    pcnt = InputBox("How many paragraphs need to be deleted?", "Number of subsequent paragraphs:", "")
                    'ActiveDocument.Paragraphs(pcnt).Range.Select 'this will always delete the 2nd paragraph in the document
                    If pcnt = 0 Then 'what if they don't want to delete subsequent paragraphs? You have to allow for that.
                        Selection.Delete
                    Else
                        Selection.MoveEnd wdParagraph, pcnt
                        Selection.Delete
                    End If
                End If
                .Collapse wdCollapseEnd
                .Find.Execute
            Loop
        Next
    End With
    MsgBox ("Finished finding all entered texts.")
    Set objDoc = Nothing
End Sub
0 голосов
/ 22 июня 2019

Измените цикл Do, чтобы задать объект Range для абзаца, в котором существует найденный элемент, а затем увеличьте его до указанного числа абзаца (минус 1 для текущего абзаца). Например:

  Do While .Find.found = True
    strButtonValue = MsgBox("Delete the content?", vbYesNoCancel)
    If strButtonValue = vbYes Then
        pcnt = InputBox("How many paragraphs need to be deleted?", "Number of subsequent paragraphs:", "")
        Dim rng As Range
        Set rng = Selection.Paragraphs(1).Range
        rng.MoveEnd wdParagraph, pcnt - 1            
        rng.Delete
    End If
    .Collapse wdCollapseEnd
    .Find.Execute
  Loop

Примечание 1 Если бы вместо Selection.Find использовалось Range.Find, объявление и установка диапазона в цикле были бы излишними.

Примечание 2 Вы должны изменить wdFindContinue для свойства wrap на wdFindStop. При использовании Find в VBA всегда существует опасность, что он входит в бесконечный цикл, повторно проверяя документ с самого начала. Так что стоит привыкнуть использовать wdFindStop.

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