Меню

Ошибка неверный тип аргумента lentityp nil

I’ve looked pretty much everywhere else for help and haven’t found it. I hope someone here can help me.

Suddenly, out of the blue, I’m getting an error whenever I try to insert components onto certain wires in my drawing. Not all wires are behaving this way, and I can’t figure out what the difference is. This is happening using one and three phase symbols. This is the error I get:

 [initiate command and choose a symbol]
Specify insertion point: [tried to place on existing wire]
Extracting networks: 1
Error: bad argument type: lentityp nil_.UNDO Current settings: Auto = On, Control = All, Combine = Yes, Layer = Yes
Enter the number of operations to undo or [Auto/Control/BEgin/End/Mark/Back] <1>: _END

This happens exactly where I would normally see the dialog box asking me if the symbol builds up or down. Frustratingly, the last line doesn’t always show; sometimes the command just craps out and all I get is «Error: bad argument type: lentityp nil». I don’t initiate the UNDO that shows up in the message, whatever is going on is causing that to happen. Needless to say, I’m very confused.

If I just insert a symbol into empty space, or if I draw fresh wires, everything seems OK. I have tried AUDIT and AEREBUILDDB with no effect. This problem exists only in one project. I use only AE commands when modifying. Every time I delete a symbol, I purge it.

This appears to be easily fixable by simply drawing new wires, but I would still like to know what caused this to happen. Bad housekeeping? Inadvertently using some vanilla command? Any help would be appreciated. I’ve attached one of the fouled-up drawings.

Thanks,

Jim



Jim Seefeldt
Electrical Engineering Technician

В этом уроке мы рассмотрим пример AutoLISP программы, которая будет считать сумму длин выбираемых отрезков.

Вначале нарисуем в AutoCAD два отрезка: один длиной 300, другой 200. Чтобы нам было, чего выбирать, и легче было тестировать программу.

Затем запустим Visual LISP, создадим новый файл и откроем консоль Visual LISP.

Для того, чтобы выбрать объект в AutoLISP используется функция entsel.

Функция entsel предлагает пользователю указать объект, выдавая запрос, текст которого задан в качестве аргумента.

( entsel [<запрос>])

Аргумент <запрос> — текст запроса.

Давайте наберем функцию.

(entsel «Выберите отрезок:»: «)

Дважды щелкнем после закрывающейся скобки (функция выделится) и нажмем кнопку «Загрузить выделенный фрагмент». См. Рис. 1.

Пример AutoLISP

Рис. 1.  Функция entsel

На запрос: «Выберите отрезок:» укажите один из ранее нарисованных отрезков. См. Рис. 2.

Пример AutoLISP

Рис. 2.    Выбор отрезка.

Функция entsel вернет нам имя объекта и координаты точки, которые мы указали, выбирая отрезок. См. Рис. 3.

Пример AutoLISP

Рис. 3. Функция entsel. Имя объекта и координаты точки.

Чтобы, оставить только имя объекта, используем функцию car, которая извлекает первый элемент из списка.

В начале запроса поставим n, чтобы он отображался в отдельной строке.

Выделяем всю строку и нажмем кнопку «Загрузить выделенный фрагмент».

На запрос, «Выберите отрезок:» укажите один из ранее нарисованных отрезков.

На консоли Visual LISP появится результат выполнения всей строки — это имя выбранного объекта.

См. Рис. 4.

Пример AutoLISP

Рис. 4.   Функция car. Имя выбранного объекта.

Давайте, при помощи функции присвоения setq, запомним это имя в переменной name_obj.

(setq name_obj (car (entsel «n Выберите отрезок: «)))

Для того, чтобы получить список с характеристиками примитива используем функцию entget. Аргументом этой функции является имя примитива, данные которого мы хотим получить. См. Рис. 5.

Пример AutoLISP

Рис. 5.   Функция entget. Список с характеристиками примитива.

Выделяем вторую строку и нажмем кнопку «Загрузить выделенный фрагмент».

На консоли Visual LISP появится результат выполнения : список с характеристиками примитива.

Весь список выглядит так:

 ((-1 . < Имя объекта: 7ee90e38>) (0 . «LINE») (330 . < Имя объекта: 7ee8ecf8>) (5 . «32F») (100 . «AcDbEntity») (67 . 0) (410 . «Model») (8 . «0») (100 . «AcDbLine») (10 4905.76 5404.8 0.0) (11 5125.47 5609.07 0.0) (210 0.0 0.0 1.0))

Давайте, при помощи функции присвоения setq, запомним этот список в переменной list_obj.

(setq list_obj (entget name_obj))

Из этого списка нам нужны координаты точек выбранного отрезка. Для того, чтобы их от туда извлечь, используем функцию assoc.

Функция assoc применяется к сложному списку, каждый элемент которого начинается с DXF-кода. Именно по этому коду функция assoc и извлекает элемент из списка.

(assoc <код> <список>)

<код>  — DXF-код.

<список> — список с данными примитива.

Для того чтобы получить элемент списка, который содержит координаты первой точки, добавим строку:

(assoc 10 list_obj)

10 – это  DXF-код координат первой точки.

Выделяем третью строку и нажмем кнопку «Загрузить выделенный фрагмент».

В консоли появится результат выполнения. См. Рис. 6.

Пример AutoLISP

Рис. 6.  Функция assoc.  Элемент списка с DXF-кодом 10.

Из списка будет извлечен элемент с DXF-кодом 10.

Для того, чтобы оставить только координаты точки, добавляем функцию cdr.

(cdr(assoc 10 list_obj))

возвращает список без первого элемента.

При помощи функции присвоения setq, запомним значения координат в переменной р1.

(setq p1 (cdr(assoc 10 list_obj)))

Выделяем третью строку и нажмем кнопку «Загрузить выделенный фрагмент».

В консоли появится результат выполнения. См. Рис. 7.

Пример AutoLISP

Рис. 7.   Функция cdr.

В переменной р1 теперь хранятся координаты начальной точки отрезка.

Аналогичным образом извлекаем из списка list_obj координаты конечной точки отрезка (DXF-код конечной точки отрезка равен 11), и сохраняем их в переменной р2.

(setq p2 (cdr(assoc 11 list_obj)))

Длину отрезка определяем при помощи функции distance.

Функция  (distance <точка1> < точка2>) вычисляет расстояние между двумя точками, где

<точка1> < точка2> — координаты точек.

Давайте добавим строку:

(setq dl_otr (distance р1 р2))

в которой мы вычисляем длину выбранного отрезка, и сохраняем ее в переменной dl_otr

Выделяем последние две строчки и нажимаем кнопку «Загрузить выделенный фрагмент».

В консоли появится результат выполнения. Координаты второй точки и длина выбранного отрезка. См. Рис. 8.

Пример AutoLISP

Рис. 8.   Функция distance.

Для того, чтобы программа после указания первого отрезка запросила следующий мы организует цикл при помощи функции while.

Функция while выполняет операцию цикла по многократно проверяемому условию.

(while <условие>

      <выражения>

)

Если <условие> верно, то оно возвращает Т (True), если не верно то nil.

Пока <условие> принимает значение Т, функция while выполняет <выражения>, и она прекратит свою работу, когда на некотором шаге аргумент <условие> получит значение nil.

Чтобы наш цикл был бесконечным, мы вместо условия поставим значение Т.

(while Т

      <выражения>

)

В этом случаи наш цикл будет бесконечно запрашивать новый отрезок, пока мы не прервем его, нажав на <Esc>

Для того, чтобы сосчитать сумму длин выбранных отрезков, введем переменную sum_dl.

Перед началом цикла присвоим sum_dl начальное значение 0.0.

(setq sum_dl 0.0)

Внутри цикла добавим выражение:

(setq sum_dl (+ sum_dl dl_otr))

На первом шаге к sum_dl =0.0 прибавится длина первого отрезка dl_otr. Сумма снова присваивается переменной sum_dl.

На втором шаге к sum_dl (которая равна длине первого отрезка) прибавится длина второго выбранного отрезка dl_otr. Сумма снова присваивается переменной sum_dl.

И так далее с каждым новым шагом мы будем прибавлять длину выбранного отрезка к сумме отрезков выбранных ранее.

Чтобы напечатать результат в командной строке добавим выражение:

(princ sum_dl)

В результате наша программа будет выглядеть так. См. Рис. 9.

Пример AutoLISP

Рис. 9.   Функция while. Создания цикла.

Выделяем весь текст и нажимаем кнопку «Загрузить выделенный фрагмент».

На запрос: «Выберите отрезок:» укажите один из ранее нарисованных отрезков.

В командной строке появится длина выбранного отрезка, ниже снова появится запрос: «Выберите отрезок:»  См. Рис. 10.

Пример AutoLISP

Рис. 10.    Длина выбранного отрезка.

Укажите второй отрезок, и в командной строке появится сумма длин двух отрезков.

Ниже снова появится запрос: «Выберите отрезок:»  См. Рис. 11.

Пример AutoLISP

Рис. 11.   Сумма длин двух отрезков.

Чтобы прервать выполнения программы нажмите <Esc>.

Хотя мы и получили требуемый результат, написание программы еще не окончено.

Давайте проверим, что будет, если при выборе отрезка мы промахнемся и щелкнем мимо.

Снова выделяем весь текст и нажимаем кнопку «Загрузить выделенный фрагмент».

На запрос: «Выберите отрезок:», щелкнете в пустом месте не выбирая отрезок.  См. Рис. 12.

Пример AutoLISP

Рис. 12.    Ошибка: неверный тип аргумента.

Программа прервет свою работу.

В консоли Visual LISP появится сообщение: ошибка: неверный тип аргумента: lentityp nil.

Очевидно, что после того, как мы промахнулись при выборе отрезка, функция entsel вернуло не имя выбранного отрезка, а значение nil. Это и вызвало ошибку.

Чтобы программа не реагировала на промахи пользователя, нужно добавить в нашу программу еще несколько строк.

Функция if выполняет условную операцию типа if-then-else (если-то-иначе)

(if <условие> <выражение1> [<выражение2>])

Если <условие> верно выполняется <выражение1>

Если <условие> не верно выполняется <выражение2>

Давайте напишем <условие> для нашего случая.

Следующее условие (= name_obj nil) будет читаться так: если name_obj рано nil.

Но нам нужно выполнять наши выражения наоборот, когда name_obj не рано nil. А это соответствует следующему условию:

(not (= name_obj nil))

Если <условие> верно и нам нужно выполнить не одно <выражение>, а несколько, то нужно использовать функцию progn.

Функция prong объединяет несколько выражений в одно. Добавим ее к функции if и в общем случаи наш кусок кода будет выглядеть так:

(if (not (= name_obj nil))

    (progn

      <наши выражения>

    ) ;end progn

  ) ; end if

Читается: Если name_obj не равно nil выполнить <наши выражения>

Добавим эти строки в нашу программу и она примет следующий вид. См. Рис. 13

Пример AutoLISP

Рис. 13.   Функции if и progn

Выделяем весь текст и нажимаем кнопку «Загрузить выделенный фрагмент».

Протестируете программу. Теперь даже, если вы щелкаете на пустом месте, программа AutoLISP не прекращает свою работу, а продолжает выдавать запрос: «Выберите отрезок:»

Но пользователь может случайно выбрать другой примитив (не отрезок), например окружность. По всей видимости, программа снова выдаст ошибку. Чтобы этого не произошло, следующим выражением прочитаем и запомним тип выбранного примитива:

(setq tip_obj (cdr (assoc 0 list_obj)))

0 – это  DXF-код типа.

Затем, поставим условия, что выполнять выражения нужно, если выбранный объект имеет тип отрезок («LINE»).

Добавляем выше сказанное в программу, и она приобретает следующий вид. См. Рис. 14.

Пример AutoLISP

Рис. 14.  Проверка типа «LINE«.

Добавленные строки помечены синими полосками.  Теперь наша программа не будет выдавать ошибку, если пользователь случайно выделит другой примитив.

Для того, чтобы пользователь видел какие отрезки он уже выбрал, а какие нет, давайте выделим выбранные отрезки.

Для этого сначала, создадим пустой набор и сохраним его в переменной line_set:

(setq line_set (ssadd))

Функция ssadd добавляет примитив в набор.

(ssadd [<примитив> [<набор>]]) , где

<примитив> — имя примитива.

<набор> — имя набора.

Для того, чтобы выделить примитивы, входящие в набор используется функция sssetfirst:

(sssetfirst <набор1> [<набор2>])

Функция sssetfirst включает ручки у примитивов, входящих в <набор1>.

А у примитивов входящих в <набор2> включает ручки и подсвечивает их пунктиром.

Добавим в нашу программу, следующую строчку:

(sssetfirst nil (ssadd name_obj line_set))

Она добавляет примитив name_obj в набор line_set, а затем включает ручки и подсвечивает пунктиром примитивы, входящие в этот набор.

Теперь наша программа будет иметь следующий вид. См. Рис.15.

Пример AutoLISP

Рис. 15.  Функции ssadd и sssetfirst.

Выделяем весь текст и нажимаем кнопку «Загрузить выделенный фрагмент».

На запрос: «Выберите отрезок:» укажите один из ранее нарисованных отрезков.

Отрезок будет выделен. См. Рис. 16.

Пример AutoLISP

Рис. 16.   Выделенный отрезок.

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

Теперь давайте сделаем результат, который выводится у нас в командной строке более информативным.

Для этого, сначала преобразуем вещественное число, которое хранится в переменной sum_dl в строку:

(rtos sum_dl).

Затем при помощи функции сцепления строк strcat, прицепим пояснительную надпись.

Строка печати примет следующий вид:

(princ (strcat «nОбщая длина: — « (rtos sum_dl)))

Кроме этого давайте сосчитаем количество выбранных отрезков. Для этого вначале перед циклом введем переменную n и присвоим ей целочисленное значения 0.

Далее внутри цикла помещаем строку

(setq n (+ n 1))

 которая будет считать количество выбранных отрезков.

Затем, преобразуем целое число в строку (itoa n), добавим пояснительную надпись и вставим в строку печати. См. Рис.17.

Пример AutoLISP

Рис. 17.    Добавление количества выбранных отрезков.

Поле чего она примет следующий вид:

(princ (strcat «nОтрезков — « (itoa n) « nОбщая длина: — « (rtos sum_dl))).

Теперь наша программа выглядит так. См. Рис.18.

Пример AutoLISP

Рис. 18. Функции rtos, itoa и strcat. Изменения строки печати.

Выделяем весь текст и нажимаем кнопку «Загрузить выделенный фрагмент».

На запрос: «Выберите отрезок:» укажите сначала один, а затем и второй отрезок.

В командной строке будет написано количество выбранных отрезков и их общая длина. См. Рис. 19.

Пример AutoLISP

Рис. 19.  Количество выбранных отрезков и их общая длина.

Чтобы прервать выполнения программы нажмите <Esc>.

В заключении преобразуем нашу программу в пользовательскую функцию.

Добавим строку, в которой придумаем имя функции и перечислим все временные переменные:

(defun c:SumDl (/ line_set sum_Dl n name_obj list_obj tip_obj p1 p2 dl_otr)

      <наша программа>

) ; end_defun

Окончательный вариант программы см. Рис. 20.

Пример AutoLISP

Рис. 20.  Программа сумма длин отрезков.

Код программы:

(defun c:SumDl (/ line_set sum_Dl n name_obj list_obj tip_obj p1 p2 dl_otr)
   (setq line_set (ssadd)) ; создаем пустой список
   (setq sum_dl 0.0)         ; Сумма длин = 0
   (setq n 0)                      ; Кол-во выбранных отрезков
   (while T (setq name_obj (car (entsel "Выберите отрезок: ")))
       (if (not (= name_obj nil))
          (progn
             (setq list_obj (entget name_obj))
             (setq tip_obj (cdr (assoc 0 list_obj)))
             (if (= tip_obj "LINE")
                (progn
                    (sssetfirst nil (ssadd name_obj line_set))
                    (setq p1 (cdr (assoc 10 list_obj)))
                    (setq p2 (cdr (assoc 11 list_obj)))
                    (setq dl_otr (distance p1 p2))
                    (setq sum_dl (+ sum_dl dl_otr))
                    (setq n (+ n 1))
                 );end progn
              ); end if
           );end progn
        ); end if
        (princ (strcat "nОтрезков - " (itoa n) "nОбщая длина: - " (rtos sum_dl)))
    ); end while
); end_defun

 Скачать программу Sum_dl.lsp Скачать программу Sum_dl.lsp (Размер файла: 464 bytes)

Теперь, чтобы запустить программу, используем кнопку «Загрузить активное окно редактора». Переходим в AutoCAD, в командной строке набираем SumDl и нажимаем <Enter>.

После того, как программа написана и протестирована нужно:

  • Если это ещё не сделано, добавить все локальные переменные в список временных переменных функции defun.
  • Сохранить свою LISP-программу.
  • Закрыть редактор Visual LISP и AutoCAD, чтобы очистить все значения переменных.
  • Загрузить AutoCAD снова.
  • Также можно добавить нашу программу в список автоматической загрузки и создать для нее кнопку запуска. Как это сделать рассмотрено в уроке: Простой запуск LISP программ.

Надеюсь, что этот пример AutoLISP программы у Вас получился, и Вы найдете ему применение.

В следующем уроке мы рассмотрим возможные вариации этой программы: Примеры LISP программ: Сумма длин отрезков.

Пишите в комментариях:

Трудно ли было выполнить этот урок?

Где у вас возникли трудности?

Была ли для Вас полезной информация, данная в этом уроке?

На какие вопросы программирования, Вы хотели бы, увидит ответы в следующих уроках?

Я с удовольствием отвечу на ваши комментарии.

Если вы хотите получать новости с моего сайта. Оформляйте подписку.

До новых встреч.

 «Автор: Михаил Орлов»

Google

Также на эту тему Вы можете почитать:

  • Печать

Страницы: [1] 2  Все   Вниз

Тема: Выбор содержимого ячейки таблицы  (Прочитано 3561 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Столкнулся с такой проблемой. При запуске короткого лиспа в AC-2007 всё работает нормально, содержимое указываемой ячейки получается. При запуске этого же кода в AC-2021 ячейка не читается, выдается сообщение:  ** Error: неверный тип аргумента: lentityp nil **
В чем проблема, не пойму. Что интересно, если в AC-2021 (2020) указать не середину ячейки, а сторону ячейки, иногда значение получается.
Прикладываю два чертежа в разных версиях автокада.


Записан


В чем проблема, не пойму.

Тут не нужно ничего понимать — тут нужно просто отладить программу и найти откуда появляется ошибка.


Записан


Вообщем придумал вот это:

  1. (defun c:11 (/)

  2. (vl-load-com)

  3. (setq p_1 (getpoint «nКлик по числу в таблице >»))

  4. (setq p_2 (list ( (car p_1) 50) ( (cadr p_1) 20)))

  5. (setq ent (ssname (ssget «_C» p_1 p_2 ‘((0 . «ACAD_TABLE»))) 0))

  6. (setq vla_table (vlax-ename->vla-object ent))

  7. (vla-HitTest vla_table

  8. (vlax-3d-point p_1)

  9. (vlax-3d-point (trans (getvar ‘ViewDir) 1 0))

  10.               ‘row

  11.               ‘col

  12. )

  13. (setq val (vla-gettext vla_table row col))

  14. (alert (vl-prin1-to-string val))

  15. )

Вроде работает.

« Последнее редактирование: 14-04-2022, 18:33:20 от Александр Ривилис »


Записан


1958,
Не забывай про правило форматирования кода на форуме!
Что касается твоего кода, то он конечно же не универсальный. И кроме того нет проверки на то, что вообще что-то выбрано.


Записан


1958,
Проверил код из первого сообщения в AutoCAD 2021. Все нормально работает, если выбираешь текст внутри ячейки.


Записан


Проверил код из первого сообщения в AutoCAD 2021. Все нормально работает, если выбираешь текст внутри ячейки.

Ну, не знаю. У меня ни в какую. Кликаю по по тексту и сразу

** Error: неверный тип аргумента: lentityp nil **

Не забывай про правило форматирования кода на форуме!

Прощу прощения в очередной раз!  :(


Записан


1958,

Ну, не знаю. У меня ни в какую. Кликаю по по тексту и сразу

На всякий случай показываю:


Записан


Ну не получается у меня выборка значения через entsel, не знаю почему.


Записан



Записан


1958,
Правило добавления видео к сообщениям на форуме у меня в подписи.


Записан


Похоже выбор не происходит если используется TTF-шрифт и используется визуальный стиль 2D-Wireframe. В других визуальных стилях тексты в таблице нормально выбираются.


Записан


Точно! Сейчас проверил. Если выбрать другой стиль, всё работает. Если заменить текстовый стиль на любой, не использующий TTF-шрифт, то работает и при визуальном стиле 2D-каркас.


Записан


Может, попробовать vla-getcellvalue? А не vla-gettext?
Сейчас проверить не могу :(


Записан


Может, попробовать vla-getcellvalue? А не vla-gettext?
Сейчас проверить не могу :(

Не срабатывает (entsel) — ничего не выбирается.


Записан


Скорее всего, я что-то не понимаю и не учитываю. Но у меня в ACAD2020 корректно сработал следующий вариант (естественно, без проверок):

  1. (defun t1 (/ table point row col)

  2. (setq table (vlax-ename->vla-object (car (entsel «nSelect table : «)))

  3.         point (getpoint «nPick point in cell: «)

  4. ) ;_ end of setq

  5. (vla-hittest table (vlax-3d-point point) (vlax-3d-point (trans (getvar ‘viewdir) 1 0)) ‘row ‘col)

  6. (list (cons «cellvalue» (vla-getcellvalue table row col))

  7. (cons «text» (vla-gettext table row col))

  8. ) ;_ end of list

  9. ) ;_ end of defun

Одно «но»: в ячейке у меня находятся именно обычные тексты, не содержащие поля. Ну и вариант вхождения блока в ячейку тоже не предусмотрен.


Записан


  • Печать

Страницы: [1] 2  Все   Вверх

Страницы 1 2 Далее

Чтобы отправить ответ, вы должны войти или зарегистрироваться

RSS

Сообщения с 1 по 25 из 35

#1 9 марта 2006г. 09:19:29

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Тема: LISP. Разрыв (обрыв, …) строчки в указанной точке

;|====================================================
 Разрыв (обрыв, ...) строчки в указанной точке
 Программа Дениса Флюстикова "Str_Den"
 Макрос для кнопки: ^C^C^P(load "Str_Den");Str_Den
 Замечания и предложения по адресу fd-@mail.ru
====================================================|;
(defun c:Str_Den (/ n a a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 OSMODE)
(setq a nil)
(while (/= (cdr (assoc 0 a)) "TEXT")
(setq a5 (car (entsel "nВыберите текст:"))
      a (entget a5)))
(setq OSMODE (getvar "OSMODE")
      n '("l" "c" "r" "a" "m" "f")
      a7 (nth (cdr (assoc 72 a)) n )
      n '("" "b" "m" "t")
      n (nth (cdr (assoc 73 a)) n )
      a7 (strcat "_" n a7)
      a9 (cdr (assoc 50 a))
      a2 (cdr (assoc 10 a))
      a2 (trans a2 0 1))
(setvar "CMDECHO" 0)
(command "_.undo" "_g")
(if (> (rem OSMODE 128) 63)
(setvar "OSMODE" (- OSMODE 64)))
(initget 6 "Р У Н В П")
(if (not (vl-catch-all-error-p
(setq a3 (vl-catch-all-apply 'getpoint
(list "nточка Разрыва или вторую часть[Удалить/на Новую строку/Вставить в текст/Перенести]<В текст>:")))))
(progn
(setq a10 a3)
(if (null a3)(setq a10 "В"))
(if (= (type a3) 'LIST)
(setq a10 "Р")
(setq a3 (vl-catch-all-apply 'getpoint
(list "nУкажите точку разделения:"))))
(setvar "OSMODE" OSMODE)
(if (= (type a3) 'LIST)(progn
(setq a1 (cos (- (angle a2 a3) a9))
      a3 (* a1 (distance a2 a3))
      a4 (caadr (Textbox a))
      a6 a4
      a1 (cdr (assoc 1 a))
      n (strlen a1))
(if (and (< a3 a4)(> a3 0))(progn
(command "_.justifytext" a5 "" "_l"
     "_.copy" a5 "" a2 a2)
(setq a (entget a5))
(while (and (> a6 a3)(> n 0))
(setq a8 (substr a1 1 n)
      a8 (vl-string-right-trim " " a8)
      a8 (subst (cons 1 a8)(assoc 1 a) a)
      a6 (caadr (Textbox a8))
      n (1- n))
)
(entmod a8)
(setq a8 (substr a1 (+ 2 n)(strlen a1))
      a6 (subst (cons 1 a8)(assoc 1 a) a)
      a6 (- a4 (caadr (Textbox a6)))
      a1 (entlast)
      a (entget a1))
(if (= a10 "Н")
(setq a9 (- a9 (/ pi 2))
      a6 (cdr (assoc 40 a))
      a6 (* 5 (/ a6 3))))
(setq a2 (polar a2 a9 a6)
      a2 (trans a2 1 0)
      a (subst (cons 10 a2)(assoc 10 a) a))
(entmod (subst (cons 1 a8)(assoc 1 a) a))
(command "_.justifytext" a5 a1 "" a7)
(if (= a10 "П")
(vl-cmdf "_.move" a1 "" a2 pause)
(if (and (/= a10 "Р")(/= a10 "Н"))(progn
(command "_.erase" a1 "")
(if (= a10 "В")
(while a2
(if (vl-catch-all-error-p
(setq a5 (vl-catch-all-apply 'entsel
(list "nВыберите текст:"))))
(setq a2 nil)
(if (= (type a5) 'LIST)(progn
(setq a (entget (car a5)))
(if (wcmatch (cdr (assoc 0 a)) "*TEXT")(progn
(setq a2 nil
      a4 (cdr (assoc 1 a))
      a6 (vl-string-left-trim " " a4)
      a7 (- (strlen a4) (strlen a6))
      a8 (vl-string-right-trim " " a8)
      a6 (strcat a8 " " a6))
(repeat a7
(setq a6 (strcat " " a6)))
(entmod (subst (cons 1 a6)(assoc 1 a) a))
)))))))))))
(princ "nТочка за границами текста")
)))))
(setvar "OSMODE" OSMODE)
(command "_.undo" "_e")
(setvar "CMDECHO" 1)
(princ)
)

#2 Ответ от skkkk 19 мая 2008г. 23:09:39

  • skkkk
  • Участник
  • На форуме с 22 апреля 2008г.
  • Сообщений: 31
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

У меня пишет

; ошибка: неверный тип аргумента: lentityp nil

#3 Ответ от Денис Флюстиков 20 мая 2008г. 21:31:55

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

Еще раз проверил работу программы, скопировав код в LISP-формат, вроде все OK. Уточни, когда появляется сообщение, до, после или во время диалога. Проблема на разных машинах, в файлах с разными настройками?

#4 Ответ от Victor 21 мая 2008г. 08:24:43

  • Victor
  • Восстановленный участник
  • На форуме с 26 марта 2007г.
  • Сообщений: 270
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

У меня на англицком автокаде работает. Везде, где русские буквы,
стоят вопросительные знаки, но основную функцию выполняет — делит текст.

#5 Ответ от Денис Флюстиков 24 мая 2008г. 14:12:28

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> skkkk

> Victor
Погонял программу под разными версиями AutoCAD (рус., англ.), ошибок не обнаружил.
Программа работает только с однострочным текстом, и если выбрать многострочный и
нажать пробел, то появляется подобное соощение:
«    ; ошибка: неверный тип аргумента: lentityp nil    »
Этот моментик исправлю

#6 Ответ от Денис Флюстиков 24 мая 2008г. 14:14:23

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

;|====================================================
 Разрыв (обрыв, ...) строчки в указанной точке
 Программа Дениса Флюстикова "Str_Den" от 24.05.08:
 учтены коды подчеркивания и надчеркивания текста
 Макрос для кнопки: ^C^C^P(load "Str_Den");Str_Den
 Замечания и предложения по адресу fd-@mail.ru
====================================================|;
(defun c:Str_Den (/ n a a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 OSMODE)
(setq a nil)
(while (/= (cdr (assoc 0 a)) "TEXT")
(if (setq a5 (car (entsel "nВыберите однострочный текст:")))
(setq a (entget a5)))
)
(setq OSMODE (getvar "OSMODE")
      n '("l" "c" "r" "a" "m" "f")
      a7 (nth (cdr (assoc 72 a)) n )
      n '("" "b" "m" "t")
      n (nth (cdr (assoc 73 a)) n )
      a7 (strcat "_" n a7)
      a9 (cdr (assoc 50 a))
      a2 (cdr (assoc 10 a))
      a2 (trans a2 0 1))
(setvar "CMDECHO" 0)
(command "_.undo" "_g")
(if (> (rem OSMODE 128) 63)
(setvar "OSMODE" (- OSMODE 64)))
(initget 6 "Р У Н В П")
(if (not (vl-catch-all-error-p
(setq a3 (vl-catch-all-apply 'getpoint
(list "nточка Разрыва или вторую часть[Удалить/на Новую строку/Вставить в текст/Перенести]<В текст>:")))))
(progn
(setq a10 a3)
(if (null a3)(setq a10 "В"))
(if (= (type a3) 'LIST)
(setq a10 "Р")
(setq a3 (vl-catch-all-apply 'getpoint
(list "nУкажите точку разделения:"))))
(setvar "OSMODE" OSMODE)
(if (= (type a3) 'LIST)(progn
(setq a1 (cos (- (angle a2 a3) a9))
      a3 (* a1 (distance a2 a3))
      a4 (caadr (Textbox a))
      a6 a4
      a1 (cdr (assoc 1 a))
      n (strlen a1))
(if (and (< a3 a4)(> a3 0))(progn
(vl-cmdf "_.justifytext" a5 "" "_l")
(vl-cmdf "_.copy" a5 "" a2 a2)
(setq a (entget a5)
      a11 a1)
(while (and (> a6 a3)(> n 0))
(setq a11 (substr a11 1 n)
      a11 (vl-string-right-trim " " a11)
      a8 (subst (cons 1 a11)(assoc 1 a) a)
      a6 (caadr (Textbox a8)))
(if (wcmatch a11 "*%%?")
(setq n (- n 3))
(if (wcmatch a11 "*U+????")
(setq n (- n 7))
(if (wcmatch a11 "*%%###")
(setq n (- n 5))
(setq n (1- n)))))
)
(entmod a8)
(setq a6 "%%U"
      a8 1
      a11 (strcase a11))
(while (wcmatch a11 (strcat "*" a6 "*"))
(setq a6 (strcat a6 "*%%U")
      a8 (1+ a8)))
(if (= 0 (rem a8 2))
(setq a3 "%%U")
(setq a3 ""))
(setq a6 "%%O"
      a8 1)
(while (wcmatch a11 (strcat "*" a6 "*"))
(setq a6 (strcat a6 "*%%O")
      a8 (1+ a8)))
(if (= 0 (rem a8 2))
(setq a3 (strcat a3 "%%O")))
(setq a8 (substr a1 (1+ (strlen a11))(strlen a1))
      a8 (strcat a3 a8)
      a6 (subst (cons 1 a8)(assoc 1 a) a)
      a6 (- a4 (caadr (Textbox a6)))
      a1 (entlast)
      a (entget a1))
(if (= a10 "Н")
(setq a9 (- a9 (/ pi 2))
      a6 (cdr (assoc 40 a))
      a6 (* 5 (/ a6 3))))
(setq a2 (polar a2 a9 a6)
      a2 (trans a2 1 0)
      a (subst (cons 10 a2)(assoc 10 a) a)
      a2 (trans a2 0 1))
(entmod (subst (cons 1 a8)(assoc 1 a) a))
(vl-cmdf "_.justifytext" a5 a1 "" a7)
(if (= a10 "П")
(vl-cmdf "_.move" a1 "" a2 pause)
(if (and (/= a10 "Р")(/= a10 "Н"))(progn
(command "_.erase" a1 "")
(if (= a10 "В")
(while a2
(if (vl-catch-all-error-p
(setq a5 (vl-catch-all-apply 'entsel
(list "nВыберите текст:"))))
(setq a2 nil)
(if (= (type a5) 'LIST)(progn
(setq a (entget (car a5)))
(if (wcmatch (cdr (assoc 0 a)) "*TEXT")(progn
(setq a2 nil
      a4 (cdr (assoc 1 a))
      a6 (vl-string-left-trim " " a4)
      a7 (- (strlen a4) (strlen a6))
      a8 (vl-string-right-trim " " a8)
      a6 (strcat a8 " " a6))
(repeat a7
(setq a6 (strcat " " a6)))
(entmod (subst (cons 1 a6)(assoc 1 a) a))
)))))))))))
(princ "nТочка за границами текста")
)))))
(setvar "OSMODE" OSMODE)
(command "_.undo" "_e")
(setvar "CMDECHO" 1)
(princ)
)

#7 Ответ от skkkk 3 июня 2008г. 04:04:35

  • skkkk
  • Участник
  • На форуме с 22 апреля 2008г.
  • Сообщений: 31
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

Отлично работает….Дай Бог Вам здоровья:)

#8 Ответ от skkkk 3 июня 2008г. 04:10:17

  • skkkk
  • Участник
  • На форуме с 22 апреля 2008г.
  • Сообщений: 31
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

А с многострочным также нельзя??? И чтоб еще и объединить потом?? В идеале вижу это так: есть мтекст…разрываем его в нужных местах….редактируем, причем, каждую часть разными лиспами, затем обратно соединяем в том виде, как он есть, хотя этот пункт и необязателен, можно сгруппировать на худой конец. Но в любом случае прога — супер

#9 Ответ от Малявка 3 июня 2008г. 08:27:19

  • Малявка
  • Активный участник
  • На форуме с 18 января 2007г.
  • Сообщений: 274
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

Спасибо за программу! Часто приходится переносить часть текста на другую строчку. Раньше делала тупым копированием и дальнейшим удалением лишних частей в полученных строчках.
Теперь горя не знаю.

#10 Ответ от Малявка 3 июня 2008г. 11:24:52

  • Малявка
  • Активный участник
  • На форуме с 18 января 2007г.
  • Сообщений: 274
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

А макрос работает только в модели! В листе не работает!!!
(хнык)

#11 Ответ от Денис Флюстиков 3 июня 2008г. 17:24:32

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

Для указания места разрыва текста по точке на нижней границе, в коде вместо строчки:
      a6 (caadr (Textbox a8)))
вставте строчки:
      a6 (subst ‘(51 . 0)(assoc 51 a8) a8)
      a6 (caadr (Textbox a6)))
более удобно при работе с наклонным текстом.

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

> Малявка
Обычно пользуюсь программой в модели, да и в работе в листе проблем не замечал. Малявка, забрось мне в ящик этот DWG-файлик, попробую разобраться.

#12 Ответ от Малявка 3 июня 2008г. 18:49:35

  • Малявка
  • Активный участник
  • На форуме с 18 января 2007г.
  • Сообщений: 274
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Денис Флюстиков
Не пойму, что случилось! Всё работает и в листе тоже! Может, перезагрузка помогла, какой-нибудь глюк в моем компе снесла? Не знаю.
Короче, спасибо. Чмоки тя в разные приятные места.

#13 Ответ от Денис Флюстиков 3 июня 2008г. 19:09:05

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Малявка
Это лишнее, мне достаточно было узнать, что с помощью программы сделал человека не знающего горя 🙂
(> Малявка (2008-06-03 08:27:19))

#14 Ответ от Малявка 3 июня 2008г. 20:03:16

  • Малявка
  • Активный участник
  • На форуме с 18 января 2007г.
  • Сообщений: 274
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Денис Флюстиков
Сделал человека? И когда ж успел? Я че-й-то не заметила… ))
(типа прикол, не хотела обидеть, просто фраза получилась пошленько-смешная. Лучше бы «сделал человека счастливым». Или так: «сделал человека НЕ ЗНАЮЩИМ горя»).

#15 Ответ от Денис Флюстиков 3 июня 2008г. 20:06:39

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

:S

#16 Ответ от Kosarev 4 июня 2008г. 09:27:09

  • Kosarev
  • Активный участник
  • На форуме с 14 октября 2004г.
  • Сообщений: 162
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

Нормальная штука.
Ненавязчиво предлагаю подсветить изначально выбранную строку для наглядности, для этого в начало вместо

(while (/= (cdr (assoc 0 a)) "TEXT")
(if (setq a5 (car (entsel "nВыберите однострочный текст:")))
(setq a (entget a5)))
)

вставим

(while (/= (cdr (assoc 0 a)) "TEXT")
  (if (setq a5 (car (entsel "nВыберите однострочный текст:")))
    (progn (redraw a5 3)(setq a (entget a5)))
  )
)

а в конце добавим

перед строкой (command «_.undo» «_e»)
Автор не против?

#17 Ответ от getr 4 июня 2008г. 10:57:30

  • getr
  • Восстановленный участник
  • На форуме с 20 декабря 2005г.
  • Сообщений: 22
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Денису
Флюстикову
Хотелось бы чтобы строка разделялась именно в указанной точке,а не как сейчас на пробел левее.
А то, напр. при опции на Новую строку,нижняя строка начинается с пробела и оказывается смещенной вправо на оный.

#18 Ответ от Малявка 4 июня 2008г. 12:08:38

  • Малявка
  • Активный участник
  • На форуме с 18 января 2007г.
  • Сообщений: 274
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Kosarev
Спасибо, маленькая фенечка, а мне понравилось.

#19 Ответ от Денис Флюстиков 4 июня 2008г. 13:42:24

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Kosarev
Спасибо, так лучше

> getr
Попробуй эту версию, то?

;|====================================================
 Разрыв (обрыв, ...) строчки в указанной точке
 Программа Дениса Флюстикова "Str_Den" от 04.06.08
 Макрос для кнопки:
 ^C^C^P(load "Str_Den");Str_Den
 Замечания и предложения по адресу fd-@mail.ru
 Большое спасибо Kosarev за помощь в доработке программы
====================================================|;
(defun c:Str_Den (/ n a a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 OSMODE)
(setq a nil)
(while (/= (cdr (assoc 0 a)) "TEXT")
(if (setq a5 (car (entsel "nВыберите однострочный текст:")))
(progn (redraw a5 3)(setq a (entget a5)))
)
)
(setq OSMODE (getvar "OSMODE")
      n '("l" "c" "r" "a" "m" "f")
      a7 (nth (cdr (assoc 72 a)) n )
      n '("" "b" "m" "t")
      n (nth (cdr (assoc 73 a)) n )
      a7 (strcat "_" n a7)
      a9 (cdr (assoc 50 a))
      a2 (cdr (assoc 10 a))
      a2 (trans a2 0 1))
(setvar "CMDECHO" 0)
(command "_.undo" "_g")
(if (> (rem OSMODE 128) 63)
(setvar "OSMODE" (- OSMODE 64)))
(initget 6 "Р У Н В П")
(if (not (vl-catch-all-error-p
(setq a3 (vl-catch-all-apply 'getpoint
(list "nточка Разрыва или вторую часть[Удалить/на Новую строку/Вставить в текст/Перенести]<В текст>:")))))
(progn
(setq a10 a3)
(if (null a3)(setq a10 "В"))
(if (= (type a3) 'LIST)
(setq a10 "Р")
(setq a3 (vl-catch-all-apply 'getpoint
(list "nУкажите точку разделения:"))))
(setvar "OSMODE" OSMODE)
(if (= (type a3) 'LIST)(progn
(setq a1 (cos (- (angle a2 a3) a9))
      a3 (* a1 (distance a2 a3))
      a4 (caadr (Textbox a))
      a6 a4
      a1 (cdr (assoc 1 a))
      n (strlen a1))
(if (and (< a3 a4)(> a3 0))(progn
(vl-cmdf "_.justifytext" a5 "" "_l")
(vl-cmdf "_.copy" a5 "" a2 a2)
(setq a (entget a5)
      a11 a1)
(while (and (> a6 a3)(> n 0))
(setq a11 (substr a11 1 n)
      a11 (vl-string-right-trim " " a11)
      a8 (subst (cons 1 a11)(assoc 1 a) a)
      a6 (subst '(51 . 0)(assoc 51 a8) a8)
      a6 (caadr (Textbox a6)))
(if (wcmatch a11 "*%%?")
(setq n (- n 3))
(if (wcmatch a11 "*U+????")
(setq n (- n 7))
(if (wcmatch a11 "*%%###")
(setq n (- n 5))
(setq n (1- n)))))
)
(entmod a8)
(setq a6 "%%U"
      a8 1
      a11 (strcase a11))
(while (wcmatch a11 (strcat "*" a6 "*"))
(setq a6 (strcat a6 "*%%U")
      a8 (1+ a8)))
(if (= 0 (rem a8 2))
(setq a3 "%%U")
(setq a3 ""))
(setq a6 "%%O"
      a8 1)
(while (wcmatch a11 (strcat "*" a6 "*"))
(setq a6 (strcat a6 "*%%O")
      a8 (1+ a8)))
(if (= 0 (rem a8 2))
(setq a3 (strcat a3 "%%O")))
(setq a8 (substr a1 (1+ (strlen a11))(strlen a1))
      a8 (vl-string-left-trim " " a8)
      a8 (strcat a3 a8)
      a6 (subst (cons 1 a8)(assoc 1 a) a)
      a6 (- a4 (caadr (Textbox a6)))
      a1 (entlast)
      a (entget a1))
(if (= a10 "Н")
(setq a9 (- a9 (/ pi 2))
      a6 (cdr (assoc 40 a))
      a6 (* 5 (/ a6 3))))
(setq a2 (polar a2 a9 a6)
      a2 (trans a2 1 0)
      a (subst (cons 10 a2)(assoc 10 a) a)
      a2 (trans a2 0 1))
(entmod (subst (cons 1 a8)(assoc 1 a) a))
(vl-cmdf "_.justifytext" a5 a1 "" a7)
(if (= a10 "П")
(vl-cmdf "_.move" a1 "" a2 pause)
(if (and (/= a10 "Р")(/= a10 "Н"))(progn
(command "_.erase" a1 "")
(if (= a10 "В")
(while a2
(if (vl-catch-all-error-p
(setq a5 (vl-catch-all-apply 'entsel
(list "nВыберите текст:"))))
(setq a2 nil)
(if (= (type a5) 'LIST)(progn
(setq a (entget (car a5)))
(if (wcmatch (cdr (assoc 0 a)) "*TEXT")(progn
(setq a2 nil
      a4 (cdr (assoc 1 a))
      a6 (vl-string-left-trim " " a4)
      a7 (- (strlen a4) (strlen a6))
      a8 (vl-string-right-trim " " a8))
(if (and (wcmatch a8 "*`-")(not (wcmatch a8 "*`-`-")))
(setq a8 (vl-string-right-trim "-" a8)
      a6 (strcat a8 a6))
(setq a6 (strcat a8 " " a6))
)
(repeat a7
(setq a6 (strcat " " a6)))
(entmod (subst (cons 1 a6)(assoc 1 a) a))
)))))))))))
(princ "nТочка за границами текста")
)))))
(setvar "OSMODE" OSMODE)
(command "_.regenall"
     "_.undo" "_e")
(setvar "CMDECHO" 1)
(princ)
)

#20 Ответ от Малявка 4 июня 2008г. 14:08:26

  • Малявка
  • Активный участник
  • На форуме с 18 января 2007г.
  • Сообщений: 274
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Денис Флюстиков
Класс! Я в восхищении!
Я тоже так хочу!

#21 Ответ от getr 4 июня 2008г. 15:46:47

  • getr
  • Восстановленный участник
  • На форуме с 20 декабря 2005г.
  • Сообщений: 22
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

СПАСИБО!Самое то.

#22 Ответ от Tarmo 5 июня 2008г. 12:53:56

  • Tarmo
  • Восстановленный участник
  • На форуме с 28 января 2005г.
  • Сообщений: 306
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

Спасибо, Денис!
Мечтала об этом давно… руки так и не дошли! А тут Ваш подарок! : )

#23 Ответ от Денис Флюстиков 5 июня 2008г. 15:25:03

  • Денис Флюстиков
  • Активный участник
  • На форуме с 12 октября 2005г.
  • Сообщений: 374
  • Спасибо: 10

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

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

#24 Ответ от Малявка 5 июня 2008г. 15:55:46

  • Малявка
  • Активный участник
  • На форуме с 18 января 2007г.
  • Сообщений: 274
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

> Денис Флюстиков
Наверное, всему свое время. Главное, чтобы вовремя.

#25 Ответ от Kosarev 6 июня 2008г. 10:03:16

  • Kosarev
  • Активный участник
  • На форуме с 14 октября 2004г.
  • Сообщений: 162
  • Спасибо: 0

Re: LISP. Разрыв (обрыв, …) строчки в указанной точке

Ну и специальный бонус для любителей «фишек»!
Вставьте нижеследующий блок в конце, перед строкой (command «_.regenall» «_.undo» «_e»)

(if (= a10 "Р")(repeat 6
  (redraw a1 2)(command "_.delay" 50)(redraw a1 1)(command "_.delay" 50)
))

Теперь при разрыве строки некоторое время будет происходить волшебство с «оторванным» хвостом…

Страницы 1 2 Далее

Чтобы отправить ответ, вы должны войти или зарегистрироваться

I have the same problem with my routine, it produces the same error message: ; error: bad argument type: lentityp nil. It skips the ENTSEL in each subroutine of the IF.

Help!!

(defun c:hln(/ LAS OS R1 R2 XNv XFv r2v Y1v X1v X2v P1v P2v xnh xfh r2h y1h x1h x2h p1h p2h)

(SETVAR «CMDECHO» 0)

(SETQ LAS(GETVAR «CLAYER»))

(SETQ OS (GETVAR «OSMODE»))

(initget «V H»)

(setq direc(getkword «Type: Vert/Horiz»))

;need to change from horizontal to vertical

;swap involves components of chosen line

;if statement should control use of those components

;simple way, if V then change components to XNV versus XNH, etc.

(command «layer» «s» «hid» «»)

(setvar «osmode» 512)

(if(= «V» direc)

(

(SETQ R1(ENTSEL «Pick line: «))

(SETQ XNv(GETPOINT «Pick BOTTOM side of plate: «))(terpri);point selected on top line

(SETQ XFv(GETPOINT «Pick TOP hside of plate: «))(terpri);point selected on bottom line

(setq R2v(entget(car R1)))

(setq Y1v(CADR(ASSOC 10 R2v))) ;X COORDINATE

(setq X1v(CADR XNv)) ;BOTTOM SIDE Y COORDINATE

(setq X2v(CADR XFv)) ;TOP SIDE Y COORDINATE

(SETQ P1v(LIST Y1v X1v))

(SETQ P2v(LIST Y1v X2v))

(command «line» p1v p2v /c/c)))

(if(= «H» direc)

(

(SETQ R2(ENTSEL «Pick line: «))

(SETQ XNh(GETPOINT «Pick RIGHT side of plate: «))(terpri)

(SETQ XFh(GETPOINT «Pick LEFT side of plate: «))(terpri)

(setq R2h(entget(car R2)))

(setq Y1h(CADDR(ASSOC 11 R2h))) ;Y COORDINATE

(setq X1h(CADR XNh)) ;NEAR SIDE X COORDINATE

(setq X2h(CAR XFh)) ;FAR SIDE X COORDINATE

(SETQ P1h(LIST X2H Y1h))

(SETQ P2h(LIST X1h Y1h))

(command «line» p1h p2h /c/c)))

(COMMAND «LAYER» «S» LAS «»)

(SETVAR «OSMODE» 183)

(PRINC)

)

What I’m trying to do is draw a hidden line in an adjacent view by just selecting the line in the other «visible» view of the line. I want to specify if it will be vertical or horizontal (I think, might not be necessary) to draw the line. But I can’t get it to select either line.

I had to change the text styles and width attributes of several blocks in Autocad. There was 10-30 blocks on each dwg and nearly 100 dgs and I could not be bothered to manually convert each block to the new standard.

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-width-change/td-p/1525357
this link has a script to change all the blocks (title blocks and several electrical symbols) width to 1 and as a first pass it does what I want (failing due to bad ; error: bad argument type: lentityp nil Command:which after changing it to manually select and just selecting the blocks I want fixes it). However I also need to change the test style from whatever it is to «Standard»
https://www.afralisp.net/reference/dxf-group-codes.php
after checking this link I found «Text style name» is code dxf 7
so I changed the script to the following.

(defun C:StandardFromDWGTEXT (/ ss sslen cnt blck ent entinfo)
  (setq ss (ssget))
  (setq cnt 0)
  (setq sslen (sslength ss))
  (while (< cnt sslen)
    (setq blck (ssname ss cnt))
    (setq ent (entnext blck))
    (setq entinfo (entget ent))
    (while
      (and ent (= (cdr (assoc 0 entinfo)) "ATTRIB"))
       (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
;;;    (entupd ent)
;;;    (setq ent (entnext ent))
;;;    (setq entinfo (entget ent))    
       (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
       (entupd ent)
       (setq ent (entnext ent))
       (setq entinfo (entget ent))      
    )
    (setq cnt (1+ cnt))
  )
  (princ)
)

Now it only works with the lines I commented out (stops working with them but that also means it only changes text style not width too) and only changes the text style half the time. I managed to get through all the files by reloading auto-cad arbitrarily and sometimes when it didn’t work (not working meaning nothing changes when I expect it to) opening the script in the visual lisp editor and hitting load active window fixes it. I’d put it beside me but in the interest of learning and because I’ve already had to change the standard twice there’s a good chance I’ll have to do this again I want to try and fix this.

Considering the script with just changing the width to 1 works 100% of the time I’ve decided the problem is not with adding this to the startup suite/opening it in the visual lisp editor but rather with my addition to the code itself. However the line I added to change the text style
(entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo)) doesn’t seem different from the line to change the text width.

If anyone has any insight I’d appreciate it. I have experience with other programming languages but am a complete novice when it comes to Autolisp/lisp.

asked Aug 13, 2019 at 14:54

BlueLightning42's user avatar

There are a few issues which could trip up your code:

  • (setq ss (ssget))

    Without the filter list argument to permit only attributed blocks, your selection could include any entity type, meaning that the entnext call will return nil for any objects without subentities. This will consequently cause the entget call to return the following error that you are witnessing:

    error: bad argument type: lentityp nil

    The solution is to include a filter list to only permit selection of attributed blocks:

      (setq ss (ssget "_:L" '((0 . "INSERT") (66 . 1))))
    

    The _:L mode string also excludes entities on locked layers.

  • (setq sslen (sslength ss))

    Without testing for a valid selection, the variable ss could be nil which will cause (sslength ss) to return the error:

    error: bad argument type: lselsetp nil

  • (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
    (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))

    Here, the second subst expression is substituting DXF group 7 within the original DXF data list, not the DXF data which has been modified following the substitution of DXF group 41. This will have the result of reversing the modification to the width factor.


Implementing fixes for the above issues (and tweaking a few other things) might yield the following code:

(defun c:standardfromdwgtext ( / a i s x )
    (if (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
        (repeat (setq i (sslength s))
            (setq i (1- i)
                  a (entnext (ssname s i))
                  x (entget a)
            )
            (while (= "ATTRIB" (cdr (assoc 0 x)))
                (if (entmod (subst '(41 . 1.0) (assoc 41 x) (subst '(7 . "Standard") (assoc 7 x) x)))
                    (entupd a)
                )
                (setq a (entnext a)
                      x (entget  a)
                )
            )
        )
    )
    (princ)
)

Community's user avatar

answered Aug 13, 2019 at 20:43

Lee Mac's user avatar

Lee MacLee Mac

15.3k6 gold badges32 silver badges77 bronze badges

2

The error

bad ; error: bad argument type: lentityp nil

is a result of an empty variable being used for an entity.

When you use (setq ent (entnext blck)), you should then check if ent it nil.

(setq ent (entnext blck))
    (if ent
      (progn
        (setq entinfo (entget ent))

When troubleshooting AutoLisp, and you see lentityp or stringp = nil, then a variable you are using was set to nil and you need to find where and why.

answered Aug 13, 2019 at 20:48

mtaussie's user avatar

1

I had to change the text styles and width attributes of several blocks in Autocad. There was 10-30 blocks on each dwg and nearly 100 dgs and I could not be bothered to manually convert each block to the new standard.

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-width-change/td-p/1525357
this link has a script to change all the blocks (title blocks and several electrical symbols) width to 1 and as a first pass it does what I want (failing due to bad ; error: bad argument type: lentityp nil Command:which after changing it to manually select and just selecting the blocks I want fixes it). However I also need to change the test style from whatever it is to «Standard»
https://www.afralisp.net/reference/dxf-group-codes.php
after checking this link I found «Text style name» is code dxf 7
so I changed the script to the following.

(defun C:StandardFromDWGTEXT (/ ss sslen cnt blck ent entinfo)
  (setq ss (ssget))
  (setq cnt 0)
  (setq sslen (sslength ss))
  (while (< cnt sslen)
    (setq blck (ssname ss cnt))
    (setq ent (entnext blck))
    (setq entinfo (entget ent))
    (while
      (and ent (= (cdr (assoc 0 entinfo)) "ATTRIB"))
       (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
;;;    (entupd ent)
;;;    (setq ent (entnext ent))
;;;    (setq entinfo (entget ent))    
       (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
       (entupd ent)
       (setq ent (entnext ent))
       (setq entinfo (entget ent))      
    )
    (setq cnt (1+ cnt))
  )
  (princ)
)

Now it only works with the lines I commented out (stops working with them but that also means it only changes text style not width too) and only changes the text style half the time. I managed to get through all the files by reloading auto-cad arbitrarily and sometimes when it didn’t work (not working meaning nothing changes when I expect it to) opening the script in the visual lisp editor and hitting load active window fixes it. I’d put it beside me but in the interest of learning and because I’ve already had to change the standard twice there’s a good chance I’ll have to do this again I want to try and fix this.

Considering the script with just changing the width to 1 works 100% of the time I’ve decided the problem is not with adding this to the startup suite/opening it in the visual lisp editor but rather with my addition to the code itself. However the line I added to change the text style
(entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo)) doesn’t seem different from the line to change the text width.

If anyone has any insight I’d appreciate it. I have experience with other programming languages but am a complete novice when it comes to Autolisp/lisp.

asked Aug 13, 2019 at 14:54

BlueLightning42's user avatar

There are a few issues which could trip up your code:

  • (setq ss (ssget))

    Without the filter list argument to permit only attributed blocks, your selection could include any entity type, meaning that the entnext call will return nil for any objects without subentities. This will consequently cause the entget call to return the following error that you are witnessing:

    error: bad argument type: lentityp nil

    The solution is to include a filter list to only permit selection of attributed blocks:

      (setq ss (ssget "_:L" '((0 . "INSERT") (66 . 1))))
    

    The _:L mode string also excludes entities on locked layers.

  • (setq sslen (sslength ss))

    Without testing for a valid selection, the variable ss could be nil which will cause (sslength ss) to return the error:

    error: bad argument type: lselsetp nil

  • (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
    (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))

    Here, the second subst expression is substituting DXF group 7 within the original DXF data list, not the DXF data which has been modified following the substitution of DXF group 41. This will have the result of reversing the modification to the width factor.


Implementing fixes for the above issues (and tweaking a few other things) might yield the following code:

(defun c:standardfromdwgtext ( / a i s x )
    (if (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
        (repeat (setq i (sslength s))
            (setq i (1- i)
                  a (entnext (ssname s i))
                  x (entget a)
            )
            (while (= "ATTRIB" (cdr (assoc 0 x)))
                (if (entmod (subst '(41 . 1.0) (assoc 41 x) (subst '(7 . "Standard") (assoc 7 x) x)))
                    (entupd a)
                )
                (setq a (entnext a)
                      x (entget  a)
                )
            )
        )
    )
    (princ)
)

Community's user avatar

answered Aug 13, 2019 at 20:43

Lee Mac's user avatar

Lee MacLee Mac

15.3k6 gold badges32 silver badges77 bronze badges

2

The error

bad ; error: bad argument type: lentityp nil

is a result of an empty variable being used for an entity.

When you use (setq ent (entnext blck)), you should then check if ent it nil.

(setq ent (entnext blck))
    (if ent
      (progn
        (setq entinfo (entget ent))

When troubleshooting AutoLisp, and you see lentityp or stringp = nil, then a variable you are using was set to nil and you need to find where and why.

answered Aug 13, 2019 at 20:48

mtaussie's user avatar

1

Мне пришлось изменить стили текста и атрибуты ширины нескольких блоков в Autocad. Было 10-30 блоков на каждого dwg и почти 100 dgg, и я не мог потрудиться вручную конвертировать каждый блок в новый стандарт.

https: // forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-width-change/td-p/1525357 по этой ссылке есть скрипт для изменения ширины всех блоков (блоков заголовков и нескольких электрических символов) на 1, и в качестве первого прохода он делает то, что я хочу (сбой из-за bad ; error: bad argument type: lentityp nil Command:, который после его изменения выбирается вручную и просто выбирается блоки, которые я хочу исправить это). Однако мне также нужно изменить стиль теста с того, что он есть, на «Стандарт» https://www.afralisp.net/reference/dxf-group-codes. PHP После проверки этой ссылки я обнаружил, что «Имя стиля текста» — это код dxf 7 поэтому я изменил сценарий к следующему.

(defun C:StandardFromDWGTEXT (/ ss sslen cnt blck ent entinfo)
  (setq ss (ssget))
  (setq cnt 0)
  (setq sslen (sslength ss))
  (while (< cnt sslen)
    (setq blck (ssname ss cnt))
    (setq ent (entnext blck))
    (setq entinfo (entget ent))
    (while
      (and ent (= (cdr (assoc 0 entinfo)) "ATTRIB"))
       (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
;;;    (entupd ent)
;;;    (setq ent (entnext ent))
;;;    (setq entinfo (entget ent))    
       (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
       (entupd ent)
       (setq ent (entnext ent))
       (setq entinfo (entget ent))      
    )
    (setq cnt (1+ cnt))
  )
  (princ)
)

Теперь он работает только с закомментированными строками (перестает работать с ними, но это также означает, что он меняет только стиль текста, а не ширину) и только половина раза меняет стиль текста. Мне удалось пройти через все файлы, перезагружая auto-cad произвольно, а иногда, когда он не работал (не работает, значит, ничего не меняется, когда я этого ожидаю), открывая скрипт в визуальном редакторе lisp и нажимая на окно load active, исправляет его. Я бы положил это рядом со мной, но в интересах обучения, и, поскольку мне уже приходилось менять стандарт дважды, есть большая вероятность, что мне придется сделать это снова, я хочу попытаться это исправить.

Учитывая то, что сценарий с простым изменением ширины на 1 работает 100% времени, я решил, что проблема не в том, чтобы добавить его в набор автозагрузки / открыть его в редакторе визуальных шрифтов, а скорее в моем добавлении к самому коду. Однако строка, которую я добавил, чтобы изменить стиль текста (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo)) не отличается от строки для изменения ширины текста.

Если у кого-то есть понимание, я буду признателен. У меня есть опыт работы с другими языками программирования, но я начинающий, когда дело доходит до Autolisp / lisp.

2 ответа

Лучший ответ

Есть несколько проблем, которые могут испортить ваш код:

  • (setq ss (ssget))

    Без аргумента списка фильтров, разрешающего только приписанные блоки, ваш выбор может включать любой тип сущности, то есть вызов entnext вернет вызов nil для любых объектов без субтитр. Следовательно, вызов entget вернет следующую ошибку, свидетелем которой вы являетесь:

    ошибка: неверный тип аргумента: lentityp nil

    Решение состоит в том, чтобы включить список фильтров, чтобы разрешить только выбор приписанных блоков:

    (setq ss (ssget "_:L" '((0 . "INSERT") (66 . 1))))
    

    Строка режима _:L также исключает объекты на заблокированных слоях.

  • (setq sslen (sslength ss))

    Без проверки правильности выбора переменная ss может быть nil, что приведет к (sslength ss) возвращению ошибки:

    ошибка: неверный тип аргумента: lselsetp nil

  • (entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
    (entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))

    Здесь второе subst выражение заменяет группу 7 DXF в оригинале списке данных DXF, а не данные DXF, которые были изменены после замены группы 41 DXF. Это приведет к обращению изменения коэффициента ширины.


Внедрение исправлений для вышеуказанных проблем (и несколько других изменений) может привести к следующему коду:

(defun c:standardfromdwgtext ( / a i s x )
    (if (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
        (repeat (setq i (sslength s))
            (setq i (1- i)
                  a (entnext (ssname s i))
                  x (entget a)
            )
            (while (= "ATTRIB" (cdr (assoc 0 x)))
                (if (entmod (subst '(41 . 1.0) (assoc 41 x) (subst '(7 . "Standard") (assoc 7 x) x)))
                    (entupd a)
                )
                (setq a (entnext a)
                      x (entget  a)
                )
            )
        )
    )
    (princ)
)


2

Lee Mac
13 Авг 2019 в 20:43

Ошибка

плохой ; ошибка: неверный тип аргумента: lentityp nil

Является результатом использования пустой переменной для сущности.

Когда вы используете (setq ent (entnext blck)), вам следует проверить, не равен ли ему ноль.

(setq ent (entnext blck))
    (if ent
      (progn
        (setq entinfo (entget ent))

При устранении неполадок AutoLisp, когда вы видите lentityp или stringp = nil, тогда используемая вами переменная была установлена на nil, и вам нужно найти, где и почему.


0

mtaussie
13 Авг 2019 в 20:48

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Ошибка неверные показания rtc
  • Ошибка неверный тип аргумента file nil