Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Word
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.02.2009, 15:18   #1
satyr_of_frost
 
Регистрация: 09.02.2009
Сообщений: 9
По умолчанию Выделение и копирование части документа на основе структуры файла

В документе поддерживается нумерация глав, подглав, под-подглав и т.д.

Есть пунтк 2.4.1 и в нем подпункты 2.4.1.1-2.4.1.20
Как мне быстро сделать ctrl+c или ctrl+x всей главы за номером 2.4.1 ?

Выделать мышкой сотни страниц - это ведь NOT TRUE, верно?

word - 2007
satyr_of_frost вне форума Ответить с цитированием
Старый 09.02.2009, 15:26   #2
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Эти все главы в одном разделе или в разных?
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Старый 09.02.2009, 16:08   #3
satyr_of_frost
 
Регистрация: 09.02.2009
Сообщений: 9
По умолчанию

Цитата:
Сообщение от viter.alex Посмотреть сообщение
Эти все главы в одном разделе или в разных?
Что такое раздел, я не знаю. Нумерация в документе поддерживается нумерованными списками уровня от перкого (1,2,3...) до четвертого (2.23.3.4). Мне необходимо выделять кусок с определенным номером третьего уровня вложенности. То есть выделить все подпункты этого куска до следующего пунтка третьего уровня.


Никакой другой структуры в документе не ведется (например упомянутые некие "главы").

UPD: Я просто читал в одной книжке, что надо все автоматизировать и даже если тебе предстоит сделать приглашения на свадьбу - требуется писать специальную программу а список гостей распознавать из рукописного.
satyr_of_frost вне форума Ответить с цитированием
Старый 09.02.2009, 16:17   #4
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Цитата:
Сообщение от satyr_of_frost Посмотреть сообщение
…Никакой другой структуры в документе не ведется (например упомянутые некие "главы").…
Ну, главы не я упомянул, а ты.

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

UPD: Я просто читал в одной книжке, что надо все автоматизировать и даже если тебе предстоит сделать приглашения на свадьбу - требуется писать специальную программу а список гостей распознавать из рукописного.
Наш человек!

Пробуй этот код. Поставь курсор в тот параграф, откуда хочешь начать выделение и запусти макрос. Все что с нумерацией внутри этого уровня будет скопировано (я надеюсь) в буфер.
Код:
Sub selectpar()
  Dim par1 As Paragraph, ListL As String
  Dim iOutlineLevel As Integer, istart As Long, iend As Long
  Selection.HomeKey wdLine, wdMove
  iOutlineLevel = Selection.Range.ListParagraphs(1).OutlineLevel
  istart = ActiveDocument.Range(0, Selection.Paragraphs(1).Range.start).Characters.Count
  ListL = Selection.Paragraphs(1).Range.ListFormat.ListString
  For Each par1 In ActiveDocument.Range.Paragraphs
    iend = ActiveDocument.Range(0, par1.Range.End).Characters.Count
    If par1.OutlineLevel = iOutlineLevel And _
        iend > istart And _
        Val(par1.Range.ListFormat.ListString) > Val(ListL) Then
        iend = ActiveDocument.Range(0, par1.Previous.Range.End).Characters.Count
      Exit For
    End If
  Next
  Selection.SetRange istart, iend
  Selection.Copy
End Sub
Добавлено позже
Заменил переменные istart и iend на тип Long, т.к. Integer не может быть больше 32 767. На больших текстах могло давать ошибку.
Лучше день потерять — потом за пять минут долететь!©

Последний раз редактировалось viter.alex; 09.02.2009 в 16:48. Причина: Немного исправил код. Теперь условие в цикле будет срабатывать и на больших текстах.
viter.alex вне форума Ответить с цитированием
Старый 09.02.2009, 16:19   #5
satyr_of_frost
 
Регистрация: 09.02.2009
Сообщений: 9
По умолчанию спутал главы и параграфы %-)

Я верно понимаю, что для релизации "Вырезать" надо заменить строку
Selection.Copy
на строку
Selection.Cut
?
satyr_of_frost вне форума Ответить с цитированием
Старый 09.02.2009, 16:24   #6
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Цитата:
Сообщение от satyr_of_frost Посмотреть сообщение
Я верно понимаю, что для релизации "Вырезать" надо заменить строку
Selection.Copy
на строку
Selection.Cut
?
Верной дорогой идете, товарищ!
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Старый 09.02.2009, 16:47   #7
satyr_of_frost
 
Регистрация: 09.02.2009
Сообщений: 9
По умолчанию

сначала вылетело на Integer от переполнения, заменил тип на Long для меток начала и конца. Запустил - зависло (не отвечает). Обламал через ctrl-break.

Можете переписать на такое: выделить и скопировать от текущей позиции курсора до следующего абзаца уровня 3
?
satyr_of_frost вне форума Ответить с цитированием
Старый 09.02.2009, 16:51   #8
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Цитата:
Сообщение от satyr_of_frost Посмотреть сообщение
сначала вылетело на Integer от переполнения, заменил тип на Long для меток начала и конца. Запустил - зависло (не отвечает). Обламал через ctrl-break…
Исправил

Цитата:
Сообщение от satyr_of_frost Посмотреть сообщение
…Можете переписать на такое: выделить и скопировать от текущей позиции курсора до следующего абзаца уровня 3 ?
А макрос что по-твоему делает? Он запоминает уровень списка в текущем параграфе, запоминает положение курсора относительно начала документа, а затем перебирает все параграфы, пока не найдет параграф с тем же уровнем и номером больше. Ну и выделяет их.

Добавлено позже
Действительно медленно работает. 8 страниц просматривал около минуты. Нужно оптимизировать. Приду домой — подумаю.
Сходу: нужно отсеивать параграфы с другим стилем нумерации и абзацы вообще без нумерации, чтобы их вообще не трогать. Кроме того, диапазон документа засунуть в память, и там копать, а не в документе.
Лучше день потерять — потом за пять минут долететь!©

Последний раз редактировалось viter.alex; 09.02.2009 в 17:10.
viter.alex вне форума Ответить с цитированием
Старый 09.02.2009, 17:32   #9
satyr_of_frost
 
Регистрация: 09.02.2009
Сообщений: 9
По умолчанию

Цитата:
Добавлено позже
Действительно медленно работает. 8 страниц просматривал около минуты. Нужно оптимизировать. Приду домой — подумаю.
Сходу: нужно отсеивать параграфы с другим стилем нумерации и абзацы вообще без нумерации, чтобы их вообще не трогать. Кроме того, диапазон документа засунуть в память, и там копать, а не в документе.
А, ну теперь понятно, почему на моих 1100 с лишком страницах все зависло Странно, что так долго работает. Что он там перебирает, интересно... За минуту в vim-е наверное можно миллион строк автозаменой обработать а то и больше.

Про засовывание структуры в память. Ее же, структуру, перед этим создать прийдется. А это что, каждый раз 1100 сраниц лопатить? Я хочу этот макрос применять десятки, сотни раз - каждый раз будет создаваться структура.

Последний раз редактировалось satyr_of_frost; 09.02.2009 в 18:44.
satyr_of_frost вне форума Ответить с цитированием
Старый 09.02.2009, 18:57   #10
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Оптимизирую. Но очень быстрой работы не жди. Это же VBA, а не ассемблер. Он работает не с текстом, а с объектами, у которых куча свойств.

Оптимизировал
Попробуй это. В принципе, если чистый текст без рисунков, то должно правильно работать. Хотя с рисунками тоже, они же не символы. Хотя от Word всего можно ожидать
Код:
Sub selectpar()
  Dim par1 As Paragraph, ListL As Variant, ListL1 As Variant, oLP As ListParagraphs
  Dim iOutlineLevel As Integer, istart As Long, iend As Long
  Selection.HomeKey wdLine, wdMove
  iOutlineLevel = Selection.Range.ListParagraphs(1).OutlineLevel
  istart = ActiveDocument.Range(0, Selection.Paragraphs(1).Range.Start).Characters.Count
  ListL = Split(Selection.Paragraphs(1).Range.ListFormat.ListString, ".")
  ListL(UBound(ListL)) = ListL(UBound(ListL)) + 1: ListL = Join(ListL, ".")
  Set oLP = ActiveDocument.Range.ListParagraphs
  For Each par1 In oLP
    If par1.OutlineLevel = iOutlineLevel And _
        ListL = par1.Range.ListFormat.ListString Then
      iend = ActiveDocument.Range(0, par1.Previous.Range.End).Characters.Count
        Exit For
    End If
  Next par1
  Selection.SetRange istart, iend: Selection.Copy
End Sub
Лучше день потерять — потом за пять минут долететь!©

Последний раз редактировалось viter.alex; 09.02.2009 в 19:35.
viter.alex вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Кодирование на основе ключевого слова и шифрование файла Шульц Помощь студентам 5 24.09.2008 22:09
Чтение структуры файла SDK Помощь студентам 4 23.01.2008 19:30
Выделение части изображения Luboff Помощь студентам 1 26.11.2007 08:07
Копирование структуры в буфер обмена bill Общие вопросы Delphi 14 20.11.2007 17:22
Вывод части текста из файла CoDeR Общие вопросы Delphi 10 16.08.2007 14:30