Цикл по строкам в word

Мне нужно выделить каждую третью строку документа и отформатировать текст жирным шрифтом, подчеркнутым и синим цветом. У меня уже есть код для этого, но мне нужно зациклить его в течение установленного количества раз.

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

Код, который я настроил, приведен ниже, а строки в квадратных скобках — вот что мне нужно для помощи:

Selection.HomeKey Unit:=wdStory

[Do the following code until the end of the document]

        Selection.HomeKey Unit:=wdLine
        Selection.EndKey Unit:=wdLine, Extend:=wdExtend
        With Selection.Font
            .Bold = wdToggle
            .Color = 12611584
            .Underline = wdUnderlineSingle
        End With

        Selection.MoveDown Unit:=wdLine, Count:=3

[end of loop]

Очень простой вопрос. Я знаком с настройкой этих типов петель в Excel, но словом, я не могу понять это. Я ценю любого, кто находит время, чтобы ответить.

0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

1

Word

Удаление пустых строк в таблице ворда

02.10.2022, 16:04. Показов 721. Ответов 16


Студворк — интернет-сервис помощи студентам

Доброго времени суток.
Есть документы с большим количеством таблиц, необходимо удалить во всех таблицах полностью пустые строки и строки в которых есть пустые ячейки.

Есть на форуме похожие задачи, но под свою не получилось оптимизировать их.
Буду рад, если поможете!
Спасибо!



0



344 / 206 / 78

Регистрация: 16.07.2020

Сообщений: 591

02.10.2022, 16:38

2

AndyChamin, Добрый вечер, прокрутите эту страницу вниз и просмотрите похожие темы.



0



0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

02.10.2022, 16:55

 [ТС]

3

Изучил все схожие темы на форуме. Я совсем далек от макросов, программирования и т.д.
У меня не получилось применить ничего из просмотренного(



0



344 / 206 / 78

Регистрация: 16.07.2020

Сообщений: 591

02.10.2022, 21:39

4

Цитата
Сообщение от AndyChamin
Посмотреть сообщение

У меня не получилось применить ничего из просмотренного

. Враньё, ничего ты не смотрел, за такое короткое время это невозможно сделать. Картина ясная — типичный лентяй и халявщик. Я пас — таким наглецам я не помогаю.



0



AndyChamin

0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

03.10.2022, 10:10

 [ТС]

5

Очень странный вывод
Я проштудировал форум еще до того как создать данную тему.
Некоторые макросы, найденные на форуме, успешно применяю в работе, однако под данную задачу не могу их оптимизироваться.
Например с другой формой документа пользуюсь следующим кодом

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    Dim oTable As Word.Table
    Dim lRowLength As Long
    Dim sRowText As String
    Dim i As Long
 
    For d = 1 To 400
         Set oTable = ActiveDocument.Tables(d)
         lRowLength = oTable.Columns.Count + 1
              Application.ScreenUpdating = False
               For i = oTable.Rows.Count To 1 Step -1
                   sRowText = oTable.Rows(i).Range.Text
                  sRowText = Replace(sRowText, Chr(13), "")
                  If Len(sRowText) = lRowLength Then
                  oTable.Rows(i).Delete
            End If
        Next i
        Application.ScreenUpdating = True
        Next d
        MsgBox "Код завершил работу", vbInformation
    
End Sub

Однако в данном документе он некорректно работает, удаляет только строки в одной таблице, в другой, где есть пустые ячейки, ничего не происходит.

В целом, для чего вешать на меня такие ярлыки я не совсем понимаю.
Если нет желания помочь мне в этом вопросе, я никого не заставляю, можно пройти мимо.



0



Punkt5

малоболт

1143 / 442 / 193

Регистрация: 30.01.2020

Сообщений: 1,095

03.10.2022, 10:50

6

Цитата
Сообщение от AndyChamin
Посмотреть сообщение

днако в данном документе он некорректно работает, удаляет только строки в одной таблице, в другой, где есть пустые ячейки, ничего не происходит.

Так вроде там всё прозрачно — это код как раз для удаления пустых строк, но не строк, в которых среди непустых значений есть хотя бы одно пустое. И правится вроде элементарно — добавлением цикла перебора ячеек в строке:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Dim oTable As Word.Table
Dim lRowLength As Long
Dim sRowText As String
Dim i As Long, j As Long
 
Application.ScreenUpdating = False
For d = 1 To ActiveDocument.Tables.Count 'только по таблицам текущего документа
  Set oTable = ActiveDocument.Tables(d)
  lRowLength = oTable.Columns.Count' число колонок
  For i = oTable.Rows.Count To 1 Step -1 'перебор строк снизу вверх
    For j = 1 To lRowLength Step 1 перебор ячеек слева направо в выбранной строке
      sRowText = Trim(Replace(Replace(oTable.Cell(i, j).Range.Text, Chr(13), ""), Chr(7), "")) 'текст в ячейке без спецсимволов
      If Len(sRowText) = 0 Then 'если встретилась пустая ячейка
        oTable.Rows(i).Delete ' удалим строку
        Exit For 'прервём цикл по ячейкам строки
      End If
    Next j
  Next i
Next d
Application.ScreenUpdating = True
MsgBox "Код завершил работу", vbInformation

P.S. Данный код вроде должен работать только если в таблицах нет объединения ячеек. Если же есть объединённые ячейки — надо сначала определиться с логикой:
1. Нужно ли удалять все строки, через которые эта ячейка проходит, или только верхнюю?
2. Нужно ли удалять нижние строки, которые захватывает объединённая ячейка с непустым значением (поскольку в них её значение пустое, а не пусто только в верхней из объединённых), оставляя только верхнюю?



0



0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

03.10.2022, 11:02

 [ТС]

7

Цитата
Сообщение от Punkt5
Посмотреть сообщение

Так вроде там всё прозрачно — это код как раз для удаления пустых строк, но не строк, в которых среди непустых значений есть хотя бы одно пустое. И правится вроде элементарно — добавлением цикла перебора ячеек в строке

Спасибо. Однако при запуске в документе выдает ошибку «5941, Запрашиваемый номер семейства не найден» с ссылкой на «sRowText = Trim(Replace(Replace(oTable.Cell(i, j).Range.Text, Chr(13), «»), Chr(7), «»)) ‘текст в ячейке без спецсимволов»

Может, конечно я что-то не то делаю



0



малоболт

1143 / 442 / 193

Регистрация: 30.01.2020

Сообщений: 1,095

03.10.2022, 11:20

8

Цитата
Сообщение от AndyChamin
Посмотреть сообщение

Может, конечно я что-то не то делаю

Цитата
Сообщение от AndyChamin
Посмотреть сообщение

выдает ошибку «5941, Запрашиваемый номер семейства не найден»

Всё просто: Значит в этой таблице есть объединённые ячейки. И простой перебор строк, с последующим перебором ячеек строки к данной таблице неприменим. Нужен более изощрённый перебор собственно ячеек таблицы, с анализом .RowIndex и .ColumnIndex с удалением/оставлением в зависимости от выбранной логики (одной из вышеупомянутых или какой-то своей).



0



Модератор

Эксперт MS Access

11343 / 4661 / 749

Регистрация: 07.08.2010

Сообщений: 13,512

Записей в блоге: 4

03.10.2022, 11:25

9

AndyChamin,

Данный код вроде должен работать только если в таблицах нет объединения ячеек. Если же есть объединённые ячейки — надо сначала определиться с логикой:

у вас же в таблицах множество объединенных ячеек, по крайней мере в шапках таблиц



0



малоболт

1143 / 442 / 193

Регистрация: 30.01.2020

Сообщений: 1,095

03.10.2022, 11:26

10

AndyChamin, Вдогон — хорошо бы ещё продумать, что делать со строками, в которых есть ячейки, объединённые по вертикали — искать ли для проверки верхнюю из объединённых ячеек (у неё .RowIndex будет другой) или пропускать, проверяя только те, что соответствуют данному .RowIndex?
Без выбора логики продолжать бессмысленно.



0



0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

03.10.2022, 11:32

 [ТС]

11

Цитата
Сообщение от shanemac51
Посмотреть сообщение

у вас же в таблицах множество объединенных ячеек, по крайней мере в шапках таблиц

Цитата
Сообщение от Punkt5
Посмотреть сообщение

Всё просто: Значит в этой таблице есть объединённые ячейки.

А можно при проверке ячеек их не учитывать?
Мне нужна корректировка необъединенных ячеек в строке 020 и 030



0



Punkt5

малоболт

1143 / 442 / 193

Регистрация: 30.01.2020

Сообщений: 1,095

03.10.2022, 11:45

12

Цитата
Сообщение от AndyChamin
Посмотреть сообщение

Мне нужна корректировка необъединенных ячеек в строке 020 и 030

Ну, пропишите номера этих строк в цикле по строкам, если эти строки определимы заранее

Visual Basic
10
For i =  ... To ...

Или внутри цикла по строкам — проверяйте сначала нужную ячейку на значение sRowtext = «020» или «030» и только для нужных затем начинайте цикл перебора ячеек в строке по j.



0



0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

03.10.2022, 12:08

 [ТС]

13

Цитата
Сообщение от Punkt5
Посмотреть сообщение

Ну, пропишите номера этих строк в цикле по строкам, если эти строки определимы заранее

020 и 030 это названия таблицы, это не сам номер строки) Немного лишней информации написал)

Добавлено через 15 минут

Цитата
Сообщение от Punkt5
Посмотреть сообщение

Ну, пропишите номера этих строк в цикле по строкам, если эти строки определимы заранее

Если указываю номера строк, то выдает ошибку со ссылкой на строку
14. oTable.Rows(i).Delete



0



малоболт

1143 / 442 / 193

Регистрация: 30.01.2020

Сообщений: 1,095

03.10.2022, 12:31

14

Цитата
Сообщение от AndyChamin
Посмотреть сообщение

Если указываю номера строк, то выдает ошибку со ссылкой на строку
14. oTable.Rows(i).Delete

Номера строк, надеюсь, в цикле от наибольшего к наименьшему? А то, при удалении строки выше, для удаления последующих надо пересчитывать как i, так и ограничение цикла сверху, с учётом количества удалённых строк — гемор тот ещё, да и вот такие ошибки вылезают.



0



0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

03.10.2022, 18:08

 [ТС]

15

Да, от большего к меньшему.



0



Punkt5

малоболт

1143 / 442 / 193

Регистрация: 30.01.2020

Сообщений: 1,095

04.10.2022, 05:21

16

Лучший ответ Сообщение было отмечено AndyChamin как решение

Решение

AndyChamin, давайте попробуем такую логику:
1. Обрабатываем таблицу только если в в ней число ячеек = числу строк * число колонок. (то есть все таблицы, где есть объединённые ячейки — пропускаем)
2. В строке таблицы начинаем проверку ячеек на пустоту не с первой колонки, а СО ВТОРОЙ. (потому что, если в первой стоит автонумерация, то текста в данной ячейке нет — возвращает пустоту)

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Dim oTable As Word.Table
Dim i As Long, j As Long, d As Long, xStr As String
 
Application.ScreenUpdating = False
For d = 1 To ActiveDocument.Tables.Count 'только по таблицам текущего документа
  Set oTable = ActiveDocument.Tables(d)
  If (oTable.Columns.Count * oTable.Rows.Count) = oTable.Range.Cells.Count Then ' ячеек = колонок * строк
    For i = oTable.Rows.Count To 1 Step -1 'перебор строк снизу вверх
      For j = 2 To oTable.Columns.Count Step 1 'перебор ячеек со ВТОРОЙ в выбранной строке
        xStr = Trim(Replace(Replace(oTable.Cell(i, j).Range.Text, Chr(13), ""), Chr(7), ""))
        If Len(xStr) = 0 Then
          oTable.Rows(i).Delete ' если встретилась пустая ячейка - удалим строку
          Exit For 'прервём цикл по ячейкам строки
        End If
      Next j
    Next i
  End If
Next d
Application.ScreenUpdating = True
MsgBox "Код завершил работу", vbInformation



1



0 / 0 / 0

Регистрация: 18.12.2021

Сообщений: 10

04.10.2022, 18:52

 [ТС]

17

Это магия какая-то, спасибо!
Вы сохранили десятки, а то и сотни часов моей жизни!
Все работает!



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

04.10.2022, 18:52

17

Sub Макрос()

    Dim tbl As Table, i As Long

            ‘1. Отключение монитора (может это ускорит макрос и не будет мерцать).
    Application.ScreenUpdating = False

        ‘2. Присваиваем таблице имя «tbl».
    Set tbl = ActiveDocument.Tables(1)

        ‘3. Цикл по строкам таблицы с последней по четвёртую.
    For i = tbl.Rows.Count To 4 Step -1
        ‘ Если в текущей ячейке в столбце 1 текст «Начало», то удалить строку.
            ‘ В ворде, в конце каждой ячейки есть два символа. Один символ в виде кружка,
            ‘ второй символ вообще не видно, но VBA его видит.
        If tbl.Cell(i, 1).Range.Text = «Начало» & Chr(13) & Chr(7) Then
            tbl.Rows(i).Delete
        End If
    Next i

        ‘4. Вкл. монитора.
    Application.ScreenUpdating = True

        ‘5. Сообщение.
    MsgBox «Готово.», vbInformation

End Sub

[свернуть]

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

1 21.06.2018 15:25:54

  • Тегирование строк Word
  • Fck_This
  • генерал-полковник
  • Неактивен
  • Откуда: Минск, Беларусь
  • Зарегистрирован: 13.07.2016
  • Сообщений: 648
  • Поблагодарили: 97

Тема: Тегирование строк Word

Товарищи, может кто-то подбросит идейку о том, как можно разметить строки в Word вне текста. Суть в том, что нужно каждой строке дать порядковый номер (Под строкой понимаю здесь набор символов, умещающийся по горизонтали на листе ворд без перехода на новую строку. Это может быть как абзац, так и часть абзаца) и его где-то записать. На ум пришли следующие идеи:
1) Использовать дополнительные свойства документа (пока не поэкспериментировал с их максимальным количеством), но среднее количество строк в документах — 5000 (документы бывают в 200 страниц)
2) Использовать закладки (тут явно попроще и по добавлению и по считыванию)
3) Использовать примечания. Эта идея мне не очень нравится, но не отказываюсь пока.

Пока в голову ничего больше не лезет. Хотелось бы рассмотреть все возможные варианты и потому хотелось бы услышать другие идеи.

Спасибо можно перевести на WebMoney-кошелёк R378231864568 или на Яндекс-деньги 410015093172871

2 Ответ от shanemac51 21.06.2018 16:29:43

  • shanemac51
  • генерал-полковник
  • Неактивен
  • Зарегистрирован: 05.03.2012
  • Сообщений: 467
  • Поблагодарили: 119

Re: Тегирование строк Word

не поняла, в чем суть номеров

возможно
—набивала бы текст в ексель/аксесс(код, сортировка, номер,текст)
—программно создавала НТМ ,хотя в минимальном объеме тегов(30-30)

полученный документ можно смотреть в НТМ или ВОРД

3 Ответ от Fck_This 22.06.2018 09:55:25

  • Тегирование строк Word
  • Fck_This
  • генерал-полковник
  • Неактивен
  • Откуда: Минск, Беларусь
  • Зарегистрирован: 13.07.2016
  • Сообщений: 648
  • Поблагодарили: 97

Re: Тегирование строк Word

shanemac51 пишет:

не поняла, в чем суть номеров

возможно
—набивала бы текст в ексель/аксесс(код, сортировка, номер,текст)
—программно создавала НТМ ,хотя в минимальном объеме тегов(30-30)

полученный документ можно смотреть в НТМ или ВОРД

Суть в том, что каждая строка должна быть отмечена каким-то образом (не в тексте) В дальнейшем номера будут использоваться в базе и связаны со строками

Спасибо можно перевести на WebMoney-кошелёк R378231864568 или на Яндекс-деньги 410015093172871

4 Ответ от yshindin 22.06.2018 12:35:25

  • yshindin
  • генерал-полковник
  • Неактивен
  • Откуда: Москва
  • Зарегистрирован: 12.05.2012
  • Сообщений: 447
  • Поблагодарили: 171
  • За сообщение: 1

Re: Тегирование строк Word

Fck_This пишет:

. . .
Под строкой понимаю здесь набор символов, умещающийся по горизонтали на листе ворд без перехода на новую строку. Это может быть как абзац, так и часть абзаца) и его где-то записать. На ум пришли следующие идеи:
1) Использовать дополнительные свойства документа (пока не поэкспериментировал с их максимальным количеством), но среднее количество строк в документах — 5000 (документы бывают в 200 страниц)
2) Использовать закладки (тут явно попроще и по добавлению и по считыванию)
3) Использовать примечания. Эта идея мне не очень нравится, но не отказываюсь пока.
. . .

Кроме закладок и свойств, можно еще предложить так называемые переменные Word (ActveDocument.Variables). Они могут сохраняться вместе с документом. Создать их можно только через макрос. Можно было бы переменные для строк назвать типа Line00001,  Line00001… и т.д., а значения — это символы соответствующих строк.
Чтобы двигаться по строкам, надо организовать цикл по абзацам, а внутри них действовать так:
1. Запомнить Selection.range.Start (как начало диапазона первой строки)
2. Выполнить Selection.GoTo What:=wdGoToLine, Which:=wdGoToNext, count:=1
3. Запомнить Selection.Range.Start -1  (как конец диапазона первой строки)
4. Из найденного диапазона выделяются символы строки (.Text), но вы можете в очередной переменной документа хранить как значение строки, так и границы диапазона, напр. в виде строки:
           |000045|000083|
это пример значения строковой переменной, содержащей позиции начала и конца диапазона строки. Потом такое значение легко разобрать макросом извлечения значения строки.
5. Далее выполнять шаги 1-3 пока конец диапазона очередной строки не превысит конец диапазона текущего абзаца.
6. И так далее по всем абзацам.
Потом для извлечения строк нужно написать отдельный несложный макрос.
Недостаток этого метода — нужно проводить пересоздание переменных, связанных со строками при любом изменении текста в документе.

5 Ответ от Fck_This 22.06.2018 17:57:40

  • Тегирование строк Word
  • Fck_This
  • генерал-полковник
  • Неактивен
  • Откуда: Минск, Беларусь
  • Зарегистрирован: 13.07.2016
  • Сообщений: 648
  • Поблагодарили: 97

Re: Тегирование строк Word

Спасибо за идею с Variables. По выделению строк я уже подготовил макрос. Почитаю про этого зверя и определюсь.

Спасибо можно перевести на WebMoney-кошелёк R378231864568 или на Яндекс-деньги 410015093172871

6 Ответ от yshindin 22.06.2018 18:11:20

  • yshindin
  • генерал-полковник
  • Неактивен
  • Откуда: Москва
  • Зарегистрирован: 12.05.2012
  • Сообщений: 447
  • Поблагодарили: 171

Re: Тегирование строк Word

Fck_This пишет:

Спасибо за идею с Variables. По выделению строк я уже подготовил макрос. Почитаю про этого зверя и определюсь.

Сам я пользуюсь такими подпрограммами (далее подпрограммы записи и чтения Variables  и проверка этих подпрограмм). Если переменной с указанным именем нет, то функция GetDocVariable возвращает значение пустой строки.

Public Function GetDocVariable(varname) As String
'Get value from a document variable
Dim dv As String
dv = ""
On Error Resume Next
dv = ActiveDocument.Variables(varname).Value
On Error GoTo 0
GetDocVariable = dv
End Function

Public Sub SetDocVariable(varname, varvalue)
'Set value to a document variable
On Error Resume Next
ActiveDocument.Variables(varname).Delete
ActiveDocument.Variables.Add Name:=varname, Value:=varvalue
On Error GoTo 0
End Sub

Sub test_doc_variable()
Dim vv as String
SetDocVariable "BD", "4"
vv = GetDocVariable("BD")
End Sub

7 Ответ от Boris_R 23.06.2018 16:43:45

  • Boris_R
  • полковник
  • Неактивен
  • Зарегистрирован: 07.08.2012
  • Сообщений: 234
  • Поблагодарили: 110

Re: Тегирование строк Word

А может быть так?

Sub Line_Numbering()
'
    With ActiveDocument.PageSetup
        With .LineNumbering
            .Active = True
            .StartingNumber = 1
            .CountBy = 1
            .RestartMode = wdRestartContinuous
            .DistanceFromText = wdAutoPosition
        End With
    End With
End Sub

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Вы, кажется, пропускаете параметр диапазона в Sub Sub CopyCell

Sub CreateWordDocuments()

    'create copy of Word in memory

    Dim doc As Word.Document
    wd.Visible = True
    Dim SOPRange As Range
    'create a reference to all the people

    Set SOPRange = Range(Range("A1"), Range("A1").End(xlDown)).Cells

    'for each person in list 

    For Each SOPCell In SOPRange
        'open a document in Word
        Set doc = wd.Documents.Open(FilePath & "template.doc")
        'go to each bookmark and type in details
        CopyCell SOPCell, "sop", 0
        CopyCell SOPCell, "equipment", 1
        CopyCell SOPCell, "component", 2
        CopyCell SOPCell, "step", 3
        CopyCell SOPCell, "form", 4
        CopyCell SOPCell, "frequency", 5
        CopyCell SOPCell, "frequencyB", 5
        'save and close this document
        doc.SaveAs2 FilePath & "SOP " & SOPCell.Value & ".doc"

        doc.Close

    Next SOPCell

    wd.Quit

    MsgBox "Created files in " & FilePath & "!"

End Sub

Sub CopyCell(rg As Range, BookMarkName As String, ColumnOffset As Integer)

    'copy each cell to relevant Word bookmark

    wd.Selection.GoTo What:=wdGoToBookmark, Name:=BookMarkName

    wd.Selection.TypeText rg.Offset(0, ColumnOffset).Value

End Sub

Понравилась статья? Поделить с друзьями:
  • Циклы в vba excel для ячеек
  • Цикл по колонкам excel
  • Циклы в excel для чайников
  • Цикл по всем записям excel
  • Циклы в excel без vba