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

Обсуждение

Неизвестный
13.03.2010, 19:31
общий
14.03.2010, 15:00
это ответ
Здравствуйте, Ципихович Эндрю.
Решение вопроса представлено в URL >> тестовых файла к вопросу 177212
Тексты макросов прилагаю:

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

Dim flag As Boolean
Dim st As String
Dim i As Long, j As Long, pred As Long, pos As Long

flag = True
i = 1

Me.ListBox1.Clear

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, " ")
Me.ListBox1.AddItem Left(st, pos) & "ГК РФ"
Application.Documents("Гражданский кодекс.doc").Activate
Next j
flag = False
End If
Wend

Application.Documents("Гражданский кодекс.doc").Close
End Sub

Private Sub CommandButton1_Click()
Dim st As String
Dim flag As Boolean
Dim i As Long, j As Long

If (Me.ListBox1.ListIndex <> -1) Then
st = Me.ListBox1.Text
st = Left(st, Len(st) - 5)

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

flag = True
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
If InStr(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, st) = 1 Then
ActiveDocument.Fields(i).Result.Hyperlinks(j).Follow
'Selection.GoTo
Selection.Collapse
flag = False
Exit For
End If
Next j
End If
Wend
Else
MsgBox "Nothing selected"
End If

Application.Documents("Гражданский кодекс.doc").Activate
End Sub
Неизвестный
13.03.2010, 19:33
общий
Ципихович Эндрю:
Что-то в ответе на странице поломались русские буквы - - вместо крякозябров должна быть фраза "Гражданский кодекс".
в сети
Управляющий
143894
2148
13.03.2010, 20:35
общий
Andrew Kovalchuk:
Еще поломаные две строчки:
If ActiveDocument.Fields(i).Code Like "*4-4*" Then ' ïîäáåðèòå ïîäõîäÿùèé êðèòåðèé äëÿ îïðåäåëåíèÿ íóæíîãî ïîëÿ
и
Me.ListBox1.AddItem Left(st, pos) & "ÃÊ ÐÔ"
Напишите их в мини-форуме и я исправлю.
Об авторе:
Устав – есть устав! Если ты устав – то отдыхай!


Неизвестный
13.03.2010, 22:51
общий
Ципихович Эндрю:
If ActiveDocument.Fields(i).Code Like "*4-4*" Then ' ïîäáåðèòå ïîäõîäÿùèé êðèòåðèé äëÿ îïðåäåëåíèÿ íóæíîãî ïîëÿ
If ActiveDocument.Fields(i).Code Like "*4-4*" Then ' подберите подходящий критерий для определения нужного поля
Me.ListBox1.AddItem Left(st, pos) & "ÃÊ ÐÔ"
Me.ListBox1.AddItem Left(st, pos) & "ГК РФ"
Неизвестный
14.03.2010, 11:17
общий
Andrew Kovalchuk:
Совет, чтобы буквы не ломались перед тем как их копировать расскладку смените на русскую, скопируйте
и отправьте окончательный ответ, пожалуйста
в сети
Управляющий
143894
2148
14.03.2010, 15:02
общий
Andrew Kovalchuk:
На будущее - внимательнее относитесь к своим ответам в ПЛАТНЫХ ВОПРОСАХ!
Об авторе:
Устав – есть устав! Если ты устав – то отдыхай!


Неизвестный
21.03.2010, 16:41
общий
Andrew Kovalchuk:
После того как в вопросе № 177371 мне подсказали как пройти строки
Application.Documents.Open "Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
Application.Documents("Гражданский кодекс.doc").Activate
Прошу Вас загруженный файл URL >> файл к вопросу 177212
загрузить на форум РФ про и выложить на него ссылку
Спасибо
Неизвестный
21.03.2010, 19:14
общий
Ципихович Эндрю:
Цитата: 238244
Прошу Вас загруженный файл URL >> файл к вопросу 177212 загрузить на форум РФ про и выложить на него ссылку
Выложил. Забирайте тестовый файл к вопросу 177212
Неизвестный
22.03.2010, 16:35
общий
Andrew Kovalchuk:
Я правильно понял, что, увы, данным решением в лист бокс загнать название статей например УК РФ, состоящий из 473 статей или Гражданского кодекса РФ у которого статей еще более просто нереально, долго??? Я не понял название статей ВБА черпает из всего документа или из поля вида ТОС ..., если из документа, может можно сделать чтобы черпал из поля, так по моему будет быстрее???
В таком случае подскажите по концовке присланной Вами, то есть по исходному тексту кнопки я не понял, пробовал у меня не получилось, что то делает макрос непонятно что!!!!
Упростим задачу, например пользователь ввёл куда либо, то есть сообщил программе что хочет посмотреть статью 6, он вводит просто «6»
Программа это воспринимает как «Статья 6 », то есть «Статья » & Значение & « »
Ранее я спрашивал как организовать, чтобы открылся документ Гражданский кодекс.doc в нужном месте.
Сейчас я понимаю, что чтобы быть гибче есть два варианта, просто его открыть в нужном месте. Или эту статью взять в память и показать на форме. Подскажите оба варианта.
Спасибо Эндрю
Неизвестный
22.03.2010, 20:23
общий
Цитата: 238244
Я правильно понял, что, увы, данным решением в лист бокс загнать название статей например УК РФ, состоящий из 473 статей или Гражданского кодекса РФ у которого статей еще более просто нереально, долго???
Загнать можно. Для начала нужно определить критерии понятия "долго". Операции над строками традиционно считаются "дорогими", поэтому в итоге может оказаться, что извлечение части строки может быть более долгим по времени, нежели помещение десяти строк в листбокс.
Цитата: 238244
Я не понял название статей ВБА черпает из всего документа или из поля вида ТОС ..., если из документа, может можно сделать чтобы черпал из поля, так по моему будет быстрее???
Из поля вида TOC для заголовков четвертого уровня.
Цитата: 238244
В таком случае подскажите по концовке присланной Вами, то есть по исходному тексту кнопки я не понял, пробовал у меня не получилось, что то делает макрос непонятно что!!!!
Если имелось в виду Sub CommandButton1_Click(), то она ничего не делает, если в листбоксе не выделен ни один элемент, а только лишь показывает сообщение, что ничего не выделено (пожалуй после этого нужно вставить команду Exit Sub). В случае, когда в листбоксе выделен какой-то элемент открывается документ Гражданский кодекс, в нем ищется поле ТОС, а в нем ссылка на выбранную главу, по которой и осуществляется переход к нужному месту документа (при этом переходе может выделяться заголовок, поэтому дополнительно снимается всякое выделение). Вот, собственно, и все.
Неизвестный
22.03.2010, 21:00
общий
Andrew Kovalchuk:
Вот этой части
открывается документ Гражданский кодекс, в нем ищется поле ТОС, а в нем ссылка на выбранную главу, по которой и осуществляется переход к нужному месту документа (при этом переходе может выделяться заголовок, поэтому дополнительно снимается всякое выделение). Вот, собственно, и все.
я увы не добился
Упростим задачу, например пользователь ввёл куда либо, то есть сообщил программе что хочет посмотреть статью 6, он вводит просто «6»
Программа это воспринимает как «Статья 6 », то есть «Статья » & Значение & « »
Выложите пожалуйста код следующего, чтобы оно работало
открывается документ Гражданский кодекс, в нём ищется поле ТОС, а в нем ссылка на выбранную главу, по которой и осуществляется переход к нужному месту документа (при этом переходе может выделяться заголовок, поэтому дополнительно снимается всякое выделение).
Неизвестный
23.03.2010, 00:42
общий
Ципихович Эндрю:
Цитата: 238244
Вот этой части я увы не добился
Упростим задачу, например пользователь ввёл куда либо, то есть сообщил программе что хочет посмотреть статью 6, он вводит просто «6»
Программа это воспринимает как «Статья 6 », то есть «Статья » & Значение & « »
Выложите пожалуйста код следующего, чтобы оно работало
открывается документ Гражданский кодекс, в нём ищется поле ТОС, а в нем ссылка на выбранную главу, по которой и осуществляется переход к нужному месту документа (при этом переходе может выделяться заголовок, поэтому дополнительно снимается всякое выделение).
Код ниже:
Код:
Sub alt177212(ByVal num As String)
Dim st As String
Dim flag As Boolean
Dim i As Long, j As Long

st = "Статья " & num & " "

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

flag = True
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
If InStr(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, st) = 1 Then
ActiveDocument.Fields(i).Result.Hyperlinks(j).Follow
Selection.Collapse
flag = False
Exit For
End If
Next j
End If
Wend

Application.Documents("Гражданский кодекс.doc").Activate
End Sub

Sub test()
Call alt177212("16.1")
End Sub
Неизвестный
23.03.2010, 11:07
общий
Andrew Kovalchuk:
'Application.Documents.Open "Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
'скажите зачем строка Application.Documents("Гражданский кодекс.doc").Activate два раза в начале макроса и в конце, то есть активировать активированное???
'скажите зачем в строке If ActiveDocument.Fields(i).Code Like "*4-4*" Then есть "*4-4*", как я понял надо "*1-4*"
'скажите зачем строка Call alt177212("16.1"), откуда взялась, что должна выполнить???
'скажите зачем i = 1, как же оно сдвинется с места????
Неизвестный
23.03.2010, 14:07
общий
Ципихович Эндрю:
Цитата: 238244
'скажите зачем строка Application.Documents("Гражданский кодекс.doc").Activate два раза в начале макроса и в конце, то есть активировать активированное???
Только лишь для установления активности документа. Если вы считаете, что в этом нет необходимости - удалите лишнее.
Цитата: 238244
'скажите зачем в строке If ActiveDocument.Fields(i).Code Like "*4-4*" Then есть "*4-4*", как я понял надо "*1-4*"
В условии задачи написано - "Задача, состоит в том, чтобы взять в этом документе открывая его в «тёмную» все эти заголовки 4 уровня". Поле ТОС я делал только для заголовков четвертого уровня. В этой строке долгое время стоял комментарий ' подберите подходящий критерий для определения нужного поля
Цитата: 238244
скажите зачем строка Call alt177212("16.1"), откуда взялась, что должна выполнить???
Я ее написал. Это сделано для тестирования работоспособности процедуры. Должна вызвать процедуру с именем alt177212 передавая ей в качестве параметра значение "16.1".
Цитата: 238244
'скажите зачем i = 1, как же оно сдвинется с места????
Перед окончанием внешнего цикла, пожалуй, правильным будет увеличить счетчик (что-то такое уже исправлялось) - вставьте строку i = i + 1 перед строкой Wend.
Неизвестный
23.03.2010, 21:29
общий
Andrew Kovalchuk:
Разобрался я в этом вопросе во первых я соорудил конструкцию
А = InStr(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, st) 'я сколько не пробовал всё время в любых вариантах = 0, а Вы её сравниваете с = 1
поэтому внёс изменения:
перед циклом:
num = 277
st = "Статья " & num & " "
Длина_искомой_статьи = Len(num) + 7 'длина "Статья " & num , "Статья " занимает семь знаков
А в цикле:
If Left$(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, Длина_искомой_статьи) & " " = st Then 'условие, если ... первых знаков & " " = статье, которую ищем, тогда ...
и всё работает, но увы очень медленно.
Поэтому хотел спросить, если изменить условие вопроса:
если в документе имеется поле вида ТОС .... 1-4, тогда в его содержимом найти текст с учётом регистра на всякий случай
"Статья " & Значение & " ", узнать какая ссылка найденому и перейти по этой ссылке, так вроде быстрей???
Если да то представьте пожалуйста решение, пожалуйста
Спасибо Эндрю
Неизвестный
24.03.2010, 16:14
общий
Ципихович Эндрю:
Цитата: 238244
Разобрался я в этом вопросе во первых я соорудил конструкцию А = InStr(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, st) 'я сколько не пробовал всё время в любых вариантах = 0, а Вы её сравниваете с = 1
Конечно с 1. Ведь я хочу убедиться, что искомая строка входит в потенциально-искомую с ПЕРВОЙ позиции.
Цитата: 238244
Поэтому хотел спросить, если изменить условие вопроса:
если в документе имеется поле вида ТОС .... 1-4, тогда в его содержимом найти текст с учётом регистра на всякий случай
"Статья " & Значение & " ", узнать какая ссылка найденому и перейти по этой ссылке, так вроде быстрей???
Если да то представьте пожалуйста решение, пожалуйста
Насчет быстрее - вам с тестовым материалом виднее. Код прилагаю:
Код:
Sub alt177212(ByVal title As String)
Dim flag As Boolean
Dim i As Long, j As Long

Application.Documents.Open "D:\Mydoc\RfPro\Гражданский кодекс.doc", , ReadOnly, , , , , , , , , , False
Application.Documents("Гражданский кодекс.doc").Activate

flag = True
i = 1

While (flag) And (i < ActiveDocument.Fields.Count)
If ActiveDocument.Fields(i).Code Like "*1-4*" Then ' подберите подходящий критерий для определения нужного поля
For j = 1 To ActiveDocument.Fields(i).Result.Paragraphs.Count
If InStr(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, title) = 1 Then
ActiveDocument.Fields(i).Result.Hyperlinks(j).Follow
Selection.Collapse
flag = False
Exit For
End If
Next j
End If
If flag Then i = i + 1
Wend
If flag Then MsgBox "Link to " & title & " not found."
End Sub

Sub test()
Call alt177212("Статья 16.1 ")
Call alt177212("Статья 15 ")
Call alt177212("Заголовок первого уровня 1 ")
End Sub
Неизвестный
24.03.2010, 16:44
общий
Andrew Kovalchuk:
Спасибо за ответ, еще по ответу не разбирался, выяснил для себя что такое
Call alt177212("Статья 16.1 ")
Ни разу не пользовался возьму на вооружение
Неизвестный
24.03.2010, 18:01
общий
Andrew Kovalchuk:
В данном примере от примера
я увидел отличие - st заменено на title
Более я не увидел разницы, Вы даже не поправили, всё также пишите
If InStr(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, title) = 1 Then НЕ БУДЕТ ОНА НИКОГДА РАВНА ЕДИНИЦЕ, ВЕГДА РАВНА НУЛЮ
Я Вас спрашиваю простое решение основанное на методе Финд, надо найти в поле ТОС например "Статья 11.1 К" соблюдая регистр то есть Статья, пробел, несколько цифр до тех пор пока не будет после них пробел и следом большая буква, потом перейти по ссылке и снять выделение, возможно сразу не заходя в поле ТОС перейти в искомое место, это без разницы
Неизвестный
24.03.2010, 19:46
общий
Цитата: 238244
Более я не увидел разницы,
Плохо смотрели. Функционально разница существенна. Процедура, которая осуществляет переход по ссылке к закладке более не занимается формированием тела ссылки.
Цитата: 238244
Вы даже не поправили, всё также пишите If InStr(ActiveDocument.Fields(i).Result.Paragraphs.Item(j).Range.Text, title) = 1 Then НЕ БУДЕТ ОНА НИКОГДА РАВНА ЕДИНИЦЕ, ВЕГДА РАВНА НУЛЮ
Я двумя сообщениями выше пытался объяснить, почему я пишу именно так. Более того, можете посмотреть описание функции InStr и поинтересоваться когда эта функция возвращает нулевое значение. Особенно обратите внимание на фразу "Начальный индекс начинается с 1."
Других простых решений у меня нет.
Неизвестный
24.03.2010, 20:11
общий
Andrew Kovalchuk:
Вы говорите Конечно с 1. Ведь я хочу убедиться, что искомая строка входит в потенциально-искомую с ПЕРВОЙ позиции
И я тоже хочу, на Эф 8 держал палец устал, видел что искомое уже просмотрело и на искомом также было = 0
Неизвестный
26.03.2010, 15:37
общий
Andrew Kovalchuk:
Я с функцией Финд не могу никак подружиться подскажите, пожалуйста в коде на эту тему
'
Set myDoc = Documents.Open(fileName:="D:\Рабочая папка\УПК РФ.doc", Visible:=True)

Число = "499"
Искомая_статья = "Статья " & Число & ". "
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = Искомая_статья 'искомое слово
.MatchCase = True 'свойство MatchCase заставляет искать слово, соблюдая его регистр (то есть положение заглавных и строчных букв)
.Forward = True
.Wrap = wdFindStop
End With
While Selection.Find.Execute = True
Selection.MoveRight Unit:=wdCharacter, Count:=1
Wend
Selection.HomeKey Unit:=wdLine 'в начало строки
Beep

КАК ПОСТАВИТЬ УСЛОВИЕ, ЕСЛИ ИСКОМАЯ СТАТЬЯ НЕ НАЙДЕНА, ТОГДА ,,,,
Неизвестный
29.03.2010, 17:14
общий
Ципихович Эндрю:
Цитата: 238244
КАК ПОСТАВИТЬ УСЛОВИЕ, ЕСЛИ ИСКОМАЯ СТАТЬЯ НЕ НАЙДЕНА, ТОГДА ,,,,
If Selection.Find.Execute then Операторы_Когда_Найдено... else Операторы_Когда_НЕ_Найдено... end if
Если нужно только НЕ найдено, то рабочей оказывается конструкция If Selection.Find.Execute = False then Операторы_Когда_НЕ_Найдено... end if (более адекватной выглядит конструкция If Not Selection.Find.Execute then Операторы_Когда_НЕ_Найдено... end if, но я помню трудности использования оператора Not).
Неизвестный
29.03.2010, 19:20
общий
Andrew Kovalchuk:
Спасибо большое!!!!!!
Форма ответа