Логотип сайта поддержки пользователей САПРО сайте поддержки пользователей САПР Translate to:

AutoCAD 2008: конвертирование данных из старых таблиц в новый табличный формат.

Tony Hotchkiss
www.cadalyst.com

Если вы перешли на AutoCAD 2008 с более ранней версии AutoCAD, перед вами может возникнуть задача преобразования таблиц, сделанные до введения команды в AutoCAD команды Table. Простейшим способом является использование метода извлечения данных в команды Table. Конечно это достаточно мощный инструмент, но когда данные находятся в форме линий, полилиний, текста, и mtext, получить данные в пригодном для использования формате довольно трудоёмко. Решением стало написание утилиты MAKETABLE.LSP, который позволяет пользователю выбирать линии, полилиний, и любой тип текста и преобразовывать их в табличный объект AutoCAD, который заменяет первоначальные данные.

Утилита называется MAKETABLE.LSP и ее можно скачать здесь. Ниже дано описание ее принципов работы и использования.

Как использовать MAKETABLE.LSP

Используйте средство Appload, выбрав пункт Load Application в меню Tools, а затем выбрав MAKETABLE.LSP в меню просмотра.

Чтобы загрузить программу, введите MTB в командной строке, затем у вас будет запрошено выбрать окном по двум точкам исходную таблицу. После этого, таблица, состоящая из линий, полилиний и текста будет автоматически преобразована в табличный объект AutoCAD, который будет содержать оригинальные данные и заголовки. На рисунках 1 и 2 показана таблица до и после преобразования.


Рис. 1. Таблица, состоящая из линий, полилиний и текста

Рис. 2. Таблица, сконвертированная в табличный формат AutoCAD

Программа работает с большинством типов таблиц, которые могут содержать любое числом строк и столбцов и любой тип текста. Работоспособность программы сохраняется даже если есть линии, нарисованные точно одна над другой, или есть полилинии, используемые произвольно - например, как разделители для строк или столбцов. В новой таблице текст форматируется по центру ячеек, за исключением текста в столбце 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