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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Достать "формулу" из ячейки таблицы autocad

Достать "формулу" из ячейки таблицы autocad

Ответ
Поиск в этой теме
Непрочитано 11.12.2018, 21:08 #1
Достать "формулу" из ячейки таблицы autocad
tsetse
 
Инженер-конструктор
 
Москва
Регистрация: 25.12.2015
Сообщений: 77

Добрый день! Возникла следующая проблема. Имеется таблица, в одной из ее ячеек, например A5, вписана формула =A3+A4. Возникла необходимость "достать данную формулу. Стандартный метод vla-getText возвращает число, а не формулу "=A3+A4". Можно ли как-то это побороть?
12.12.2018
Вот что получилось в результате
Код:
[Выделить все]
 (defun C:PCS ( / cellset)
; Функция "складывает" ячейки таблицы и записывает в выбранную
(vl-load-com)
(setq pt nil)
(setq cellset "=")
(setq findedcell nil)
(setq row nil)
(setq col nil)
(setq tblobj nil)
; Запрашиваем ячейки, которые нужно добавить в цикле
(while
	; Запрашиваем точку внутри ячейки
	(setq pt (getpoint "\n Укажите ячейки таблицы, которые нужно сложить:"))
	; получаем row и col в буквенном формате а также указатель на таблицу tblobj
	(GET_CELL_ID pt)
	; добавляем элемент в строку, которую потом впишем	
	(setq cellset (strcat cellset findedcell "+" ))
	(setq findedcell nil)
	(setq row nil)
	(setq col nil)
) ; end of while
; Удаляем последний знак плюс из cellset
(progn
	(setq cellsetlen (strlen cellset))
	(setq cellsetlen (- cellsetlen 1))
	(setq cellset (substr cellset 1 cellsetlen))
	(setq cellsetlen nil)
) ; end of progn
; Запрашиваем ячейку, в которую вписать сумму
(setq pt (getpoint "\n Укажите ячейку таблицы, в которую вписать сумму:"))
; получаем row и col в буквенном формате а также указатель на таблицу tblobj
(GET_CELL_ID pt)
; получаем содержимое заполняемой ячейки
(CELL_FIELD row col tblobj)
; Записываем в ячейку строку-формулу
(vla-SetText tblobj row col cellset)
(setq row nil)
(setq col nil)
(setq tblobj nil)
) ; end of defun

;________________________________________________________________________________


(defun C:PCSA ( / cellset)
; Функция "добавляет" к указанной ячейке таблицы выбранные
(vl-load-com)
(setq pt nil)
(setq cellset "=")
(setq findedcell nil)
(setq row nil)
(setq col nil)
(setq tblobj nil)
(setq row1 nil)
(setq col1 nil)
(setq tblobj1 nil)
(setq field_string nil)
; Запрашиваем точку внутри ячейки к которой добавляем
(setq pt (getpoint "\n Укажите ячейку таблицы, к которой добавляем:"))
; получаем row и col в буквенном формате а также указатель на таблицу tblobj
(GET_CELL_ID pt)
(setq tblobj1 tblobj)
(setq row1 row)
(setq col1 col)
(setq row nil)
(setq col nil)
(setq tblobj nil)
; получаем содержимое заполняемой ячейки
(setq field_string "")
(CELL_FIELD row1 col1 tblobj1)
; Запрашиваем ячейки, на которые домножаем
; Запрашиваем ячейки, которые нужно добавить в цикле
(while
	; Запрашиваем точку внутри ячейки
	(setq pt (getpoint "\n Укажите ячейки таблицы, которые нужно добавить:"))
	; получаем row и col в буквенном формате а также указатель на таблицу tblobj
	(GET_CELL_ID pt)
	; добавляем элемент в строку, которую потом впишем	
	(setq cellset (strcat cellset findedcell "+" ))
	(setq findedcell nil)
	(setq row nil)
	(setq col nil)
) ; end of while
; собираем новый текст
(setq txtnew (strcat cellset "(" field_string ")"))
(vla-SetText tblobj1 row1 col1 txtnew)
(setq row1 nil)
(setq col1 nil)
(setq tblobj1 nil)
(setq row nil)
(setq col nil)
(setq tblobj nil)
) ; end of defun

;________________________________________________________________________________


(defun C:PCM ( / cellset)
; Функция "перемножает" выбранные ячейки таблицы и записывает в выбранную
(vl-load-com)
(setq pt nil)
(setq cellset "=")
(setq findedcell nil)
(setq row nil)
(setq col nil)
(setq tblobj nil)
; Запрашиваем ячейки, которые нужно добавить в цикле
(while
	; Запрашиваем точку внутри ячейки
	(setq pt (getpoint "\n Укажите ячейки таблицы, которые нужно перемножить:"))
	; получаем row и col в буквенном формате а также указатель на таблицу tblobj
	(GET_CELL_ID pt)
	; добавляем элемент в строку, которую потом впишем	
	(setq cellset (strcat cellset findedcell "*" ))
	(setq findedcell nil)
	(setq row nil)
	(setq col nil)
) ; end of while
; Удаляем последний знак * из cellset
(progn
	(setq cellsetlen (strlen cellset))
	(setq cellsetlen (- cellsetlen 1))
	(setq cellset (substr cellset 1 cellsetlen))
	(setq cellsetlen nil)
) ; end of progn
; Запрашиваем ячейку, в которую вписать произведение
(setq pt (getpoint "\n Укажите ячейку таблицы, в которую вписать произведение:"))
; получаем row и col в буквенном формате а также указатель на таблицу tblobj
(GET_CELL_ID pt)
; получаем содержимое заполняемой ячейки
(CELL_FIELD row col tblobj)
; Записываем в ячейку строку-формулу
(vla-SetText tblobj row col cellset)
(setq row nil)
(setq col nil)
(setq tblobj nil)
) ; end of defun

;________________________________________________________________________________

(defun C:PCMA ( / cellset)
; Функция "домножает" указанную ячейку таблицы на выбранные
(vl-load-com)
(setq pt nil)
(setq cellset "=")
(setq findedcell nil)
(setq row nil)
(setq col nil)
(setq row1 nil)
(setq col1 nil)
(setq tblobj nil)
(setq tblobj1 nil)
(setq field_string nil)
; Запрашиваем точку внутри ячейки которую домножаем
(setq pt (getpoint "\n Укажите ячейку таблицы, которую нужно домножить:"))
; получаем row и col в буквенном формате а также указатель на таблицу tblobj
(GET_CELL_ID pt)
(setq tblobj1 tblobj)
(setq row1 row)
(setq col1 col)
(setq row nil)
(setq col nil)
(setq tblobj nil)
; получаем содержимое заполняемой ячейки
(setq field_string "")
(CELL_FIELD row1 col1 tblobj1)
; Запрашиваем ячейки, на которые домножаем
(while
		(setq pt (getpoint "\n Укажите ячейки таблицы, на которые нужно домножить:")) 
		(GET_CELL_ID pt)
		(setq cellset (strcat cellset findedcell "*" ))
		(setq findedcell nil)
) ; end of while
; собираем новый текст
(setq txtnew (strcat cellset "(" field_string ")"))

(vla-SetText tblobj1 row1 col1 txtnew)
(setq row1 nil)
(setq col1 nil)
(setq tblobj1 nil)
(setq row nil)
(setq col nil)
(setq tblobj nil)
) ; end of defun

; Ниже приведены вспомогательные функции
;________________________________________________________________________________

; Функция получения objectID
; Источник: https://discussion.autodesk.com/forums/message.jspa?messageID=6172961
(defun Get-ObjectID-x86-x64 (obj / util)
	(setq util (vla-get-Utility (vla-get-activedocument (vlax-get-acad-object))))
	(if	(= (type obj) 'ENAME)(setq obj (vlax-ename->vla-object obj)))
		(if	(= (type obj) 'VLA-OBJECT)
     		(if	(> (vl-string-search "x64" (getvar "platform")) 0)
			(vlax-invoke-method util "GetObjectIdString" obj :vlax-False)
			(rtos (vla-get-objectid obj) 2 0)
		)
	)
)

;________________________________________________________________________________

; Функция преобразования кода ячейки таблицы к строковому формату
; Terry Miller (Email: [email protected])
(defun Number2Alpha (Num# / Val#)
	(if (< Num# 27)
		(chr (+ 64 Num#))
		(if (= 0 (setq Val# (rem Num# 26)))
			(strcat (Number2Alpha (1- (/ Num# 26))) "Z")
			(strcat (Number2Alpha (/ Num# 26)) (chr (+ 64 Val#)))
		);if
	);if
)

;________________________________________________________________________________

; Функция определения кода ячейки
; VVA forum.dwg.ru
(defun GET_CELL_ID (pt)
(if	
	(and
		(setq tblobj nil
			tblset nil
			tblset (ssget "_X" '((0 . "ACAD_TABLE")))
		) ;_ end of setq
		(setq lst
			(mapcar 'vlax-ename->vla-object
				(vl-remove-if 'listp (mapcar 'cadr (ssnamex tblset)))
			) ;_ end of mapcar
		) ;_ end of setq
		(mapcar
			'(lambda (x)
				(or tblobj
					(and
						(= :vlax-true
							(vla-HitTest
								x
								(vlax-3d-point (trans pt 1 0))
								(vlax-3d-point (trans (getvar "VIEWDIR") 1 0))
								'row
								'col
							) ;_ end of vla-HitTest
		   				) ;_ end of =
		   				(setq tblobj x)
					) ;_ end of and
				) ;_ end of or
			) ;_ end of lambda
			lst
		) ;_ end of mapcar
		tblobj
		row
		col
	) ;_ end of and
	; конвертируем числовой формат кода ячейки в буквенный
	(setq findedcell (strcat (vl-princ-to-string (Number2Alpha (1+ col)))(vl-princ-to-string (1+ row))))
	(alert "Мимо!")
) ; end of if
)

;________________________________________________________________________________

; Функция получения значения ячейки или значения ее поля
; koMon  forum.dwg.ru
(defun CELL_FIELD (#row #col #tbl / fieldlen field_id)
; определяем id поля в выбранной ячейке #row #col таблицы #tbl
(setq field_id (vla-getfieldid #tbl #row #col))
; если field_id=0 (содержимое не поле, то читаем текст, иначе читаем поле
(if (= 0 field_id)
(setq field_string (vla-getText #tbl #row #col))
(progn
(setq field_string 
	(cdr 
		(assoc 2 
			(entget 
				(cdr 
					(assoc 360 
						(entget 
							(vlax-vla-object->ename
								(vla-objectidtoobject
									(vla-get-activedocument (vlax-get-acad-object))
								field_id)
							)
						)
					)
				)
			)
		)
	)
) ; end of seq
(setq fieldlen (strlen field_string))
(setq fieldlen (- fieldlen 8))
; удаляем лишние символы
(setq field_string (substr field_string 9 fieldlen))
) ; end progn
) ; end if
) ; end defun
Вспомогательные функции брал с этого форума.
Lisp работает на стандартный таблицах автокада и добавляет 4 функции
PCS - при запуске просит "пощелкать" по ячейкам, которые мы хотим сложить, затем enter и выбираем, в какую ячейку вписать "формулу". При этом значение ячейки переписывается на "формулу"
PCSA - при запуске просит выбрать ячейку, к которой мы хотим добавить. Затем "щелкаем по ячейкам которые добавляем. При этом значение выбранной вначале ячейки увеличивается на "формулу".
Аналогично
PCM - перемножение ячеек
PCMA - домножение содержимого.
При запуске рекомендую выключать объектные привязки
Вспомогательная функция Get-ObjectID-x86-x64 лежит тут для светлого будущего, когда ячейки лежат в разных таблицах.
Жду критики и советов.
Спасибо всем, кто был активен в данной теме!

Вложения
Тип файла: lsp PUT_CELL_SUM(MULT).lsp (8.2 Кб, 17 просмотров)


Последний раз редактировалось tsetse, 12.12.2018 в 18:28. Причина: Добавил результат
Просмотров: 8138
 
Непрочитано 11.12.2018, 23:33
#2
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


Формула - это же поле.
Сергей812 вне форума  
 
Автор темы   Непрочитано 11.12.2018, 23:52
#3
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Формула - это же поле.
Я попробую через филд, но боюсь это не поможет мне. Немного уточню задачу. В итоге в ячейке A5 должна быть формула = A3*(A3+A4). Но это пример, на практике будет сложнее
tsetse вне форума  
 
Непрочитано 12.12.2018, 00:29
#4
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


Ну я вижу для формулы С2=А2+B2 поле "%<\AcExpr (A2+B2)>%". Соответственно, в вашем варианте тогда будет "%<\AcExpr (А3*(A3+А4))>%"
Сергей812 вне форума  
 
Автор темы   Непрочитано 12.12.2018, 00:42
#5
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Ну я вижу для формулы С2=А2+B2 поле "%<\AcExpr (A2+B2)>%". Соответственно, в вашем варианте тогда будет "%<\AcExpr (А3*(A3+А4))>%"
Я, наверное, не слишком точно объясняю суть проблемы. Представьте, что вы не знаете, что в вашей ячейке С2 формула =А2+B2. Вы хотите домножить ячейку С2 на А1, допустим. Соответственно, вначале нужно как-то "прочитать", что в С2 формула А2+B2. Затем записать эту формулу в какую-либо переменную например
Код:
Потом объединить строки как-то так
Код:
[Выделить все]
 (setq newcelltext (strcat "=" "(" celltext ")" "*" "A1"  ))
Затем вписать новую формулу в старую ячейку
Код:
[Выделить все]
 (vla-SetText tbl row col  newcelltext)
В этом и основной вопрос, как выяснить, что в известной ячейке написана формула А2+B2.
Спасибо, за помощь!
Во вложениях в качестве примера таблица с ячейкой в которой есть формула, и то, как я вижу значения ячейки с формулой
Миниатюры
Нажмите на изображение для увеличения
Название: Снимок1.PNG
Просмотров: 49
Размер:	10.4 Кб
ID:	208961  Нажмите на изображение для увеличения
Название: Снимок2.PNG
Просмотров: 57
Размер:	46.9 Кб
ID:	208962  

Последний раз редактировалось tsetse, 12.12.2018 в 00:48. Причина: добавил вложения
tsetse вне форума  
 
Непрочитано 12.12.2018, 00:52
#6
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


Цитата:
Сообщение от tsetse Посмотреть сообщение
(vla-SetText tbl row col newcelltext)
ну формулу как поле вставлять надо.
Сергей812 вне форума  
 
Автор темы   Непрочитано 12.12.2018, 00:55
#7
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
ну формулу как поле вставлять надо.
Мне нужно взять существующую формулу в таблице, отредактировать ее в лисп (дополнить) и вставить назад. В этом и вопрос, как прочитать существующую, а не как записать новую формулу.
tsetse вне форума  
 
Непрочитано 12.12.2018, 00:57
#8
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


Ну на втором вложении вижу "внешнюю" ссылку на ячейку А5 таблицы с Id 61614...

----- добавлено через ~4 мин. -----
Цитата:
Сообщение от tsetse Посмотреть сообщение
Мне нужно взять существующую формулу в таблице, отредактировать ее в лисп (дополнить) и вставить назад. В этом и вопрос, как прочитать существующую, а не как записать новую формулу.
так если взять как поле, распарсить до значения формулы (A1+B1), собрать новое значение выражения "%<\AcExpr (новая формула на основе старой)>% и вставить обратно как поле?
Сергей812 вне форума  
 
Автор темы   Непрочитано 12.12.2018, 01:01
#9
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Ну на втором вложении вижу "внешнюю" ссылку на ячейку А5 таблицы с Id 61614...
Так вот, в ячейке А5 вписана формула. Предположим мы не знаем эту формулу. Как ее узнать?
tsetse вне форума  
 
Непрочитано 12.12.2018, 01:04
#10
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


Ну судя по всему формула - это что расположено между первой и последней полукруглыми скобками в поле "%<\AcExpr (A2+B2)>%
Сергей812 вне форума  
 
Автор темы   Непрочитано 12.12.2018, 01:04
#11
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Ну на втором вложении вижу "внешнюю" ссылку на ячейку А5 таблицы с Id 61614...

----- добавлено через ~4 мин. -----

так если взять как поле, распарсить до значения формулы (A1+B1), собрать новое значение выражения "%<\AcExpr (новая формула на основе старой)>% и вставить обратно как поле?
Вот я и спрашиваю, как расковырять до формулы (а не значения формулы !). Новые поля я собирать научился благодаря этому форуму).
tsetse вне форума  
 
Непрочитано 12.12.2018, 01:13
#12
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


по ссылке из поста №1 получаем поле из ячейки в виде строки, далее через vl-string-position ищите первую и последнюю скобку, и по полученным значениям индексов функцией substr получаете саму формулу
Сергей812 вне форума  
 
Автор темы   Непрочитано 12.12.2018, 01:27
#13
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
по ссылке из поста №1 получаем поле из ячейки в виде строки, далее через vl-string-position ищите первую и последнюю скобку, и по полученным значениям индексов функцией substr получаете саму формулу
Вот, что я получил с использованием команды PFLD. Правда на моем автокаде vla-get-objectid не работает, использовал лисп Get-ObjectID-x86-x64 предложенный Александром Ривилисом. В результате
%<\AcExpr (Table(%<\_ObjId 616148048>%).A5)>%
И что с этим делать? как понять, что в ячейке А5 забита формула и как узнать эту формулу?
tsetse вне форума  
 
Непрочитано 12.12.2018, 01:45
#14
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


все проще) надо использовать vla-FileldCode
Сергей812 вне форума  
 
Автор темы   Непрочитано 12.12.2018, 01:49
#15
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
все проще) надо использовать vla-FileldCode
У Вас нет примеров, с использованием данного метода?

Код:
[Выделить все]
 (vla-fieldcode (vlax-ename->vla-object (car (entsel))))
Вот, что я получил "%<\\AcExpr (Table(%<\\_ObjId 616148048>%).A5)>%"

Последний раз редактировалось tsetse, 12.12.2018 в 02:03. Причина: добавил результаты
tsetse вне форума  
 
Непрочитано 12.12.2018, 02:00
#16
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,041


Пример от Алексея Кулика.
Сергей812 вне форума  
 
Автор темы   Непрочитано 12.12.2018, 02:12
#17
tsetse

Инженер-конструктор
 
Регистрация: 25.12.2015
Москва
Сообщений: 77


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
Пример от Алексея Кулика.
В очередной раз я получил %<\AcExpr (Table(%<\_ObjId 616148048>%).A5)>%
Но, в ячейке A5 таблицы у которой ObjId=616148048 вписана формула, а именно А2+А3.
Пока все рассмотренные варианты не позволяют достать эту несчастную строку "=А2+А3"
Вопрос не в том, как вписать в какой нибудь текст значение ячейки полем.
Задача иная - как вытащить из ячейки таблицы в которой вписана формула (не поле! а формула!) текстовую запись этой формулы (а не ее значение!) например в нашем случае "=А2+А3"
tsetse вне форума  
 
Непрочитано 12.12.2018, 06:55
#18
Boxa

КЖ; C#
 
Регистрация: 03.11.2005
Санкт-Петербург
Сообщений: 2,588


tsetse, Вы бы воспользовались утилитой ARXDBG и все для Вас стало бы проще...
Если выбрать таблицу и посмотреть ее dxf , то для ячейки с полем, в коде 344 можно увидеть ссылку на некий объект, если этот объект выбрать, то в dxf коде 2 лежит собственно формула.
Boxa вне форума  
 
Непрочитано 12.12.2018, 07:32
#19
trir


 
Регистрация: 18.12.2010
Сообщений: 5,057


autolisp-regexp
trir вне форума  
 
Непрочитано 12.12.2018, 07:52
#20
Кулик Алексей aka kpblc
Moderator

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


trir, частенько обычного wcmatch достаточно.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Достать "формулу" из ячейки таблицы autocad

Размещение рекламы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Создание поля (field), ссылающегося на текстовое значение ячейки таблицы. skkkk Готовые программы 141 24.11.2023 15:49
Перенести данные с таблицы AutoCad в Eccess Jeneva AutoCAD 2 23.06.2017 10:11
В ячейке одной таблицы есть текст, как сделать чтоб этот текст отображался в ячейки другой таблицы? Basily AutoCAD 2 05.02.2017 16:46
Как программно узнать координаты ячейки таблицы (для LISP)? kp+ LISP 0 15.02.2016 11:41
Блокирование высоты ячейки таблицы Autocad casaatik AutoCAD 3 15.09.2011 15:40