| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Извлечение ObjID указанного объекта в буфер обмена

LISP. Извлечение ObjID указанного объекта в буфер обмена

Ответ
Поиск в этой теме
Непрочитано 17.07.2020, 16:08 #1
LISP. Извлечение ObjID указанного объекта в буфер обмена
modest-bp
 
Регистрация: 15.04.2019
Сообщений: 58

Здравствуйте!
Подскажите, пожалуйста, макрос для кнопки, чтобы при её нажатии в командной строке выводилось ObjId выбранного объекта (а если не выбран - то сначала запрашивался бы выбор) и это же значение автоматически загонялось в clipboard.
Заранее очень благодарен за помощь!

Последний раз редактировалось modest-bp, 21.07.2020 в 10:44. Причина: В ходе обсуждения выяснилось, что макросом задача не решается, нужен .LSP
Просмотров: 3127
 
Непрочитано 17.07.2020, 16:39
#2
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


хм?
Сергей812 вне форума  
 
Автор темы   Непрочитано 19.07.2020, 22:39
#3
modest-bp


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


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Не могу разобраться с рекомендациями, которые там давались. Не получается заставить работать.
Создаю в блокноте файл, в который закидываю код:

Код:
[Выделить все]
 
(vl-load-com)
(defun Get-ObjectID-x86-x64 (obj / util)
  (setq util (vla-get-Utility (vla-get-activedocument (vlax-get-acad-object))))
  (if (= (type obj) 'ENAME)(setq obj (vlax-ename->vla-object obj)))
  (if (= (type obj) 'VLA-OBJECT)
     (if (> (vl-string-search "x64" (getvar "platform")) 0)
       (vlax-invoke-method util "GetObjectIdString" obj :vlax-False)
       (rtos (vla-get-objectid obj) 2 0)
     )
  )
)
Сохраняю этот файл с расширением .LSP

Далее создаю кнопку. В макросе у неё пишу:
(Get-ObjectID-x86-x64)

Подгружаю лисп - "успешно загружен"

Далее тыкаю в кнопку - и получаю сообщение:

Command: (Get-ObjectID-x86-x64) ; error: too few arguments

Но хуже того: даже если мне удастся заставить этот код в лиспе работать и получать ObjId (я ещё даже не знаю, где он отобразится, поскольку в коде лиспа ведь нет никаких printc, то пришить к этому коду кусок лиспа для отправки ObjId в клипборд - будет для меня явно выше всяких возможностей.
Поскольку, как мы с вами один раз уже выяснили, языкам я не обучен.
modest-bp вне форума  
 
Непрочитано 19.07.2020, 22:49
1 | #4
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


Цитата:
Сообщение от modest-bp Посмотреть сообщение
я ещё даже не знаю, где он отобразится, поскольку в коде лиспа ведь нет никаких printc
это функция и возвращает - в лиспе нет никаких отдельных языковых инструкций, последнее вычисленное внутри функции значение и есть результат, возвращаемый функцией. А как вызывать - VVA же написал в явном виде
Код:
[Выделить все]
 (get-objectid-x86-x64 (car (entsel)))
Сергей812 вне форума  
 
Автор темы   Непрочитано 20.07.2020, 16:42
#5
modest-bp


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


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
А как вызывать - VVA же написал в явном виде
Код:
[Выделить все]
 (get-objectid-x86-x64 (car (entsel)))
Большое спасибо! Не заметил я слона))) Теперь заработало)

Дальше "приклеил" к нему код из copyToClipboard от VVA, поставив вызов по его же инструкции - и ID стал отправляться в клипборд.....
Код:
[Выделить все]
 (vl-load-com)
(defun Get-ObjectID-x86-x64 (obj / util)
  (setq util (vla-get-Utility (vla-get-activedocument (vlax-get-acad-object))))
  (if (= (type obj) 'ENAME)(setq obj (vlax-ename->vla-object obj)))
  (if (= (type obj) 'VLA-OBJECT)
     (if (> (vl-string-search "x64" (getvar "platform")) 0)
       (vlax-invoke-method util "GetObjectIdString" obj :vlax-False)
       (rtos (vla-get-objectid obj) 2 0)
     )
  )
)
(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
)
... Но теперь ID не выводится в командной строке))))
Методом научного тыка, подставляя (princ *что-нибудь*) в разные строки кода и пытаясь наугад понять, какую же переменную следует указывать в звёздочках - ничего у меня не вышло.
Пробовал даже под
Код:
[Выделить все]
            'SetData
            "Text"
подписать
Код:
[Выделить все]
            'GetData
            "Text"
Не помогло...

А ещё эти программы работают только в одной среде: если нужно взять ID у объекта, размещённого в пространстве модели, то надо находиться в пространстве модели. Через вьюпорт ткнуть на объект в модельном пространстве не получается.
Есть какой-нибудь метод это подправить?
modest-bp вне форума  
 
Непрочитано 20.07.2020, 16:57
1 | #6
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


Цитата:
Сообщение от modest-bp Посмотреть сообщение
... Но теперь ID не выводится в командной строке))))
потому что это был побочный эффект - если не погасить вывод пустым (princ) в функции, то в комстроке будет выведено последнее посчитанное/полученное значение.
Цитата:
Сообщение от modest-bp Посмотреть сообщение
Методом научного тыка, подставляя (princ *что-нибудь*) в разные строки кода и пытаясь наугад понять, какую же переменную следует указывать в звёздочках - ничего у меня не вышло.
надо не тыкать, а прочитать базовые вещи по языку программирования - например. Чтобы хотя бы различать определение просто функции и функции с возможностью вызова из комстроки акада.
Сергей812 вне форума  
 
Автор темы   Непрочитано 20.07.2020, 17:31
#7
modest-bp


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


И ещё один вопрос.
Форма макроса, который перед подгрузкой лиспа проверяет наличие команды - мне известна:
Код:
[Выделить все]
 ^C^C(if (not C:{команда}) (load "{лисп_с_командой}"));{команда};
или
Код:
[Выделить все]
 ^C^C(if (null C:{команда}) (load "{лисп_с_командой}"));{команда};
Но как быть, если лисп не команду загружает, а функцию (как раз как этот, который ObjID извлекает и в клипборд отправляет)?
Надо задать имя команды для этой функции? Подскажите, пожалуйста, как, потому как, не зная никакого синтаксиса, я точно это сделать не смогу (в скобках потеряюсь)
Или можно обойтись без назначения команды? Тогда как?

----- добавлено через ~12 мин. -----
Цитата:
Сообщение от Сергей812 Посмотреть сообщение
базовые вещи по языку программирования - например
Спасибо.
modest-bp вне форума  
 
Непрочитано 20.07.2020, 18:47
1 | 1 #8
skkkk


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


modest-bp, для этих функций надо создать команду-оболочку:
Код:
[Выделить все]
 (defun C:ID2CLP ( / obj ID) ;;; объявляем новую команду автокад. 
 ;;; Аргументов (до слэша) нет, а после слэша - объявление локальных переменных obj и ID.
 ;;; Если переменные, задаваемые в коде функцией setq не сделать локальными, 
 ;;; то они после завершения функции станут глобальными переменными Автокада и будут жить до конца сеанса, забивая память. 
 ;;; Поскольку в данном случае этого не нужно, делаем их локальными - перечисляем после слэша. 
	
	;;; запрашиваем у пользователя объект
	(setq obj (car (entsel "\nВыберите объект для определения его ID:")))
	(if obj ;;; если объект выбран, 
		(setq ID (Get-ObjectID-x86-x64 obj)) ;;; то вызываем функцию определения его ID, аргумент - выбранный объект (obj),
		(princ "\nОбъект не выбран.") ;;; если не выбран, то пишем об этом в командную строку
	) ;;; закрываем скобку if
	(if ID ;;; если ID определен, 
		(progn ;;; открываем "программную скобку" для if с помощью функции progn, чтоб можно было выполнить несколько действий
			(copyToclipboard ID) ;;; 1) вызываем функцию помещения строки ID в буфер,
			(princ (strcat "\nID " ID " скопирован в буфер.")) ;;; 2) пишем об этом в командную строку 
		) ;;; закрываем "программную скобку" для if в виде скобки для progn
		(princ "\nID не определен.") ;;; если ID НЕ определен, пишем в командную строку
	) ;;; закрываем скобку if
	(princ) ;;; пустым princ'ом гасим повторное сообщение в командную строку

) ;;; закрываем скобку defun
(vl-load-com)
(defun Get-ObjectID-x86-x64 (obj / util)
  (setq util (vla-get-Utility (vla-get-activedocument (vlax-get-acad-object))))
  (if (= (type obj) 'ENAME)(setq obj (vlax-ename->vla-object obj)))
  (if (= (type obj) 'VLA-OBJECT)
     (if (> (vl-string-search "x64" (getvar "platform")) 0)
       (vlax-invoke-method util "GetObjectIdString" obj :vlax-False)
       (rtos (vla-get-objectid obj) 2 0)
     )
  )
)
(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
)

(princ "C:ID2CLP")
(princ)
В коде прописал комментарии для более полного понимания процесса (коли уж возникло такое желание самостоятельно разобраться).

----- добавлено через ~4 мин. -----
Если лисп сохранить с именем "ID2CLP.lsp", макрос на кнопку будет таким:
Код:
[Выделить все]
^C^C(if (not C:ID2CLP) (load "ID2CLP.lsp"));(C:ID2CLP);
----- добавлено через ~10 мин. -----
Да, и предлагаю сменить название темы. Поскольку макросом общепринято в Автокаде называется именно код кнопки, макрокоманда, а тут макросом не обошлось, то это уже лисп - в данном контексте прижившееся название кода на этом языке.
Думаю, правильным будет что-то подобное: LISP. Извлечение ObjID указанного объекта в буфер обмена. Хотя, после того, как раздел "Программирование" разделили на подразделы и, поскольку тема добавлена в подразделе "LISP", может, префикс LISP._ уже и не нужен. На мой взгляд удобно: когда видишь в "Горячем" в названии темы префикс, сразу понимаешь, о каком языке речь. Хотелось бы знать мнение администрации на сей счет.
Но "макрос" - точно будет сбивать с толку.

Последний раз редактировалось skkkk, 21.07.2020 в 10:21.
skkkk вне форума  
 
Автор темы   Непрочитано 21.07.2020, 00:28
#9
modest-bp


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


Цитата:
Сообщение от skkkk Посмотреть сообщение
modest-bp, для этих функций надо создать команду-оболочку:
ОГРОМНОЕ спасибо! Всё работает! Всё работает, как надо!

Цитата:
Сообщение от skkkk Посмотреть сообщение
В коде прописал комментарии для более полного понимания процесса (коли уж возникло такое желание самостоятельно разобраться).
Как же они помогли! Прямо как для дебила - ровно так, как мне и надо было!!!

Да, Сергей812, наверное, расстроится, что мне дали рыбку, а не удочку. Но и за его удочку я тоже благодарен: не ровен час, почитаю учебник. Просто моя работа - не программирование, а проектирование. Поэтому на освоение ещё одной профессии (пусть и её азов) - времени никогда не находится (тут и по своему профилю всегда есть масса того, что надо почитать).
А Вы таким подробным комментированием кода дали возможность понять на конкретном примере, что как работает, да ещё и открыли мне возможность потом творчески дорабатывать этот код под свои нужды, а не засорять форум своими профановскими темами.
Ещё раз спасибо от всей души! Поскольку этой командой предстоит пользоваться очень часто - буду Вас часто вспоминать самыми добрыми словами!

Цитата:
Сообщение от skkkk Посмотреть сообщение
Да, и предлагаю сменить название темы. (...) На мой взгляд удобно: когда видишь в "Горячем" в названии темы префикс, сразу понимаешь, о каком языке речь.
Согласен. На будущее буду иметь в виду (но я действительно надеялся, что можно будет обойтись макросом). А сейчас поменять тему уже, похоже, не в моих силах (по крайней мере, я не нашёл, как это делается)
modest-bp вне форума  
 
Непрочитано 21.07.2020, 01:01
| 1 #10
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,004


Offtop:
Цитата:
Сообщение от modest-bp Посмотреть сообщение
Просто моя работа - не программирование, а проектирование.
да наша с skkkk тоже как бы...
Сергей812 вне форума  
 
Непрочитано 21.07.2020, 10:19
1 | #11
skkkk


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


Offtop:
Цитата:
Сообщение от modest-bp Посмотреть сообщение
А сейчас поменять тему уже, похоже, не в моих силах (по крайней мере, я не нашёл, как это делается)
В углу стартового сообщения нажать "Правка", затем "Расширенный режим". Появится поле с заголовком темы, которое можно отредактировать.
skkkk вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Извлечение ObjID указанного объекта в буфер обмена

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
SPDS макрос на кнопку масштаб нужна помощь dextron3 ПО от CSoft 18 20.05.2019 13:37
Как избавиться от искажения объекта после перемещения объекта. boroda205 AutoCAD 2 21.09.2018 15:44
Помогите дополнить макрос простановки уклона MrBrown Программирование 2 14.04.2015 13:50
Помогите сделать макрос на циклический перебор: орто/поляр.отсл./выкл все VAV AutoCAD 4 23.01.2015 12:38