|
||
| Правила | Регистрация | Пользователи | Сообщения за день | | Поиск | | Справка по форуму | Файлообменник | |
|
Поиск в этой теме |
14.07.2017, 18:03 | #1 | |
Извлечение значений атрибутов динамического блока и создание таблицы Autocad VBA
Регистрация: 01.03.2010
Сообщений: 21
|
||
Просмотров: 8464
|
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,848
|
Ну во-первых, не помешает добавить фильтр для набора.
2. При проходе по набору сразу проверяй EffectiveName для примитива. 3. Для таблицы есть свойство, если не ошибаюсь, что-то-там-Recompute (посмотри в справке). Перед заполнением настоятельно рекомендую установить его в False, после выполнения кода в True, и не забудь про регенерацию.
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
|
||||
Регистрация: 01.03.2010
Сообщений: 21
|
Цитата:
Постараюсь со всем разобраться. |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,049
|
1. Привязываться к установке количества строк таблицы по значению тега "ПОЗ" плохая идея - влияние человеческого фактора. А если понадобиться вставить позицию 10.1 или 10а (ну или просто сотрудник ошибется) - то сразу получите ошибку при вызове CInt.
2. Я бы использовал словарь Scripting.Dictionary с поздним связыванием (чтобы не подключать лишние референсы): 2.1. В качестве ключа использовать - значение атрибута "ПОЗ". 2.2. Длина в качестве значения элемента словаря. Извлекаете данные из блока, проверяете в словаре по ключу значения атрибута "ПОЗ" через Exists. Если найдено, то извлекаете длину из словаря, корректируете и записываете обратно. Не найдено - добавляете в словарь. 2.3. После проходу по всем блокам в свойстве Count словаря будет как раз искомое реальное количество строк таблицы. насколько понял, в таблице связка значений атрибута "ПОЗ" и динамического параметра длины, поэтому имя блока вообще можно игнорировать. |
|||
|
||||
Регистрация: 01.03.2010
Сообщений: 21
|
Цитата:
Со словарем никогда не работал, буду изучать чтобы понять что с ним делать. Из Вашего ответа не совсем понял как будут суммироваться длины всех одинаковых позиций. Спасибо за ответ! |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,049
|
Цитата:
----- добавлено через ~6 мин. ----- Только не факт, что позиции будут идти по порядку. В каком порядке опросит блоки акад - в таком и получите (когда первый раз встретилась данная позиция, точнее). |
|||
|
||||
Регистрация: 01.03.2010
Сообщений: 21
|
Цитата:
И еще один вопрос: AcadDictionary это то, о чем Вы говорили? Просто в справке Scripting.Dictionary не могу найти, да и в книжке тоже нет. |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,049
|
Цитата:
Словарь вообще не имеет непосредственного отношения к VBA, это часть библиотеки Microsoft Scripting Runtime где-то c 2000 версии. Наберите в поисковике: VBA Scripting.Dictionary. Просто в самом VBA есть похожие вещи - коллекции, но там нет метода Exists. Поэтому приходиться подключать внешний словарь. Ну или писать самому реализацию) |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,049
|
так в вашем коде как раз и нету этой части - сбора информации по длинам с привязкой к позициям. Отдельный цикл по блокам, отдельный цикл по таблице - а между ними ничего. С готовым словарем получиться код - ну раза в три больше, чем сейчас. Тем более, если выкинуть с начала процедуры сильно информативные сообщения об том, что примитив не является блоком, например.
|
|||
|
||||
Регистрация: 05.11.2015
Сообщений: 585
|
После того как в цикле
Цитата:
2. создайте двумерный динамический массив ReDim otd_ster(kol_otd, 2) 3. перенесите все аргументы блоков в этот массив 4. суммируйте, сокращайте и сортируйте элементы массива 5. сливайте окончательный массив в таблицу акада. |
|||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,049
|
Цитата:
2. Все операции по обработке элементов массива придется писать самим. Удаление элемента массива является операцией сложности O(n), т.е. зависит от количества элементов в списке. Сортировка тоже зависит, причем классический метод быстрой сортировки через рекурсивный вызов вызовет очень быстро ошибку переполнения стека. 3. ReDim otd_ster(kol_otd, 2) - получите трехмерный массив с лишней строкой и столбцом (0..kol_otd, 0..2). Да и тогда более логичным было бы применение UTD - создать структуру из двух полей: Поз и Длина. И массив из UTD. |
|||
|
||||||
Регистрация: 05.11.2015
Сообщений: 585
|
Цитата:
Можно и цикл по атрибутам, тоже непонятно в чем проблема? Но для данной задачи заведомо известно, что их там только 2. Ну и считали их на раз-два, без цикла. Цитата:
Цитата:
Цитата:
Цитата:
и работать с массивом по-человечески. Тогда Первая позиция - она и первый элемент массива. Откуда Вы тут получили трехмерный массив вообще непонятно. Трехмерный это как-то вот так будет Код:
Код:
|
|||||
|
||||
Регистрация: 10.08.2013
Сообщений: 11,049
|
Владимир_М, поскольку я ленив, но написал бы так:
Код:
----- добавлено через ~42 мин. ----- p.s. 1. Насчет трехмерного массива оговорился, сорри - имел в виду массив из трех столбцов) 2. Option Base 1 -> можно написать проще Redim %Имя массива%(1 To N, 1 To 2). В одной функции индексация с единицы, в другой (написанной позже или скопированной готовой) с нуля - проще локально объявлять, имхо. Зачем создавать лишние источники ошибок? 3. Метод сортировки пузырьком один из самых медленных, есть и изящнее решения - где стек эмулируется дополнительным массивом и используется быстрая сортировка. Возможно, в ряде случаев проще будет выгрузить в эксель, там отсортировать, создать диапазон и связать с таблицей. |
|||
|
||||
Регистрация: 01.03.2010
Сообщений: 21
|
Сергей812, большое Вам спасибо, все получилось!
Единственное, пришлось сделать lDict.Count + 1 (число строк) поскольку выпадала максимальная позиция. А также выдавало ошибку в строке: lLength = CDbl((varAttribs(intI).TextString), пришлось сделать так - lLength = CDbl(Replace(varAttribs(intI).TextString, ".", ",")), это правильное решение? В самой таблице значения длины с пятью нулями после запятой), но сейчас погуглю как их обрезать. Владимир_М и Кулик Алексей aka kpblc спасибо за советы и замечания. |
|||
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,848
|
... А в системе может быть установлен десятичный разделитель "." - и тогда решение не прокатит. ИМХО надо читать из реестра установленный разделитель (раздел HKEY_CURRENT_USER\Control Panel\International, ключ sDecimal). И выполнять двойную конвертацию - и точки, и запятой.
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
LISP. Создание поля (field), ссылающегося на текстовое значение ячейки таблицы. | skkkk | Готовые программы | 141 | 24.11.2023 15:49 |
Автоматическое обновление атрибутов динамического блока в автокад | IllIDaN_wc | Динамические блоки | 3 | 31.05.2017 14:51 |
Ссылка атрибутов блока на ячейки таблицы СПДС | Voha | AutoCAD | 9 | 14.12.2011 17:55 |
Извлечение атрибутов блока и вставка атрибутов в формулу | andery | AutoCAD | 38 | 15.06.2009 02:39 |
Создание кнопки для динамического блока | nik7 | Динамические блоки | 4 | 23.12.2008 15:33 |