Консультация № 177169
09.03.2010, 17:26
35.77 руб.
0 18 1
Уважаемые эксперты подскажите код макроса, который может сделать следующее:
По адресу D:\Рабочая папка находится документ Гражданский кодекс.doc
4 й уровень его заголовков выглядит так:
Статья 16. Обеспечение……
Но может и выглядеть так:
Статья 16.1 Обеспечение
Задача, состоит в том, чтобы взять в этом документе открывая его в «тёмную», то есть на заднем плане, все эти заголовки 4 уровня от начала по первую большую букву включительно, эту первую большую букву заменить на ГК РФ, а затем всё это поместить в массив.
Спасибо Эндрю


Обсуждение

Неизвестный
11.03.2010, 21:03
общий
это ответ
Здравствуйте, Ципихович Эндрю.
Прилагаемый код решает поставленную задачу. А еще можно посмотреть на URL >> тестовые файлы к вопросу 177169

Приложение:
Sub q177169()
Application.Documents.Open "Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
Application.Documents("Гражданский кодекс.doc").Activate

Dim p As Paragraph
Dim s As String
Dim pred, pos, Uidx As Long
Dim Ar() As String

Uidx = 0
For Each p In ActiveDocument.Paragraphs
If p.Style.Description Like "*Уровень 4*" Then
pred = InStr(1, p.Range.Text, " ")
pos = InStr(pred + 1, p.Range.Text, " ")
s = Left(p.Range.Text, pos)
Uidx = Uidx + 1
ReDim Preserve Ar(Uidx)
Ar(Uidx) = s & "ГК РФ"
MsgBox Ar(Uidx)
End If
Next

Application.Documents("Гражданский кодекс.doc").Close
' А здесь, наверное, самое время сделать что-либо с данными из массива
End Sub
Неизвестный
12.03.2010, 15:52
общий
Andrew Kovalchuk:
Под 4 уровнем я имею ввиду элементы содержания, как если бы в документе было поле вида { TOC \o "4-4" \n \h \z \u }, тогда обновив его мы и получим элементы содержания 4 уровня
В Вашем случае если присвоить переменную и вставить её в коде после строки
For Each p In ActiveDocument.Paragraphs
Имя = p.Style.Description
В переменную Имя попадает текст вида: Шрифт: (по умолчанию) Таймс Нэв Роман и т. д.
То есть не то, что нужно
Также пользуясь случаем хотел спросить для какой цели открывать документ в режиме только для чтения
А также поясните строку
Application.Documents.Open "Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
Запятые зачем нужны, опечатка???
Неизвестный
12.03.2010, 17:24
общий
Цитата: 238244
Под 4 уровнем я имею ввиду элементы содержания, как если бы в документе было поле вида { TOC \o "4-4" \n \h \z \u }, тогда обновив его мы и получим элементы содержания 4 уровня
В Вашем случае если присвоить переменную и вставить её в коде после строки
For Each p In ActiveDocument.Paragraphs
Имя = p.Style.Description
В переменную Имя попадает текст вида: Шрифт: (по умолчанию) Таймс Нэв Роман и т. д.
То есть не то, что нужно
Когда я вижу текст "заголовок 4 уровня" я воспринимаю его буквально - "заголовок четвертого уровня". Посему в архиве тестовые файлы к вопросу 177169 вы можете видеть и документ организованный таким образом как это описано в условии задачи. А та часть из p.Style.Description которую вы обозначили как "и т.д." как раз и содержит информацию об уровне заголовка (у меня это в самом конце текста).
Цитата: 238244
Также пользуясь случаем хотел спросить для какой цели открывать документ в режиме только для чтения
А также поясните строку
Application.Documents.Open "Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
Запятые зачем нужны, опечатка???
Режим ReadOnly исключительно из соображений [b]"не навреди"[/b]. Запятые для соответствия вызова функции ее синтаксису (неуказанные параметры берутся как значения по умолчанию).
Неизвестный
12.03.2010, 18:34
общий
Ципихович Эндрю:
Предлагаемый ниже вариант решает уточненную задачу:
Код:
Sub q177169()
' Application.Documents.Open "Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
Application.Documents("Гражданский кодекс.doc").Activate

Dim flag As Boolean
Dim Ar() As String
Dim st As String
Dim i, j, pred, pos, j, Uidx As Long

flag = True
Uidx = 0
i = 1

While (flag) And (i < ActiveDocument.Fields.Count)
If ActiveDocument.Fields(i).Code Like "*4-4*" Then ' подберите подходящий критерий для определения нужного поля
For j = 1 To ActiveDocument.Fields(i).Result.Paragraphs.Count
st = ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text
pred = InStr(1, st, " ")
pos = InStr(pred + 1, st, " ")
Uidx = Uidx + 1
ReDim Preserve Ar(Uidx)
Ar(Uidx) = Left(st, pos) & "ГК РФ"
MsgBox Ar(Uidx)
Next j
flag = False
End If
Wend

' Application.Documents("Гражданский кодекс.doc").Close
' А здесь, наверное, самое время сделать что-либо с данными из массива

End Sub
Неизвестный
12.03.2010, 20:46
общий
Andrew Kovalchuk:
Проверю отвечу, а что касается А здесь, наверное, самое время сделать что-либо с данными из массива
У Вас есть шанс ответить на вопрос № 177006, на него так никто и не ответил, эти два вороса почти одно и то же, вопрос 177006 более обширный
На всякий случай смотрю на Ваше "тестовое файлы к вопросу 177169" в форуме вроде ссылка, выкрашено синим цветом, но не открывается, уточните пожалуйста
Неизвестный
12.03.2010, 21:23
общий
Andrew Kovalchuk:
Есть файл, ссылка https://rfpro.ru/upload/1820, там скриншот на ошибку
Также никак не пойму в вопросе сказано: По адресу D:\Рабочая папка находится документ Гражданский кодекс.doc

Вы так настойчиво пишите Application.Documents.Open "Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
Он что его откроет??
Неизвестный
13.03.2010, 00:04
общий
Ципихович Эндрю:
Вас не затруднит сделать замену имени пути на требуемый вам?
Для этого замените "Гражданский кодекс.doc" на "D:\\Рабочая папка\\Гражданский кодекс.doc"
PS: А то ведь если по каждому вопросу создавать запрашиваемые структуры каталогов, то личный винт будет больше похож на помойку.
Неизвестный
13.03.2010, 00:16
общий
Ципихович Эндрю:
Цитата: 238244
На всякий случай смотрю на Ваше "тестовое файлы к вопросу 177169" в форуме вроде ссылка, выкрашено синим цветом, но не открывается, уточните пожалуйста
Рабочую ссылку вы найдете в теле ответа на вопрос. Синий цвет в ответе мини-форума, на мой взгляд, должен был натолкнуть на мысль вернуться к ответу.
Неизвестный
13.03.2010, 00:22
общий
Ципихович Эндрю:
Цитата: 238244
У Вас есть шанс ответить на вопрос № 177006, на него так никто и не ответил, эти два вороса почти одно и то же, вопрос 177006 более обширный
Вопрос закрыт и ушел в рассылку.
Неизвестный
13.03.2010, 06:24
общий
Andrew Kovalchuk:
Сейчас откроем, всё остальное напишу завтра
Неизвестный
14.03.2010, 17:30
общий
Andrew Kovalchuk:
'12/3/2010 я Вам писал есть файл, ссылка https://rfpro.ru/upload/1820, там скриншот на ошибку
'в строке Dim i, j, pred, pos, j, Uidx As Long выделяет ", j," и сообщение:Компилле эррор Дупликате декрацион ин куррент скоре
'на этот счёт Вы не отвечаете, дальше пока сдвинуться нельзя !!!!!!
Неизвестный
14.03.2010, 21:22
общий
Ципихович Эндрю:
Цитата: 238244
Dim i, j, pred, pos, j, Uidx As Long
Два раза упомянута переменная j - удалите одну из них. Строка примет вид:
Код:
Dim i, j, pred, pos, Uidx As Long
Неизвестный
14.03.2010, 23:32
общий
Andrew Kovalchuk:
'я с Вами согласен, что не надо форум превращать в помойку, ну если код не идёт, начинаешь сомневаться во всех мелочах
'Вы говорите:Для этого замените "Гражданский кодекс.doc" на "D:\\Рабочая папка\\Гражданский кодекс.doc"
'Смотрю почему две наклонные, сомневаюсь, в то же время следую Вашим указаниям
'и в своих вопросах я спрашиваю иногда не точно, что мне надо, иногда что придёт в голову, затем меняю, творю ...
'Мне вобще то нужно не Гражданский кодекс.doc, а УК РФ.doc
Application.Documents.Open "D:\\Рабочая папка\\УК РФ.doc", , ReadOnly, , , , , , , , , , False
Application.Documents("D:\\Рабочая папка\\УК РФ.doc").Activate ' на этой строке получаю неверное имя файла
'как верхнюю строку пропустило, а тут не верное имя файла, ведь они одинаковые
'Смотрю почему две наклонные, сомневаюсь, в то же время следую Вашим указаниям
'напишите пожалуйста финальную версию с учётом всего, что нужен файл УК РФ.doc
'не забудьте и в этой строке Application.Documents("УК РФ.doc").Close если что надо изменить
'поясняю, еще раз мне это изменить не трудно, просто если код не идёт сомневаюсь во всех мелочах
Неизвестный
15.03.2010, 01:32
общий
Ципихович Эндрю:
Цитата: 238244
Application.Documents.Open "D:\\Рабочая папка\\УК РФ.doc", , ReadOnly, , , , , , , , , , False
Application.Documents("D:\\Рабочая папка\\УК РФ.doc").Activate ' на этой строке получаю неверное имя файла
Во втором случае экранировать слеши не требуется. То есть нужно использовать одинарные, а не двойные слеши, к примеру так (эта пара строк кода рабочая - пути указаны для моей структуры каталогов):
Код:
Application.Documents.Open "d:\\Mydoc\\RfPro\\УК РФ.doc", , ReadOnly, , , , , , , , , , False
Application.Documents("d:\Mydoc\RfPro\УК РФ.doc").Activate
Неизвестный
15.03.2010, 18:58
общий
Andrew Kovalchuk:
Мало того, что я почему-то с открытием файла не могу справиться это из симптомов указанных мною ранее в вопросе № 177168, но это уже дело десятое, я в макрос поместил предложенный Вами код:
Dim flag As Boolean
Dim Ar() As String
Dim st As String
Dim i, j, pred, pos, Uidx As Long

flag = True
Uidx = 0
i = 1

While (flag) And (i < ActiveDocument.Fields.Count)
If ActiveDocument.Fields(i).Code Like "*4-4*" Then ' подберите подходящий критерий для определения нужного поля
For j = 1 To ActiveDocument.Fields(i).Result.Paragraphs.Count
st = ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text
pred = InStr(1, st, " ")
pos = InStr(pred + 1, st, " ")
Uidx = Uidx + 1
ReDim Preserve Ar(Uidx)
Ar(Uidx) = Left(st, pos) & "ГК РФ"
MsgBox Ar(Uidx)
Next j
flag = False
End If
Wend
При открытом документе УК РФ.doc его запустил и компьютер завис
Видно, что он что то делает, но как я понял внутри макроса ходит по кругу
Нет ему ни конца ни края
Файл УК.doc по ссылке https://rfpro.ru/upload/1856
Давайте пока с открытым этим файлом решим!!



Неизвестный
15.03.2010, 20:25
общий
Ципихович Эндрю:
Цитата: 238244
При открытом документе УК РФ.doc его запустил и компьютер завис
Видно, что он что то делает, но как я понял внутри макроса ходит по кругу
Нет ему ни конца ни края
Файл УК.doc по ссылке https://rfpro.ru/upload/1856
Давайте пока с открытым этим файлом решим!!
Да уж. Обмишурился я на мякине - не изменялась переменная внешнего цикла. Ниже приведен исправленный вариант.
Код:
    Dim flag As Boolean
Dim Ar() As String
Dim st As String
Dim i, j, pred, pos, Uidx As Long

flag = True
Uidx = 0
i = 1

While (flag) And (i < ActiveDocument.Fields.Count)
If ActiveDocument.Fields(i).Code Like "*4-4*" Then '
For j = 1 To ActiveDocument.Fields(i).Result.Paragraphs.Count
st = ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text
pred = InStr(1, st, " ")
pos = InStr(pred + 1, st, " ")
Uidx = Uidx + 1
ReDim Preserve Ar(Uidx)
Ar(Uidx) = Left(st, pos) & "УК РФ"
MsgBox Ar(Uidx)
Next j
flag = False
End If
i = i + 1
Wend

Вот только во время тестового прогона не нашлось в нем подходящих элементов - нужно менять либо критерий поиска, либо структуру документа.
Неизвестный
15.03.2010, 21:38
общий
Andrew Kovalchuk:
Так уж исправьте до конца теперь вы знаете о чём идёт речь, только меняйте только критерий поиска, а то документ он с Консультанта +, всегда такой
Неизвестный
16.03.2010, 01:49
общий
Ципихович Эндрю:
Цитата: 238244
Так уж исправьте до конца теперь вы знаете о чём идёт речь, только меняйте только критерий поиска, а то документ он с Консультанта +, всегда такой
Код:
HYPERLINK \l "_Toc253153541"
HYPERLINK \l "_Toc253153542"
HYPERLINK \l "_Toc253153543"
HYPERLINK \l "_Toc253153544"
HYPERLINK \l "_Toc253153545"
HYPERLINK \l "_Toc253153546"
HYPERLINK \l "_Toc253153547"
HYPERLINK \l "_Toc253153548"
HYPERLINK \l "_Toc253153549"
HYPERLINK \l "_Toc253153550"
HYPERLINK \l "_Toc253153551"
HYPERLINK \l "_Toc253153552"
Какой из этих линков является линком на заголовок 4-го уровня? Я не вижу никаких объективных отличий - просто гиперссылки со сквозной нумерацией.

Из истории поставновки вопроса:
взять в этом документе .... все эти заголовки 4 уровня
Цитата: 238244
Под 4 уровнем я имею ввиду элементы содержания, как если бы в документе было поле вида { TOC \o "4-4" \n \h \z \u }, тогда обновив его мы и получим элементы содержания 4 уровня
Вставьте в документ поле указанного вида и будут вам все нужные заголовки.
Форма ответа