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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Сортировка списка, содержащего в себе информацию о полях

Сортировка списка, содержащего в себе информацию о полях

Ответ
Поиск в этой теме
Непрочитано 12.03.2018, 12:17 #1
Сортировка списка, содержащего в себе информацию о полях
Matvey Razin
 
Регистрация: 28.09.2015
Сообщений: 69

Формируется следующий список (список 1):

Код:
[Выделить все]
 (("%<\\AcObjProp Object(%<\\_ObjId -1120819320>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120818648>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818960>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818880>%).TextString>%") ("%<\\AcObjProp Object(%<\\_ObjId -1120820024>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120819416>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819728>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819648>%).TextString>%")) 
Его элементы - параметры динамического блока. В данном случае представлен список, сформированный из двух блоков, в каждом из которых четыре параметра.

На деле этот список может принимать следующий вид (список 2):

Код:
[Выделить все]
 (("12" "∅12 А500С ГОСТ Р52544-2006 L=7700" "21" "0,88") ("2" "∅8 А500С ГОСТ Р52544-2006 L=5500" "10" "0,55"))
Данный список (список 2) можно отсортировать по его первому элементу в порядке возрастания, но мне необходимо сделать это с первым списком (список 1), что бы далее вставить его значения в таблицу в виде полей.

Подскажите, можно ли представить список 1 в виде списка 2, что бы можно было с ним оперировать?

Последний раз редактировалось Matvey Razin, 12.03.2018 в 15:01.
Просмотров: 2188
 
Непрочитано 12.03.2018, 12:23
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Ну добавь в качестве первого элемента не представление поля, а его отображаемое значение - и сортируй как угодно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 12.03.2018, 12:56
#3
Matvey Razin


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


А как это сделать я и не знаю
Вот поэтому и написал
Matvey Razin вне форума  
 
Непрочитано 12.03.2018, 13:48
#4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Покажи, откуда и как ты получаешь эти списки.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 12.03.2018, 14:22
#5
Matvey Razin


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


Код:
[Выделить все]
 
(setq list_blocks '()); создали пустой список с именами блоков
(setq nab_block (ssget '((0 . "INSERT")))); создали набор из блоков
(setq nab_block_length (sslength nab_block)); длина набора
(setq i -1)
(repeat nab_block_length
    (setq i (1+ i))	
    (setq block (vlax-ename->vla-object (ssname nab_block i))); извлекли имя i-го блока набора, сделали его vla-объектом
    (setq list_blocks (append list_blocks (list block))); добавили имя i-го блока в список с именами блоков
    
    (setq position (strcat "%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (nth i list_blocks)))">%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%"))
    (setq name (strcat "%<\\Acobjprop Object(%<\\_Objid "(Vl-Princ-To-String (Vla-Get-Objectid (Vlax-Safearray-Get-Element (Vlax-Variant-Value (Vla-Getattributes (Nth i List_Blocks))) 4)))">%).Textstring>%"))
    (setq number (strcat "%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (vlax-safearray-get-element (vlax-variant-value (vla-GetAttributes (nth i list_blocks))) 0)))">%).TextString>%"))
    (setq weight (strcat "%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (vlax-safearray-get-element (vlax-variant-value (vla-GetAttributes (nth i list_blocks))) 1)))">%).TextString>%"))

    (if (= i 0)
    (setq list_table_content (list (list position name number weight)))
    (setq list_table_content (append list_table_content(list (list position name number weight))))
    )
)
list_table_content - список 1
Matvey Razin вне форума  
 
Непрочитано 12.03.2018, 15:40
#6
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Абсолютно непонятный и неустойчивый код. Что будет, если вообще атрибутов в обрабатываемом блоке нет? А что будет, если порядок следования атрибутов другой?
В качестве затравки:
Код:
[Выделить все]
 (defun tt (/ selset)
  (if (= (type (setq selset (vl-catch-all-apply (function (lambda () (ssget '((0 . "INSERT") (66 . 1))))))))
         'pickset
         ) ;_ end of =
    (mapcar (function (lambda (x / at)
                        (setq x  (vlax-ename->vla-object x)
                              at (mapcar (function (lambda (a) (cons (strcase (vla-get-tagstring a)) (vla-get-objectid a))))
                                         (vlax-safearray->list (vlax-variant-value (vla-getattributes x)))
                                         ) ;_ end of mapcar
                              ) ;_ end of setq
                        ;; at - список тэгов атрибутов и их ObjectID для одного блока
                        ;; Теперь формируй из них чего надо и не забудь вперед поставить, например, значение атрибута number
                        ) ;_ end of lambda
                      ) ;_ end of function
            ((lambda (/ tab item)
               (repeat (setq tab  nil
                             item (sslength selset)
                             ) ;_ end setq
                 (setq tab (cons (ssname selset (setq item (1- item))) tab))
                 ) ;_ end of repeat
               ) ;_ end of lambda
             )
            ) ;_ end of mapcar
    ) ;_ end of if
  ) ;_ end of defun
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 12.03.2018, 17:08
#7
Matvey Razin


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


Оговорюсь, что код пишется впервые и в рамках малой автоматизации (под себя), поэтому:

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Что будет, если вообще атрибутов в обрабатываемом блоке нет? А что будет, если порядок следования атрибутов другой?
атрибуты в блоке есть всегда и порядок следования их не меняется.

К слову, первый элемент списка параметров блока не атрибут, а динамический линейный параметр ("%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (nth i list_blocks)))">%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">;%")

Мне необходимо преобразовать представление поля ("%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (nth i list_blocks)))">%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">;%") в его отображаемое значение (н-р "12"), как ты и написал в посте №2.

Например, как функция ascii:
(ascii "A") возвращает 192

Так и мне требуется:
(некая_функция "%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (nth i list_blocks)))">%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">;%") возвращает 12 (например).

Или все это невозможно?
Matvey Razin вне форума  
 
Непрочитано 13.03.2018, 07:57
#8
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Файл приложи. Гадать можно до бесконечности. А так - см.функции получения значений дин.свойств блока (на форуме несколько раз точно мелькали).
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 13.03.2018, 19:03
#9
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от Matvey Razin Посмотреть сообщение
Подскажите, можно ли представить список 1 в виде списка 2, что бы можно было с ним оперировать?
Если изначально порядок элементов в списке1 и списке2 совпадает, то смотри функцию vl-sort-i. Она возвращает индексы элементов
Сортируешь список2 по нужным критериям, получаешь список индексов элементов в списке1 и списке2
Пример
Код:
[Выделить все]
 
(setq lst1 '(("%<\\AcObjProp Object(%<\\_ObjId -1120819320>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120818648>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818960>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818880>%).TextString>%") ("%<\\AcObjProp Object(%<\\_ObjId -1120820024>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120819416>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819728>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819648>%).TextString>%")))
(setq lst2 '(("12" "?12 А500С ГОСТ Р52544-2006 L=7700" "21" "0,88") ("2" "?8 А500С ГОСТ Р52544-2006 L=5500" "10" "0,55")))
(setq index (vl-sort-i lst2 (function(lambda(e1 e2)(< (atoi (car e1))(atoi (car e2)))))))
(foreach i index
  (princ "\nСписок lst2= ")(princ (nth i lst2))
  (princ "\nСписок lst1= ")(princ (nth i lst1))
  (princ "\n==============================================")(princ)
  )
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 15.03.2018, 11:50
#10
Matvey Razin


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


VVA, спасибо, но я, видимо, не так объясняю.
В итоге добавил первым элементом списка для каждого блока значение динамического линейного параметра (строка 12).

Код:
[Выделить все]
 
(setq list_blocks '()); создали пустой список с именами блоков
(setq nab_block (ssget '((0 . "INSERT")))); создали набор из блоков
(setq nab_block_length (sslength nab_block)); длина набора

(setq i -1)

(repeat nab_block_length
    (setq i (1+ i))	
    (setq block (vlax-ename->vla-object (ssname nab_block i))); извлекли имя i-го блока набора, сделали его vla-объектом
    (setq list_blocks (append list_blocks (list block))); добавили имя i-го блока в список с именами блоков

    (setq pos (rtos (vlax-get (nth 1 (vlax-invoke (nth i list_blocks) 'getdynamicblockproperties)) 'value) 2 0))
    (setq position (strcat "%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (nth i list_blocks)))">%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%"))
    (setq name (strcat "%<\\Acobjprop Object(%<\\_Objid "(Vl-Princ-To-String (Vla-Get-Objectid (Vlax-Safearray-Get-Element (Vlax-Variant-Value (Vla-Getattributes (Nth i List_Blocks))) 4)))">%).Textstring>%"))
    (setq number (strcat "%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (vlax-safearray-get-element (vlax-variant-value (vla-GetAttributes (nth i list_blocks))) 0)))">%).TextString>%"))
    (setq weight (strcat "%<\\AcObjProp Object(%<\\_ObjId "(vl-princ-to-string (vla-get-objectid (vlax-safearray-get-element (vlax-variant-value (vla-GetAttributes (nth i list_blocks))) 1)))">%).TextString>%"))

    (if (= i 0)
    (setq list_table_content (list (list pos position name number weight)))
    (setq list_table_content (append list_table_content(list (list pos position name number weight))))
    )
) 
Для двух блоков получается следующий список:

Код:
[Выделить все]
 
(("12" "%<\\AcObjProp Object(%<\\_ObjId -1120819320>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120818648>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818960>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818880>%).TextString>%") ("2" "%<\\AcObjProp Object(%<\\_ObjId -1120820024>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120819416>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819728>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819648>%).TextString>%"))
Сортирую его вашей функций по первому элементу списка:

Код:
[Выделить все]
 
(defun SortStringWithNumberAsNumber (ListOfString IgnoreCase / NorStrs count)
  (defun NormalizeNumberInString (str count / ch i pat ret buf)
    (setq i   0
          pat '("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")
          ret ""
    )
    (while (/= (setq ch (substr str (setq i (1+ i)) 1)) "")
      (if (vl-position ch pat)
        (progn
          (setq buf ch)
          (while
            (vl-position (setq ch (substr str (setq i (1+ i)) 1)) pat)
             (setq buf (strcat buf ch))
          )
          (while (< (strlen buf) count) (setq buf (strcat "0" buf)))
          (setq ret (strcat ret buf))
        )
      )
      (setq ret (strcat ret ch))
    )
    ret
  )
  (defun getcount (lst / count pat)
    (setq count 0)
    (setq pat '("0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))
    (mapcar
      '(lambda (str / i maxlen ch)
         (setq i 0 maxlen 0)
         (while (/= (setq ch (substr str (setq i (1+ i)) 1)) "")
           (if (vl-position ch pat)
             (setq maxlen (1+ maxlen))
             (setq count  (max count maxlen) maxlen 0)
           )
         )
  (setq count  (max count maxlen))
       )
      Lst
    )
    count
  )
  (setq count   (GetCount ListOfString)
        NorStrs (mapcar '(lambda (x) (NormalizeNumberInString x count))
                        ListOfString)
  )
  (and IgnoreCase (setq NorStrs (mapcar 'strcase NorStrs)))
  (mapcar '(lambda (x) (nth x ListOfString)) (vl-sort-i NorStrs '<))
)

(setq sort_list_tabe_content (mapcar '(lambda(x)(assoc x list_table_content))
(SortStringWithNumberAsNumber (mapcar 'car list_table_content) t)
 ))
и получаю на выходе:

Код:
[Выделить все]
 
(("2" "%<\\AcObjProp Object(%<\\_ObjId -1120820024>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120819416>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819728>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120819648>%).TextString>%") ("12" "%<\\AcObjProp Object(%<\\_ObjId -1120819320>%).Parameter(296).UpdatedDistance \\f \"%lu2%pr0\">%" "%<\\Acobjprop Object(%<\\_Objid -1120818648>%).Textstring>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818960>%).TextString>%" "%<\\AcObjProp Object(%<\\_ObjId -1120818880>%).TextString>%"))
Дальше все элементы списка (без первого) заношу в таблицу.
Matvey Razin вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Сортировка списка, содержащего в себе информацию о полях

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ищу информацию по опорам ЛЭП 110 кВ "Шатурского" типа АМ 103, ПМ 103, АМ 102, ПМ 102 Vikk Поиск литературы, чертежей, моделей и прочих материалов 0 08.08.2012 17:17
Каким образом указывают информацию об изменении документа титульном листе рабочих чертежей? Rosenkranz Архитектура 1 31.07.2012 09:30
как прикрепить информацию к объекту? ZeDius AutoCAD 1 08.07.2012 22:22
Ищу информацию для проектирования мини-гостиницы SkyMan Поиск литературы, чертежей, моделей и прочих материалов 12 10.09.2011 18:43
Помогите. Программа отображения каталогизированного списка блоков. --Илья-- Программирование 18 02.12.2009 11:25