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

Вернуться   Форум 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. Причина: Добавил результат
Просмотров: 8041
 
Непрочитано 11.12.2018, 23:33
#2
Сергей812


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


Формула - это же поле.
Сергей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,004


Ну я вижу для формулы С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
Просмотров: 47
Размер:	10.4 Кб
ID:	208961  Нажмите на изображение для увеличения
Название: Снимок2.PNG
Просмотров: 55
Размер:	46.9 Кб
ID:	208962  

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


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


Цитата:
Сообщение от 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,004


Ну на втором вложении вижу "внешнюю" ссылку на ячейку А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,004


Ну судя по всему формула - это что расположено между первой и последней полукруглыми скобками в поле "%<\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,004


по ссылке из поста №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,004


все проще) надо использовать 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,004


Пример от Алексея Кулика.
Сергей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,047


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

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


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