![]() | ![]() |
Translate to: |
|||||
Обратная связь | Новости САПР | Программы | Документация | Полезные советы | Обзорные статьи | ||
Заказ и разработка | Каталог САПР | САПР-конференция | Библиотека ГОСТов | Наши соавторы | Коммерческое ПО |
Если вы перешли на AutoCAD 2008 с более ранней версии AutoCAD, перед вами может возникнуть задача преобразования таблиц, сделанные до введения команды в AutoCAD команды Table. Простейшим способом является использование метода извлечения данных в команды Table. Конечно это достаточно мощный инструмент, но когда данные находятся в форме линий, полилиний, текста, и mtext, получить данные в пригодном для использования формате довольно трудоёмко. Решением стало написание утилиты MAKETABLE.LSP, который позволяет пользователю выбирать линии, полилиний, и любой тип текста и преобразовывать их в табличный объект AutoCAD, который заменяет первоначальные данные.
Утилита называется MAKETABLE.LSP и ее можно скачать здесь. Ниже дано описание ее принципов работы и использования.
Используйте средство Appload, выбрав пункт Load Application в меню Tools, а затем выбрав MAKETABLE.LSP в меню просмотра.
Чтобы загрузить программу, введите MTB в командной строке, затем у вас будет запрошено выбрать окном по двум точкам исходную таблицу. После этого, таблица, состоящая из линий, полилиний и текста будет автоматически преобразована в табличный объект AutoCAD, который будет содержать оригинальные данные и заголовки. На рисунках 1 и 2 показана таблица до и после преобразования.
Программа работает с большинством типов таблиц, которые могут содержать любое числом строк и столбцов и любой тип текста. Работоспособность программы сохраняется даже если есть линии, нарисованные точно одна над другой, или есть полилинии, используемые произвольно - например, как разделители для строк или столбцов. В новой таблице текст форматируется по центру ячеек, за исключением текста в столбце Description (если он существует), который форматируется по левому краю.
После моих стандартных функций обработки ошибок и системных переменных, текст программы содержит функцию GETOLDTABLE, которая использует методы VLA-GETPOINT и VLA-GETCORNER чтобы установить две по диагонали противоположных точки, которые используются, чтобы выбрать объекты таблицы. Точки фактически используются дважды: один раз, чтобы выбирать все полилинии, которые могут существовать и второй раз, чтобы выделить все линии и текстовые объекты. Все найденные полилинии разбиваются с помощью метода VLA-EXPLODE. GETOLDTABLE заканчивает свою работу созданием наборов линий и текстовых объектов, а затем управление передается функции MAKETABLE, куда эти наборы передаются как аргумент.
MAKETABLE собирает линии и текст в отдельных списках вызывая функции GET-LINES и GET-TEXT. В дальнейшем линии разделяются на горизонтальные и вертикальные с помощью функции GET-ROWSCOLS до того, как они будут отсортированы в списки строк и столбцов. В случае, если присутствуют сдвоенные линии, списки строк и столбцов обрабатываются функцией DO-DUPES прежде, чем быть они будут отсортированы снова. Текстовые объекты собираются в списки многострочного и однострочного текста с помощью функции GET-TXTMTXT. Параметры для метода VLA-ADDTABLE - число строк и столбцов и высоты строки и ширины столбцов. Табличный же объект создается как пустая таблица следующим кодом:
(setq tableobj (vla-AddTable *modelspace* (vlax-3D-point (caar collines3)) rows cols RowHeight ColWidth ) ;_ end of vla-AddTable ) ;_ end of setq
По умолчанию, таблица имеет шапку и заглавие, и я решил удалить слияние для строки заголовка, и разместить табличный объект на том же слое, как и исходные текстовые объекты. Для заполнения же ячеек таблицы используется вызов функции POPULATE-TABLE, как показано ниже:
(vla-UnmergeCells tableobj 0 0 0 (- cols 1)) (setq lyr (vla-get-Layer (nth 0 horlines))) (vla-put-layer tableobj lyr) (populate-table tableobj tlist rowlines3 collines3)
Одна из наиболее интересных функций следует за вышеупомянутой DO-DUPES, и написана не смотря на то, что существует прекрасная функция Visual LISP VL-REMOVE, которая и предназначена для удаления любого элемента (и его дубликатов) из списка. К сожалению, в нашем случае метод не работал последовательно на списках точек, так как их координаты не были достаточно точны, даже если учитывать, что линии были точно на вершине друг друга в пределах 13 десятичных разрядов! Поэтому, затратив много времени на выяснение, почему двойные линии не удалялись, я вынужден был написать свою собственную версию удаляющегося метода (MYVL-REMOVE):
(defun myvl-remove (item llst) (setq j (- 1)) (repeat (length llst) (setq item2 (nth (setq j (1+ j)) llst)) (if (equal item item2 fuzz) (setq llst (vl-remove item2 llst)) ) ;_ end of if ) ;_ end of repeat llst ) ;_ end of myvl-remo
Решением является введение допуска в процедуру сравнения, а затем удалять равный элемент из списка, обозначенный в листинге как ITEM2. Этот метод гарантирует удаление одного дублированного элемента за один раз, но так как он проверяет все элементы в списке, то таким образом может обработать любое число дубликатов. Я обычно определяю глобальные переменные звездочками в начале и конце, но в случае переменной FUZZ не следовал этому формату. Фактически, везде в этой программе, я не определял местные и глобальные переменные вообще, кроме тех, которых передаются как параметры. Программирование таким образом может быть опасным, но я решил инициализировать списки и счетчики в отдельных функциях вместо этого.
Функция POPULATE-TABLE за один раз берет каждый текстовый объект из текстового списка, и использует его точку вставки для определения, где (в какой строке и столбце) он должен быть размещен в новой таблице. Это является разумным подходом для таблиц, которые не полностью заполнены текстом, так как пустые ячейки просто не рассматриваются. Все текстовые объекты - заголовки располагаются в строке 0 (самой верхней строке), и это естественно облегчает работу с ними. Столбцы для текста заголовка были определены по расположению слитых ячеек. Все остальные текстовые объекты размещены с помощью метода VL-SETTEXT, устанавливаются такие параметры ячейки как высота, ширина колонки, стиль и высота текста. Фрагмент кода, который делает это:
(progn (vla-SetText tobj row col txtstr) ) ;_ end of progn ) ;_ end of if (vla-SetCellTextHeight tobj row col txtht) (vla-SetColumnWidth tobj col colwidth) (vla-SetRowHeight tobj row rowheight) (vla-SetCellTextStyle tobj row col textstyle)
Сначала создается пустая таблица, затем форматируются ячейки и добавляется текст. Каждый раз, когда это осуществляется, таблица автоматически регенерируется, и по моему мнению для ускорения черчения следует воздержаться от регенерации до того момента, пока все ячейки не будут заполнены. Регенерация определяется как true или false, и следующий код из функции MAKETABLE показывает, как это было сделано:
(vla-put-RegenerateTableSuppressed tableobj :vlax-True) (vla-UnmergeCells tableobj 0 0 0 (- cols 1)) (setq lyr (vla-get-Layer (nth 0 horlines))) (vla-put-layer tableobj lyr) (populate-table tableobj tlist rowlines3 collines3) (if (> cols 6) (progn (vla-MergeCells tableobj 0 0 0 5) (vla-MergeCells tableobj 0 0 6 7) ) ;_ end of progn (vla-MergeCells tableobj 0 0 0 (- cols 1)) ) ;_ end of if (vla-put-RegenerateTableSuppressed tableobj :vlax-False) (vla-erase ss1) ) ;_ end of MakeTable
Последняя строка этой функции стирает весь набор линий и текста, который составляет первоначальную таблицу.
Copyright © Сайт поддержки пользователей САПР by Victor Tkachenko