Word VBA Макросы: Ошибка при выделении таблицы

Автор Anton, 01 ноября 2017, 22:27

Anton

Здравствуйте!
Подскажите пожалуйста, почему если в конструкции ниже я выделяю только строки таблицы, то возникает ошибка.
А если я выделяю вместе с таблицей еще и абзацы текста вне тблицы - не возникает.

Sub ParList()
    Dim i&
    For i = Selection.Paragraphs.count To 1 Step -1
        With Selection.Paragraphs(i).Range

'тут код

        End With
    Next
End Sub

Причем ошибка появляется не всегда, я не могу разобраться. А ругается на эту строчку:
With Selection.Paragraphs(i).Range
пишет "Запрашиваемый номер семейства не существует"

Причем ошибка возникает, когда выделяю так, как на скрине (когда строчку выделяешь, если мышь подвести слева к строке таблицы).

[вложение удалено администратором]

Администратор

В вашем случае ошибка: Запрашиваемый номер семейства не существует - означает, что нет абзаца.

Здесь: Selection.Paragraphs(i)
Paragraphs(i) - это абзац. Вот нет абзаца с порядковым номером "текущая i".

Администратор

Объект "Selection" изменялся после первого изменения текста и уже не представлял собой первоначальный выделенный фрагмент.
Сначала всегда пробуйте работать с Range, если с Range не получается, то тогда используйте Selection. Т.к. с "Range" быстрее работать и не мигает. Но иногда без "Selection" не обойтись.

Макрос
Sub ParList2TextSel()
    Dim i&, li, fli, ls$
    Dim rng As Range
   
    ' Присваиваем имя "rng" выделенному фрагменту, иначе при действиях с текстом,
        ' Selection изменяется.
    Set rng = Selection.Range.Duplicate
   
    ' Цикл по абзацам выделенного фрагмента.
    For i = rng.Paragraphs.Count To 1 Step -1
        With rng.Paragraphs(i).Range
            ls = .ListFormat.ListString    'текст нумерации
            If ls <> "" Then    'есть нумерация
                li = .ParagraphFormat.LeftIndent
                fli = .ParagraphFormat.FirstLineIndent
                .InsertBefore ls & ChrW(160)
                .ListFormat.RemoveNumbers wdNumberParagraph
                .ParagraphFormat.LeftIndent = li
                .ParagraphFormat.FirstLineIndent = fli
            End If
        End With
    Next
End Sub
[свернуть]

Anton

Ясно! Большое спасибо!
А можно еще вопрос по теме: если нужно обработать весь документ, что присвоить rng? Или как переделать процедуру Sub ParList2TextSel() в функцию и передать ей параметр, который будет указывать на обработку выделенного фрагмента или всего документа?

Администратор

В процедуре "макрос" нужный пункт раскомментируйте, а ненужный удалите или закомментируйте.

Макрос
Sub макрос()
    Dim rng As Range
   
    ' Присваиваем имя "rng" выделенному фрагменту, иначе при действиях с текстом,
        ' Selection изменяется.
    Set rng = Selection.Range.Duplicate
'    ' Присваиваем имя "rng" основному тексту.
'    Set rng = ActiveDocument.Range.Duplicate
    ParList2TextSel rng
End Sub

Private Sub ParList2TextSel(rng As Range)
    Dim i&, li, fli, ls$
   
    ' Цикл по абзацам объекта "Range".
    For i = rng.Paragraphs.Count To 1 Step -1
        With rng.Paragraphs(i).Range
            ls = .ListFormat.ListString    'текст нумерации
            If ls <> "" Then    'есть нумерация
                li = .ParagraphFormat.LeftIndent
                fli = .ParagraphFormat.FirstLineIndent
                .InsertBefore ls & ChrW(160)
                .ListFormat.RemoveNumbers wdNumberParagraph
                .ParagraphFormat.LeftIndent = li
                .ParagraphFormat.FirstLineIndent = fli
            End If
        End With
    Next
End Sub
[свернуть]

Anton