Собрать содержимое МТЕкста с разных листов в один документ/объект
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Собрать содержимое МТЕкста с разных листов в один документ/объект

Собрать содержимое МТЕкста с разных листов в один документ/объект

Ответ
Поиск в этой теме
Непрочитано 08.02.2017, 12:40 #1
Собрать содержимое МТЕкста с разных листов в один документ/объект
Immortal_6666
 
вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132

Добрый день)
Ситуация следующая - есть проект с листами, на каждом листе есть Мтекст с названием листа. Листов в проекте много >10. По завершении проекта требуется составить список из этих названий (список листов). Сейчас приходится щелкать на каждый лист, заходить в Мтекст, все выделять, копировать в Word и так для каждого листа. Получается долго и нудно. Хотелось бы как-то автоматизировать это дело. Знаком с блоками, полями, просто в данном случае никак не могу придумать решение. Может кто-то подскажет оригинальный способ.

Упрощая задачу - можно просто собрать содержимое этих мтекстов в список внутри файла, а потом уже 1 раз скопировать в word. Но как это сделать не придумать... Насколько я понимаю, взять содержимое объекта на листе через поле и вставить значение в модель нельзя..

Были мысли писать эти названия внутри 1 мтекста в модели, а потом вставлять в листы через ВЭ нужную часть этого списка, но листы в процессе работы постоянно меняются местами, названия меняются тоже - так еще большая головная боль получается.

Почти все части проекта смог автоматизировать настолько, насколько это возможно - через дин. блоки, поля, свойства документа, палитры, аннотативность, а вот с этой задачей бьюсь уже давно.
Спасибо.
Просмотров: 8462
 
Непрочитано 08.02.2017, 13:42
#2
baksconstructor


 
Регистрация: 05.11.2014
Сообщений: 944


Пример файла приложите.
baksconstructor вне форума  
 
Непрочитано 08.02.2017, 13:59
#3
kp+

идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,194


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Знаком с блоками, полями, просто в данном случае никак не могу придумать решение.
Извлечение данных (_dataextraction) может работать со многими чертежами одновременно.
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
на каждом листе есть Мтекст с названием листа
Гарантированно один Мтекст на каждый лист? Тогда вообще элементарно. Но если есть другие надписи, выполненные Мтекстом, нужные надо будет отфильтровать (по цвету, слою или другим признакам).
Или просто убрать из результатов (таблицы или внеш. файла) то, что явно не подходит.

Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Почти все части проекта смог автоматизировать настолько, насколько это возможно - через дин. блоки, поля, свойства документа, палитры, аннотативность, а вот с этой задачей бьюсь уже давно.
Осваивайте подшивки.
kp+ вне форума  
 
Автор темы   Непрочитано 08.02.2017, 14:01
#4
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


baksconstructor, примерно так.

kp+, нет, текст там конечно не один.

Подшивки мне тут ничем не помогут, как мне кажется. Если я работаю в 1 файле и без коллективной работы, вообще не вижу смысла в подшивках - публикация решает все те же задачи.
Вложения
Тип файла: dwg
DWG 2007
пример.dwg (91.9 Кб, 17 просмотров)
Immortal_6666 вне форума  
 
Непрочитано 08.02.2017, 14:12
1 | #5
baksconstructor


 
Регистрация: 05.11.2014
Сообщений: 944


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
примерно так.
Тю, я то думал что там штампы чертежей.
У Вас по одной строчке в листе, тогда kp+ прав, смотрите принтскрин. (если Вы нас не обманули и реальный чертеж не другой)
Миниатюры
Нажмите на изображение для увеличения
Название: 3.jpg
Просмотров: 66
Размер:	190.7 Кб
ID:	183293  
baksconstructor вне форума  
 
Непрочитано 08.02.2017, 14:14
#6
kp+

идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,194


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
нет, текст там конечно не один.
По файлу примера этого не скажешь Но, думаю, Вы уж как-нибудь разберетесь, чем нужный текст отличается от прочих.

Offtop:
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Если я работаю в 1 файле и без коллективной работы, вообще не вижу смысла в подшивках - публикация решает все те же задачи.
А он есть даже при таком раскладе. И кроется в том, что нумерация листов, их наименования и перекрестные ссылки хранятся в подшивке и автоматически обновляются. Без подшивки надо все хранить в голове. Впрочем, это сотни раз обсуждалось в "профильных" темах и здесь не к месту.
kp+ вне форума  
 
Непрочитано 08.02.2017, 14:56
1 | #7
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Примерно так?
Код:
[Выделить все]
 (defun C:TEST ( / ss i str)
	(vl-load-com)
	(setq ss (ssget "_X" '((0 . "MTEXT")(8 . "текст"))))
	(repeat (setq i (sslength ss))
		(setq vla-txt (vlax-ename->vla-object (ssname ss (setq i (1- i)))))
		(if (null str)
			(setq str (vla-get-TextString vla-txt))
			(setq str (strcat str "\n" (vla-get-TextString vla-txt)))
		)
	)
	(vla-AddMText 
		(vla-get-ModelSpace (vla-get-activedocument (vlax-get-acad-object)))
		(vlax-3d-point (list 0.0 0.0 0.0))
		0
		str
	)
	(vl-cmdf "_CUTCLIP" (entlast) "")
	(vl-cmdf "_PASTECLIP" pause)
)
Тестовая версия, запускать в модели. Соберет содержимое всех мтекстов на слое "текст" и на курсоре повиснет мтекст с собранным содержимым. Порядок названий пока зависит от очередности создания мтекстов на листах, но это поправимо. Для того, чтобы эта команда стала "рабочей" (могла бы использоваться на реальных чертежах), помимо прочих доработок,
Цитата:
Сообщение от kp+ Посмотреть сообщение
нужные надо будет отфильтровать (по цвету, слою или другим признакам)
Иными словами создать для таких текстов отдельный слой или дать им особенный вес, например, и следить за тем, чтобы лишних мтекстов с такими свойствами не было.
skkkk вне форума  
 
Автор темы   Непрочитано 08.02.2017, 17:34
#8
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Спасибо всем огромное!

Просто реальный пример я приложить не могу из-за политики о неразглашении. Там конечно штампы есть, и на их уровне уже все забито "личной" информацией фирмы через поля, поэтому выложил "голый" пример. Но сути задачи это не меняет.

Слой отдельный сделать для этого вообще не проблема. Про извлечение данных почему-то не подумал в данном случае! Спасибо за наводку. Код тоже попробую, чуть позже отпишусь, что вышло. Желательно, чтобы порядок сбора соответствовал порядку листов в файле.

Насчет подшивок - я с ними игрался, но кроме "лишних" действий по их созданию для своей практики пользы в них не нашел. Номер листа у меня в штампе заполняется через CTAB - пробовал много способов, этот - самый удобный. Вся инфа в штампе - опять же поля, из централизованного источника все попадает в нужное место на каждом листе. Фамилии - аналогично. Машстаб ВЭ - тоже сам попадаем в штамп через поле. Печать - через экспорт в PDF - в один клик все листы. Я против подшивок ничего не имею, уточняю, чтобы камни в меня не полетели Просто для себя сделал вывод, что это удобно, если работа "типовая" - т.е настроить все местозаполнители блока и т.п., формировать сами листы и виды через подшивку. Но это специфический метод и мало кто так умеет. Большинство используют подшивки просто как способ собрать готовые листы из разных файлов в одно место для печати - а для этого и _publish подходит отлично.


skkkk, код почему-то не заработал. Я создал слой Текст2, туда перенес Мтексты с листов. В коде заменил слово "текст" на "Текст2", после запуска просто открывается диспетчер слоев, либо справка, либо какая-то рандомная команда и все... больше ничего не происходит.

Последний раз редактировалось Immortal_6666, 08.02.2017 в 19:59.
Immortal_6666 вне форума  
 
Непрочитано 08.02.2017, 18:08
#9
kp+

идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,194


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Желательно, чтобы порядок сбора соответствовал порядку листов в файле.
Для простых Мтекстов средствами "извлечения данных" не получится Offtop: Зато с помощью подшивки можно было бы.
Впрочем, можно сделать иначе: вместо обычных Мтекстов создать блоки с двумя атрибутами:
- в первом - поле вида %<\AcVar ctab>%
- во втором (многострочном) - наименование чертежа.
Первый атрибут может быть на непечатаемом слое, а может использоваться - дело вкуса. Тогда результаты извлечения данных можно сортировать по первому атрибуту.
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Вся инфа в штампе - опять же поля, из централизованного источника все попадает в нужное место на каждом листе.
Что используется в качестве централизованного источника, если не секрет?

Последний раз редактировалось kp+, 08.02.2017 в 18:24.
kp+ вне форума  
 
Автор темы   Непрочитано 08.02.2017, 18:15
#10
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


kp+, свойства документа - там заполняю нужные строки.

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

UPDATE
Только по Мтекстам искать научился, но он выдергивает вообще все... и кучу "мусора" в строку вставляет - \pxqc,t18;
Опять же, никакого порядка и последовательности.. не очень подходит метод.

Вариант с кодом был бы оптимален. Очень надеюсь на skkkk =)
Миниатюры
Нажмите на изображение для увеличения
Название: Снимок.JPG
Просмотров: 25
Размер:	35.1 Кб
ID:	183313  

Последний раз редактировалось Immortal_6666, 08.02.2017 в 18:21.
Immortal_6666 вне форума  
 
Непрочитано 08.02.2017, 18:28
#11
kp+

идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,194


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Опять же, никакого порядка и последовательности.. не очень подходит метод.
перечитайте мой пост #9, там есть добавка.
По поводу очистки форматирования Мтекста есть отдельная тема, поиск по форуму в помощь. Знаки \P (абзац) в результатах извлечения данных нетрудно поиском-заменой убрать.
kp+ вне форума  
 
Автор темы   Непрочитано 08.02.2017, 18:32
#12
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Да, я прочитал.
Теорически можно. Правда от Мтекстов не очень хочется уходить - у меня из них потом тоже через поля "улетает" всё в другое место листа это раз. И сами эти Мтексты формируются из полей. Наверное. можно загнать поле в текст атрибута, но я так еще не пробовал и это все усложняет процесс работы.
Тут задача "минимизировать" пляски с бубном, а с поиском заменой уже набирается процесс посложнее, чем просто по листам пройтись с CTRL+C =))

Самый оптимальный вариант - как-то "считать" все Мтексты с каждого листа по параметру слой (для них я бы сделал уникальный слой) и собрать их в одно место.
Immortal_6666 вне форума  
 
Непрочитано 08.02.2017, 18:43
#13
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Это не подойдет? Автозаполнение ведомости рабочих чертежей
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 08.02.2017, 18:49
#14
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Цитата:
Сообщение от VVA Посмотреть сообщение
Как крайний случай, видимо, да. Но там чуть другая цель изначально, и смущает "Обязательно использование блока с атрибутами "ЛИСТ" и "НАИМЕНОВАНИЕ.ЧЕРТЕЖА"." Мне бы тоже самое но попроще (таблица вообще не нужна) и считывание не через блок.

Оффтоп: где бы (и у кого) в Питере программированию под AutoCAD поучиться?...
Immortal_6666 вне форума  
 
Непрочитано 08.02.2017, 19:02
#15
kp+

идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,194


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Мне бы тоже самое но попроще (таблица вообще не нужна)
А в результате получается сложнее и хуже...впрочем, код под именно Ваши нужды тоже можно написать...но это больше в "поиск исполнителей".
Offtop:
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Оффтоп: где бы (и у кого) в Питере программированию под AutoCAD поучиться?...
Сначала см. тут, потом целый раздел "программирование" к Вашим услугам. Опять же, питерские форумчане чуть не каждый месяц бухают обмениваются опытом в том или ином составе, следите за объявлениями
kp+ вне форума  
 
Непрочитано 08.02.2017, 20:37
1 | #16
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
skkkk, код почему-то не заработал. Я создал слой Текст2, туда перенес Мтексты с листов. В коде заменил слово "текст" на "Текст2", после запуска просто открывается диспетчер слоев, либо справка, либо какая-то рандомная команда и все... больше ничего не происходит.
Код с номерами строк вставился в файл что ли? Нужно копировать код кнопкой в правом верхнем углу окна с кодом. Еще может быть дело в кодировке, тогда бы попробовать сделать имя слоя на латинице (правда, в этом случае в командной строке высветилась бы ошибка типа "неверный тип аргумента selsetp nil").
Я тестировал на 2011-й и 2015-й версиях - работает.
skkkk вне форума  
 
Непрочитано 08.02.2017, 20:39
#17
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,616


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
где бы (и у кого) в Питере программированию под AutoCAD поучиться?...
тут питерских полно, ищите в разделе Программирование и через личку спрашивайте... хотя, если на лисп свет клином не сошелся, то на youtube есть обучалки по VBA и C#. Было бы желание.
Boxa вне форума  
 
Автор темы   Непрочитано 08.02.2017, 20:44
#18
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


skkkk, копировал кнопками, пробовал в разных файлах. пробовал запихнуть код в .lsp файл - тоже не помогло... попробую еще слой на латинице сделать.

UPDATE! Со слоем латинскими буквами заработало!!! Спасибо! Похоже, что это то, что нужно!

skkkk, Вы - гений! Работает и в 2017 версии - похоже, что во всех. С порядком правда, да - беда.

А сделать так, чтобы еще и русские слои понимал и порядок по порядку листов очень сложно? Или номер листа перед текстом добавлял - у меня листы названы просто цифрами, можно из CTAB брать значение, но Ваш код я не понимаю, потому не знаю куда это добавить. А отсортировать потом можно уже и в ворде.

Пока начал разбираться с функциями setq и ssget. =) буду дальше гуглить.

Как я пытаюсь понять Ваш код:
Мы объявили о создании команды TEST, создали две локальные переменные ss и i и сказали, что они типа string
Далее присвоили переменной ss значение, возвращаемое функцией ssget, которая выделила объекты типа MTEXT - т.к указан групповой код 0 на конкретном слое (т.к. код 8).

Вот тут я правда не понял - ssget выделяет объекты по критериям, и получается в переменную ss мы сразу содержимое всех мтекстов засунули??? как он понял, что надо именно содержимое взять?
И вот что дальше в коде происходит мне уже непонятно..

Последний раз редактировалось Immortal_6666, 08.02.2017 в 22:11.
Immortal_6666 вне форума  
 
Непрочитано 08.02.2017, 21:59
#19
baksconstructor


 
Регистрация: 05.11.2014
Сообщений: 944


Immortal_6666
Тогда Вам прямая дорога к Реверс.
Эта прога найдёт Вам наименование, номера листов и другую инфу, воздаст ведомость в нужном порядке и т.д.
А Ваш пример файла - нужна только рамка со штампом, логотип можете удалить.
baksconstructor вне форума  
 
Автор темы   Непрочитано 08.02.2017, 22:04
#20
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


baksconstructor, для моих целей - это микроскоп. Слишком наворочено и много лишнего.

Код skkkk в принципе оптимальное решение, за исключением порядка строк.
Immortal_6666 вне форума  
 
Непрочитано 10.02.2017, 14:33
#21
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
чтобы еще и русские слои понимал
В какой текстовый редактор вставляете код для сохранения в lsp? Судя по проблемам с кодировкой, это скорее всего, Notepad++? Там надо в настройках выставить кодировку в ANSI или в Windows-1251. С Блокнотом такого быть не должно.
Что предпочтительней, чтобы
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
понимал и порядок по порядку листов
или
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
номер листа перед текстом добавлял
?
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
создали две локальные переменные ss и i и сказали, что они типа string
Неа, создали три локальные переменные: ss - набор объектов (тип данных в Автолисп - не то же самое, что выделенные ручками объекты), i - счетчик примитивов в наборе, str - строка, которая "собирается" из всех мтекстов в цикле и в итоге вставляется в новый текстовый объект.

----- добавлено через ~6 мин. -----
Только сейчас увидел отдельную тему на этот счет. Согласен с тем, что ее бы в Программирование надо отнести, но проще было попросить модераторов перенести ее в тот раздел, а не создавать такую же, это, выходит, - нарушение правил форума. Думаю, стоит удалить ту, а эту перенести туда.

----- добавлено через ~7 мин. -----
"Та" - эта вот эта: Помогите допилить LISP собирающий Мтексты с листов в буфер обмена.
skkkk вне форума  
 
Непрочитано 10.02.2017, 14:45
#22
baksconstructor


 
Регистрация: 05.11.2014
Сообщений: 944


Ну раз Immortal_6666 стесняется, то вот вам пример, вытащите в общий список "Наименование"
Думаю эту задачу пытается решить Immortal_6666, (я знаю как и предлагал уже).
Вложения
Тип файла: dwg
DWG 2010
Пример.dwg (123.0 Кб, 11 просмотров)
baksconstructor вне форума  
 
Непрочитано 10.02.2017, 14:56
#23
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


baksconstructor, извлечение данных? Там же все тексты в основной надписи на одном слое, и я не нашел в них "изюминки", по которой можно было бы вычленить их из общей массы.
И еще вопрос: будет ли это быстрее для каждого чертежа, чем запустить лисп, предварительно создав блок, шаблон или что-то подобное, в котором нужные тексты будут с "изюминкой"? Даже учитывая то, что можно использовать извлечение данных по шаблону.
skkkk вне форума  
 
Непрочитано 10.02.2017, 14:59
#24
baksconstructor


 
Регистрация: 05.11.2014
Сообщений: 944


skkkk
В том и прелесть что у автора это так есть везде, создавать новое низя. и хочет он именно в общий список только "Наименование".
Immortal_6666 поправьте если ошибаюсь.
baksconstructor вне форума  
 
Непрочитано 10.02.2017, 15:12
#25
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


baksconstructor, насколько я понял, у автора нет проблемы с созданием отдельного слоя нет. Но я бы все же использовал для основной надписи блок с атрибутами и собирал бы содержимое атрибута, например, с тэгом "Наименование".
skkkk вне форума  
 
Непрочитано 10.02.2017, 15:13
#26
baksconstructor


 
Регистрация: 05.11.2014
Сообщений: 944


Immortal_6666 аууууууу... да или нет ?
baksconstructor вне форума  
 
Автор темы   Непрочитано 10.02.2017, 16:04
#27
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Тут я в магазин ходил.
С темами - понял.

Теперь по сути вопроса. Это не основная надпись - не штамп это, в блок это пихать не удобно.
Решение с LISP-ом мне кажется оптимальным. Особенно, если потом его на кнопку повесить или на палитру. Проблемы создать под это дело отдельный слой вообще нет. И да, если удастся "добить тему", то сразу добавлю этот слой в свой шаблон.

skkkk, чтобы понимал порядок - это было бы оптимально, нумерацию я сам потом сделаю в word. Просто про номера написал на случай, если это вдруг проще, чем с порядком задачу решить, тогда я бы их потом сортировал руками.

Про переменные я уже сообразил последние два дня читаю книги по LISP. В новой теме как раз поправил себя, что это просто 3 переменные, без указания типа.
Пытался в vlide отслеживать значения переменных - как-то не получается... у ss еще иногда пишет 160 или 190 значение (опять же не понимаю, что он там считает и в каких единицах - думал буквы поштучно - ни фига), а i и str всегда nil.. но гораздо чаще когда пытаюсь вставлять куски кода пишет в консоли "неверно сформированный список на входе". В общем путь "понять код по кусочкам" пока не проходит.. При том, что код целиком работает. Не до конца понимаю, можно ли как-то замедлить исполнение команды и в реальном времени видеть изменение значений переменных? Пробовал "точки останова" - но что-то не то, или опять же не так использую.

В принципе теперь понял, что делают defun, setq, ssget, sslength. Правда у ssget адский синтаксис... просто жесть. Так и не понял, зачем там апостроф перед скобкой - `((0 . - точки еще эти через пробелы.. Видимо, это точечные пары.
Что делает vl-load-com тоже понял. А вот как цикл с repeat работает и что там "записано" пока не догоняю. i там каждый раз уменьшается на 1, видимо при 0 цикл останавливается. Ssname видимо возвращает "внутреннее" имя конкретного Мтекста из ранее выделенного набора. Потом он видимо помещается в новую строку и так с каждым Мтекстом. Но это догадки, из кода я этого не могу понять

Текст вставлял в обычный блокнот. Попробую в ++ с кодировкой поиграться. Спасибо!

baksconstructor, нет, у меня другая задача - ровно такая как я описал и выглядит как в примере, который я приложил в начале. Еще раз повторюсь, речь не о не штампе. Это имя листа, но оно скажем так не полное, а в штампе выводится тоже + масштаб - туда как раз попадает через поля из этого Мтекста и ВЭ. Слои делаю какие хочу, для старых проектов такие списки уже составлены, соотв. просто пытаюсь оптимизировать процесс на будущее. В принципе сразу про это и писал.
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Слой отдельный сделать для этого вообще не проблема.

UPDATE
С vlide более менее разобрался (спасает Полищук)

Цитата:
Сообщение от skkkk Посмотреть сообщение
Там надо в настройках выставить кодировку в ANSI или в Windows-1251.
перекодировал файл в ANSI (был в UTF-8) - теперь все отлично, русские слои понимает!!! УРА! Остался порядок

Последний раз редактировалось Immortal_6666, 10.02.2017 в 18:57.
Immortal_6666 вне форума  
 
Непрочитано 10.02.2017, 19:20
1 | #28
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Остался порядок
Код:
[Выделить все]
 (defun C:TEST ( / LtoT adoc aspace ss i en-txt str layout-nmbr accoc-list vla-txt)
	(vl-load-com)
	;;; вспомогательная функция LtoT 
	;;; преобразует список строк в строку с разделителем div1
	;;; http://forum.dwg.ru/showthread.php?p=47837#post47837
	(defun LtoT (l1 div1 / t1 v1)
	(if (not div1)(setq div1 " "))
	(if (> (length l1) 1)
	   (progn (setq t1 (car l1))
			(foreach v1 (cdr l1)
				(setq t1 (strcat t1 div1 v1))
			);end foreach
	   );end progn
	   (car l1)
	);end if
	);end LtoT	
	
	;;; начало основной функции
	(setq adoc (vla-get-activedocument (vlax-get-acad-object))
		  aspace 
			(if (or
					(= (getvar "CTAB") "Model")
					(and (/= (getvar "CTAB") "Model")(/= (getvar "CVPORT") 1))
				);end of or
				(vla-get-ModelSpace adoc) 
				(vla-get-PaperSpace adoc)
			);end of if
		  ss (ssget "_A" '((0 . "MTEXT")(8 . "текст")))
	);end of setq
	(if (> (sslength ss) (length (layoutlist))) (alert "Количество текстовых объектов больше, чем количество листов!"))
	(if ss
		(progn
			(repeat (setq i (sslength ss))
				(setq en-txt (ssname ss (setq i (1- i)))
					  str (vla-get-TextString (vlax-ename->vla-object en-txt))
					  layout-nmbr 
						(vla-get-TabOrder 
							(vla-Item 
								(vla-get-Layouts (vla-get-ActiveDocument (vlax-get-acad-object)))
								(cdr (assoc 410 (entget en-txt)))
							);end of vla-Item
						);end of vla-get-TabOrder
				);end of setq
				(if (null accoc-list)
					(setq accoc-list (list (list layout-nmbr str)))
					(setq accoc-list (append accoc-list (list (list layout-nmbr str))))
				);end of if
			);end of repeat
			(setq str (LtoT (mapcar 'cadr (vl-sort accoc-list (function (lambda (x y) (< (car x) (car y)))))) "\n"))
			(setq vla-txt
				(vla-AddMText 
					aspace
					(vlax-3d-point (cadr (grread T)))
					0
					str
				);end of vla-AddMText
			);end of setq
			(if vla-txt 
				(if (vl-cmdf "_CUTCLIP" (entlast) "")
					(vl-cmdf "_PASTECLIP" pause)
				)
			)
		);end of progn
		(princ "\nОшибка. Текстовые объекты, необходимые для работы программы, не найдены")
	);end of if
	(princ)
);end of defun
Бегло потестировал на файле из #4 в версиях 2011 и 2015 - глюков не выявил. Но нужно проверять плотнее на реальных примерах - может, что и всплывет.
Сортирует строки в соответствии с порядком следования листов - не по номерам в именах листов.
Кстати вспомнил, как-то делал прогу для автонумерации листов, думаю, при подобном подходе сгодится:
Код:
[Выделить все]
 (defun C:LAYOUTNUMERATOR ( / lyt-lst lyt-collection i lyt nmbr-str same-name-lyt tmp-name)
	(setq lyt-lst (layoutlist)
		  lyt-collection (vla-get-Layouts (vla-get-ActiveDocument (vlax-get-acad-object)))
	)
	(repeat (setq i (length lyt-lst))
		(setq lyt (vla-Item lyt-collection (nth (setq i (1- i)) lyt-lst))
			  nmbr-str (itoa (vla-get-TabOrder lyt))
		)
		(if (member nmbr-str (vl-remove (vla-get-Name lyt) lyt-lst))
			(progn
				(vla-put-Name 
					(setq same-name-lyt (vla-Item lyt-collection nmbr-str)) 
					(setq tmp-name (strcat (vla-get-Name same-name-lyt) "-TMP"))
				)
				(setq lyt-lst (subst tmp-name nmbr-str lyt-lst))
			)
		)
		(vla-put-Name lyt nmbr-str)
		(setq lyt-lst (subst nmbr-str (nth i lyt-lst) lyt-lst))
	)
	(princ)
)
skkkk вне форума  
 
Автор темы   Непрочитано 10.02.2017, 19:24
#29
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


skkkk, Спасибо огромное!!! Потестирую, отпишусь. Я уже и на кнопку смог подвесить загрузку лиспа и вызов команды - ^C^C(if (null C:_LISTIK)(load "listik"));_LISTIK;
Если теперь будет сортировать - вообще божественно!
С нумерацией проблем не было, но все равно спасибо! Я просто листы по 1 создаю - заранее никогда не известно, сколько их в проекте будет. Местами тоже не так часто меняю. Но может и найду применение второму скрипту.

UPDATE
Попробовал - работает, собирает в список в правильном порядке! Собирает отлично!
Единственное, что нашел - текст получается какой-то странный - его отказывается нумеровать и нумератор в автокаде, просто ставит цифру 1 и нумератор в word - тоже ставит просто 1, как-будто строки не разделены. Хотя там явно есть переход на след. строку.. какая-то странная особенность. Там даже по спец. символам в Ворде видно, что новая строка начинается не как "настоящая" новая строка, а как новая строка без разрыва - то, что делается по сочетанию клавиш SHIFT+ENTER. В общем какая-то пляска с последующей нумерацией.

В остальном, ок. С кнопки запускать вообще шикарно!

P.S. Есть какая-то команда, которую можно добавить в конце кода, чтобы он сразу содержимое Мтекста в буфер винды копировал?

PPS. Напишите мне в личку какие-нибудь свои реквизиты (карту/номер телефона) - я хоть символическую благодарность Вам переведу, действительно очень помогли!

Последний раз редактировалось Immortal_6666, 10.02.2017 в 19:54.
Immortal_6666 вне форума  
 
Непрочитано 10.02.2017, 21:00
1 | #30
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
строки не разделены
Проблема ясна, попробую разобраться.
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Есть какая-то команда, которую можно добавить в конце кода, чтобы он сразу содержимое Мтекста в буфер винды копировал?
Команда - не команда, но функция такая на форуме была - можно попробовать реализовать, Тогда, может, и вставка текста не нужна?

----- добавлено через ~21 мин. -----
Код:
[Выделить все]
 ;;; программа собирает тексты на слое "текст" со всех листов (и с модели тоже)
;;; и собирает их содержимое в текстовый объект, предварительно отсортировав в порядке следования листов
(defun C:TEST ( / LtoT adoc aspace ss i en-txt str layout-nmbr accoc-list vla-txt)
	(vl-load-com)
	;;; вспомогательная функция LtoT 
	;;; преобразует список строк в строку с разделителем div1
	;;; http://forum.dwg.ru/showthread.php?p=47837#post47837
	(defun LtoT (l1 div1 / t1 v1)
	(if (not div1)(setq div1 " "))
	(if (> (length l1) 1)
	   (progn (setq t1 (car l1))
			(foreach v1 (cdr l1)
				(setq t1 (strcat t1 div1 v1))
			);end foreach
	   );end progn
	   (car l1)
	);end if
	);end LtoT	
	
	;;; начало основной функции
	(setq adoc (vla-get-activedocument (vlax-get-acad-object))
		  aspace 
			(if (or
					(= (getvar "CTAB") "Model")
					(and (/= (getvar "CTAB") "Model")(/= (getvar "CVPORT") 1))
				);end of or
				(vla-get-ModelSpace adoc) 
				(vla-get-PaperSpace adoc)
			);end of if
		  ss (ssget "_A" '((0 . "MTEXT")(8 . "текст")))
	);end of setq
	(if (> (sslength ss) (length (layoutlist))) (alert "Количество текстовых объектов больше, чем количество листов!"))
	(if ss
		(progn
			(repeat (setq i (sslength ss))
				(setq en-txt (ssname ss (setq i (1- i)))
					  str (vla-get-TextString (vlax-ename->vla-object en-txt))
					  layout-nmbr 
						(vla-get-TabOrder 
							(vla-Item 
								(vla-get-Layouts (vla-get-ActiveDocument (vlax-get-acad-object)))
								(cdr (assoc 410 (entget en-txt)))
							);end of vla-Item
						);end of vla-get-TabOrder
				);end of setq
				(if (null accoc-list)
					(setq accoc-list (list (list layout-nmbr str)))
					(setq accoc-list (append accoc-list (list (list layout-nmbr str))))
				);end of if
			);end of repeat
			(setq str (LtoT (mapcar 'cadr (vl-sort accoc-list (function (lambda (x y) (< (car x) (car y)))))) " \n"))
			(copyToclipboard str)
			; (setq vla-txt
				; (vla-AddMText 
					; aspace
					; (vlax-3d-point (cadr (grread T)))
					; 0
					; str
				; );end of vla-AddMText
			; );end of setq
			; (if vla-txt 
				; (if (vl-cmdf "_CUTCLIP" (entlast) "")
					; (vl-cmdf "_PASTECLIP" pause)
				; )
			; )
		);end of progn
		(princ "\nОшибка. Текстовые объекты, необходимые для работы программы, не найдены")
	);end of if
	(princ)
);end of defun



Код:
[Выделить все]
 ;;; программа собирает тексты на слое "текст" со всех листов (и с модели тоже)
;;; и собирает их содержимое в текстовый объект, предварительно отсортировав в порядке следования листов
(defun C:TEST ( / LtoT adoc aspace ss i en-txt str layout-nmbr accoc-list vla-txt)
	(vl-load-com)
	;;; вспомогательная функция LtoT 
	;;; преобразует список строк в строку с разделителем div1
	;;; http://forum.dwg.ru/showthread.php?p=47837#post47837
	(defun LtoT (l1 div1 / t1 v1)
	(if (not div1)(setq div1 " "))
	(if (> (length l1) 1)
	   (progn (setq t1 (car l1))
			(foreach v1 (cdr l1)
				(setq t1 (strcat t1 div1 v1))
			);end foreach
	   );end progn
	   (car l1)
	);end if
	);end LtoT	
	
	;;; начало основной функции
	(setq adoc (vla-get-activedocument (vlax-get-acad-object))
		  aspace 
			(if (or
					(= (getvar "CTAB") "Model")
					(and (/= (getvar "CTAB") "Model")(/= (getvar "CVPORT") 1))
				);end of or
				(vla-get-ModelSpace adoc) 
				(vla-get-PaperSpace adoc)
			);end of if
		  ss (ssget "_A" '((0 . "MTEXT")(8 . "текст")))
	);end of setq
	(if (> (sslength ss) (length (layoutlist))) (alert "Количество текстовых объектов больше, чем количество листов!"))
	(if ss
		(progn
			(repeat (setq i (sslength ss))
				(setq en-txt (ssname ss (setq i (1- i)))
					  str (vla-get-TextString (vlax-ename->vla-object en-txt))
					  layout-nmbr 
						(vla-get-TabOrder 
							(vla-Item 
								(vla-get-Layouts (vla-get-ActiveDocument (vlax-get-acad-object)))
								(cdr (assoc 410 (entget en-txt)))
							);end of vla-Item
						);end of vla-get-TabOrder
				);end of setq
				(if (null accoc-list)
					(setq accoc-list (list (list layout-nmbr str)))
					(setq accoc-list (append accoc-list (list (list layout-nmbr str))))
				);end of if
			);end of repeat
			(setq str (LtoT (mapcar 'cadr (vl-sort accoc-list (function (lambda (x y) (< (car x) (car y)))))) "\\P"))
			(setq vla-txt
				(vla-AddMText 
					aspace
					(vlax-3d-point (cadr (grread T)))
					0
					str
				);end of vla-AddMText
			);end of setq
			(if vla-txt 
				(if (vl-cmdf "_CUTCLIP" (entlast) "")
					(vl-cmdf "_PASTECLIP" pause)
				)
			)
		);end of progn
		(princ "\nОшибка. Текстовые объекты, необходимые для работы программы, не найдены")
	);end of if
	(princ)
);end of defun

Последний раз редактировалось skkkk, 10.02.2017 в 22:32.
skkkk вне форума  
 
Автор темы   Непрочитано 10.02.2017, 21:33
#31
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Да, вставка в текущий документ по смыслу и не нужна. Нужно в буфер только, единственное, можно какое-то сообщение выводить, что команда успешно отработала, прямо в командной строке - глянул, увидел, что все ок. Но опять же, если это как-то очень заморочисто, то и не надо. То, что сейчас уже отлично. Я просто думал, что можно как-то "по-простому" зайти в этот подготовленный мтекст, взять его содержимое и что-то вроде ctrl+с сделать программно, потом текст стереть. Но по коду вижу, что там как-то сложно все выходит.

Второй вариант работает отлично!
А первый, где через буфер выдает - ; ошибка: no function definition: COPYTOCLIPBOARD

Последний раз редактировалось Immortal_6666, 10.02.2017 в 21:51.
Immortal_6666 вне форума  
 
Непрочитано 10.02.2017, 22:06
1 | #32
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
можно какое-то сообщение выводить, что команда успешно отработала
В варианте с буфером после строчки
Код:
[Выделить все]
(copyToclipboard str)
добавить что-то вроде:
Код:
[Выделить все]
(alert (strcat "Добавлено в буфер обмена:\n" str))
----- добавлено через ~6 мин. -----
Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
А первый, где через буфер выдает - ; ошибка: no function definition: COPYTOCLIPBOARD
Странно это, ведь функция добавлена в код. Проверил еще раз, взяв код с форума - отработало без проблем.
Может, надо перезагрузить Автокад и заново загрузить код? Просто, возможно, как-то конфликтуют одна версия с другой.

----- добавлено через ~13 мин. -----
Или попробовать загрузить отдельно функцию
Код:
[Выделить все]
 (defun copyToclipboard ( text / htmlfile result)
 (setq result
        (vlax-invoke
            (vlax-get
                (vlax-get
                    (setq htmlfile (vlax-create-object "htmlfile"))
                   'ParentWindow
                )
               'ClipBoardData
            )
           'SetData
            "Text"
            text
        )
    )

    (vlax-release-object htmlfile)
    result
)
(defun Clearclipboard (  / htmlfile)

(vlax-invoke
            (vlax-get
                (vlax-get
                    (setq htmlfile (vlax-create-object "htmlfile"))
                   'ParentWindow
                )
               'ClipBoardData
            )
           'clearData
            "Text"
        )
(vlax-release-object htmlfile)
)

(defun Getclipboard ( / htmlfile result)
(setq result
        (vlax-invoke
            (vlax-get
                (vlax-get
                    (setq htmlfile (vlax-create-object "htmlfile"))
                   'ParentWindow
                )
               'ClipBoardData
            )
           'GetData
            "Text"
        )
    )

    (vlax-release-object htmlfile)

    result
)


----- добавлено через ~14 мин. -----
Сейчас есть возможность тестировать только на 2011 - там все работает. В более поздних версиях появились разные политики безопасности, с которыми я еще не очень знаком.
skkkk вне форума  
 
Автор темы   Непрочитано 10.02.2017, 22:22
#33
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Перезагрузил, пробовал в разных версиях 2014 и 2017 - та же ошибка. Пробовал и как текст в VLIDe копировать и как отдельный .lsp файл подгружать...


Цитата:
Сообщение от skkkk Посмотреть сообщение
Или попробовать загрузить отдельно функцию
Насчет отдельно загрузить не понял... сделать отдельный LISP и ее потом вызывать? Не понял как это состыковать с основным кодом.
Этот кусок сам по себе ошибок не выдает.
Immortal_6666 вне форума  
 
Непрочитано 10.02.2017, 22:24
1 | #34
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Да, под спойлером эта функция отдельно. Сохранить ее в отдельный файл и перед запуском TEST загрузить этот файл. Правда в этом случае ее лучше стереть из основного кода, дабы разных конфликтов не было. Я там еще подтёр разные ненужные вещи, которые гипотетически могут вызывать ошибки.
skkkk вне форума  
 
Автор темы   Непрочитано 10.02.2017, 22:37
#35
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Цитата:
Сообщение от skkkk Посмотреть сообщение
Да, под спойлером эта функция отдельно. Сохранить ее в отдельный файл и перед запуском TEST загрузить этот файл. Правда в этом случае ее лучше стереть из основного кода, дабы разных конфликтов не было. Я там еще подтёр разные ненужные вещи, которые гипотетически могут вызывать ошибки.
Спасибо, понял. А потерли в основном коде или в том, где отдельно функция копирования в буфер? И я так понимаю, что потом ее еще надо вызвать отдельно командой copytoclipboard ?

UPDATE

Вроде разобрался. Сделал отдельный файл. В основном эту часть удалил. И вызываю все это дело таким скриптом ^C^C(if (null C:_COPYTOCLIPBOARD)(load "copytoclip.lsp"));(if (null C:_LISTIK)(load "listik.lsp"));_LISTIK
Я заменил имя TEST на LISTIK.

Все работает похоже. В модель не вставляется, в буфер копируется. Это просто отлично! Но я так и не нашел строку (copyToclipboard str) чтобы вставить оповещение =)))

Последний раз редактировалось Immortal_6666, 10.02.2017 в 22:54.
Immortal_6666 вне форума  
 
Непрочитано 10.02.2017, 22:55
1 | #36
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
Но я так и не нашел строку (copyToclipboard str) чтобы вставить оповещение )))
В #30 в варианте с буфером строка 52
skkkk вне форума  
 
Автор темы   Непрочитано 10.02.2017, 23:10
#37
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


Все, нашел! Добавил! Я просто в конце кода почему-то искал.
Все супер теперь! Для меня это настолько "хаманство", что даже не верится! Спасибо еще раз!

А Вы именно программист? Или пользователь автокада? Я конечно продолжу все это изучать, просто интересно, сколько лет надо потратить, чтобы так влёт решать подобные задачи?
Я профессиональным программистом уже точно не стану, да и цели такой нет, но научиться писать подобные вещи для автоматизации рутины хотелось бы. Просто по одному направлению работа реально типовая, может еще что-то удастся формально описать и реализовать программно. Хотя на данный момент кажется, что автоматизировал все, что мог. Рутины все равно очень много но она уж больно вариативная.

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

П.С. Насчет благодарности я серьезно писал, так что надумаете - пишите в лс.
Immortal_6666 вне форума  
 
Непрочитано 10.02.2017, 23:43
#38
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,680


Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
А Вы именно программист? Или пользователь автокада?
Когда-то также просто захотел упростить рутину и также пришел сюда за помощью. Не могу судить сам, что я должен из себя представлять, чтобы слыть программистом. Я бы сказал, что пока просто - программист-любитель, по большей части - пользователь. Для меня это пока больше хобби. Да и задачка Ваша - довольно плёвая. Тут есть мастодонты, которые бы при желании решили бы ее намного "влётнее" и красивее. В основном, для себя и довольно узкого круга моих коллег уже приходилось решать на порядок более сложные задачи, повысив в разы производительность. Доводилось участвовать и в более ли менее серьезных сторонних проектах.

Цитата:
Сообщение от Immortal_6666 Посмотреть сообщение
просто интересно, сколько лет надо потратить, чтобы так влёт решать подобные задачи?
Начинал вникать я в это дело где-то в 2009-м, лет пять-шесть назад понял, что под силу стало решить практически любую задачу в лиспе - и решал, другой вопрос, что времени на все это было не так много - по совместительству. Коллеги зачастую как могли тянули многие мои дела, чтобы я писал код, они в меня верили - и ни капли не жалеют сейчас об этом.
Хочу сказать, что это все вполне реально - освоить для себя программирование, - и стоит того, особенно, если в удовольствие. Только, возможно, стоит подумать над выбором языка. Лисп - довольно прост в освоении, есть много готового на нем тут, и на других форумах, в том числе англоязычных, но возможности ограничены. Например, из лиспа не подобраться к подшивке, не получить красивых, продвинутых диалоговых окон, но основные задачи по черчению, решаемые в Автокаде, ему доступны, в том числе различные расчеты, да и вообще можно давать волю фантазии. Главное самому понимать и формулировать задачи. Как раз сейчас тут идет бурное обсуждение по поводу выбора языка, советую почитать прежде чем начинать "погружение" .
skkkk вне форума  
 
Автор темы   Непрочитано 11.02.2017, 07:28
#39
Immortal_6666

вольный копейщик
 
Регистрация: 03.11.2010
Сообщений: 132


skkkk, ну это более менее разумный срок Уделить такое время этой теме я смогу себе позволить.

В личку отписал ) За рекомендации спасибо, ознакомлюсь.
Immortal_6666 вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Собрать содержимое МТЕкста с разных листов в один документ/объект



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Копирование, сортировка, переименование листов (layout) VVA Готовые программы 115 28.03.2025 20:59
Печать в один PDF фаил нескольких листов YuryKlimchuk AutoCAD 103 24.05.2018 20:47
Упорядочивание вкладок (листов) Малюк AutoCAD 15 18.11.2015 17:03
Как собрать несколько DWF файлов в один koks AutoCAD 7 24.06.2013 11:44
Как собрать несколько оформленных чертежей в один E.D. AutoCAD 33 16.07.2009 09:42