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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Готовые программы > LISP. Создание поля (field), ссылающегося на текстовое значение ячейки таблицы.

LISP. Создание поля (field), ссылающегося на текстовое значение ячейки таблицы.

Ответ
Поиск в этой теме
Непрочитано 01.08.2013, 12:14 6 |
LISP. Создание поля (field), ссылающегося на текстовое значение ячейки таблицы.
skkkk
 
Регистрация: 20.03.2008
Сообщений: 2,653

По многочисленным просьбам трудящихся форумчан и не только их. Возник этот вопрос довольно давно.
Может ли поле принимать текстовое значение ячейки таблицы?
Возможно ли выцепить текст у таблиц? Как это можно реализовать на AutoLISP?
Как вставить полем содержимое ячейки таблицы?
Как должно быть многим известно, в AutoCAD'е не предусмотрена возможность сослаться полем на ТЕКСТОВУЮ ячейку таблицы.
Попытаемся исправить это, на мой взгляд, досадное недоразумение.
Предлагается для обсуждения и тестирования код, который содержит в себе функции из перечисленных выше тем, несколько переработанные и собранные в одну, то есть, в две команды. Отдельное спасибо VVA за весомую помощь в реализации идеи.

Доступные команды:
- TextCellField (или TCF) - создание поля, ссылающегося на указанную ячейку таблицы (текстовую или числовую);
- UpdateTextCellFields (или UTCF) - обновление всех созданных командой TextCellField полей после редактирования исходных ячеек с последующей регенерацией. Как вариант, эту команду можно повесить вместо привычной регенерации. Если полей, созданных командой TextCellField в чертеже нет, то просто произойдет регенерация.

Входящие параметры:
У пользователя запрашивается две точки: первая - внутри ячейки таблицы, на которую нужно сослаться полем, вторая - точка вставки текстового объекта с полем.

Алгоритм:
После указания пользователем двух точек из указанной ячейки (1-я точка) берется содержимое и очищается от форматирования. В Свойствах чертежа (команда _dwgprops), во вкладке Прочее (Custom) создается свойство с именем следующего формата:
Код:
[Выделить все]
Table<handle таблицы>_<адрес ячейки>
Значение этого свойства заполняется строкой, взятой из ячейки, которая может иметь как текстовый, так и числовой формат. Во второй указанной точке создается поле, источником информации для которого служит только что созданное свойство чертежа (значение этого поля становится равным значению ячейки таблицы). Если ячейка пуста, то полю присвоится значение "----".
После того, как пользователь изменит значение в исходной ячейке таблицы, необходимо запустить команду UpdateTextCellFields. Она "пройдется" по всем созданным командой TextCellField свойствам чертежа и назначит каждому актуальное значение "своей" ячейки, затем выполнит регенерацию, присвоив полям новые (если они изменились) значения свойств чертежа. При удалении строк или столбцов из таблицы поле будет продолжать ссылаться на абсолютный адрес ячейки, т.е. если пользователь, например, сослался полем на ячейку A2, а затем удалил вторую строку таблицы, то поле начнет ссылаться на ту ячейку, адрес которой стал A2 (бывший A3). Если ячейка (или вся таблица), на которую ссылались поля, перестала существовать, то свойство чертежа, оставшееся без "своей" ячейки, будет удалено из списка Custom-свойств, и на экран выведется сообщение о количестве недостающих ячеек; "осиротевшие" поля "попадут за решетку". Поэтому удалять строки и столбцы, впрочем как и в случае с "родными" полями, надо осторожно, с головой.


Результат:
Результатом работы лиспа является объект MTEXT, содержащий в себе искомое поле. После двойного щелчка по этому тексту можно скопировать и вставить поле в нужное место. Можно было бы и сразу занести его в буфер обмена, но я пока не знаю, как. Да и вообще, код еще очень далек от совершенства, это пока, так скажем, бета-версия.


Перспективы развития:
- добавить обработку ошибок;
- добавить возможность копирования поля сразу в буфер обмена;
- добавить возможность вставки поля сразу в другую ячейку (другой) таблицы, либо в существующий текст или атрибут, в зависимости от того, куда ткнет мышью пользователь;
- повесить на курсор фантом - "висящий" на курсоре объект для вставки (это, похоже, взаимоисключает предыдущий пункт);
- создать реактор на событие - редактирование ячейки, который запустит процедуру UpdateTextCellFields
- ........


Используемые в коде функции и их авторы:

Используемые в академическом плане:
insfld Кулик Алексей aka kpblc
get_cell_value VVA
и некоторые другие из ссылок в начале сообщения.

Библиотечные:
_dwgru-dwgprops-get-all-prop VVA
_dwgru-dwgprops-get-custom-prop VVA
_dwgru-dwgprops-set-custom-prop VVA
_dwgru-assoc-multi VVA
_dwgru-assoc VVA
_dwgru-string-some-part ShaggyDoc
_dwgru-str->list Елпанов Евгений
dwgru-string-to-list ShaggyDoc
dwgru-string-right-part ShaggyDoc
dwgru-string-left-part ShaggyDoc
LM:UnFormat Lee Mac
Number2Alpha Gilles Chanteau
Alpha2Number Gilles Chanteau

Выражаю свои глубочайшие признательность и благодарность Авторам. Если ошибся в авторстве, прошу простить и поправить.
Все необходимые функции включены в листинг.
______________________________________________
Обновление 07/08/2013
Теперь поле вставляется туда, куда укажет пользователь: это может быть ячейка таблицы, текст, мтекст, мультивыноска. Если пользователь укажет на пустое место или на ту часть чертежа, где нет текстовых объектов, то создастся новый мтекст с полем.
Код:
[Выделить все]
 ;;--------------------------------------------------------
;;Команда cоздает поле (field), ссылающееся на текстовое значение ячейки таблицы.
;; Работает в связке с командой UpdateTextCellFields (см.ниже) 
;; Подробности на http://forum.dwg.ru/showthread.php?p=1130077#post1130077
;; Описание используемых функций
;; get_cell_by_pick
;; get_cell_value
;; _dwgru-dwgprops-get-all-prop
;; _dwgru-dwgprops-get-custom-prop
;; _dwgru-dwgprops-set-custom-prop
;; _dwgru-assoc-multi
;; _dwgru-assoc
;; _dwgru-string-some-part
;; _dwgru-str->list
;; dwgru-string-to-list
;; dwgru-string-right-part
;; dwgru-string-left-part
;; LM:UnFormat
;; Number2Alpha
;; Alpha2Number
(defun C:TCF nil (C:TextCellField))
(defun C:TextCellField ( / *error* adoc oldOSMODE pt pt2 str TextHeight ColumnWidth txtobj tblobj tblset lst row col TargetObj)
(vl-load-com)
	(defun *error* (msg)
		(if oldOSMODE (setvar "OSMODE" oldOSMODE))
		(vla-EndUndomark adoc)
		(princ)
	) ;defun *error*
	(vla-StartUndomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
	(setq oldOSMODE (getvar "OSMODE"))
	(while (null row)
		(setvar "OSMODE" 0)
		(if (null pt)(setq pt (getpoint "\nВыберите ячейку таблицы <Отмена>:")))
		(setvar "OSMODE" oldOSMODE)
		(if (null pt) (progn (princ "\nОтменено пользователем") (exit)))
		(if (get_cell_by_pick pt)
			(progn
				(setvar "OSMODE" 0)
				(if (null pt2) (setq pt2 (getpoint "\nУкажите точку, ячейку или текстовый объект для вставки поля <Отмена> : ")))
				(setvar "OSMODE" oldOSMODE)
				(if (null pt2) (progn (princ "\nОтменено пользователем") (exit)))
				(_dwgru-dwgprops-set-custom-prop 
					(strcat "Table" 
							(vla-get-Handle tblobj)
							"_" 
							(vl-princ-to-string (Number2Alpha (1+ col)))
							(vl-princ-to-string (1+ row))
					) ;_ end of strcat
					(LM:UnFormat (vla-GetText tblobj row col) nil)
					nil
				);_ end of (_dwgru-dwgprops-set-custom-prop)
				(setq str
					(strcat "%<\\AcVar CustomDP.Table" 
							(vl-princ-to-string (vla-get-Handle tblobj))
							"_"
							(vl-princ-to-string (Number2Alpha (1+ col)))
							(vl-princ-to-string (1+ row))
							">%"
					) ;_ end of strcat
				) ;_ end of setq str
				(setq TextHeight (vla-GetCellTextHeight tblobj row col))
				(setq ColumnWidth (vla-GetColumnWidth tblobj col))
				(cond
					(	(get_cell_by_pick pt2) ;_cond #1
						(if (eq (vla-IsContentEditable tblobj row col) :vlax-true)
							(progn
								(vla-SetText tblobj row col str)
								(vla-SetCellTextHeight tblobj row col TextHeight)
							) ;_ end of progn
							(progn
								(princ "\nСодержимое ячейки заблокировано")
							) ;_ end of progn
						) ;_ end of if
					) ;_end of cond #1
					(	(null (ssget "_C" (polar pt2 (/ pi 4) 3) (polar pt2 (/ (* 5 pi) 4) 3) '((0 . "*TEXT,ATTRIB,ATTDEF,MULTILEADER")))) ;_cond #2
						(progn
							(setq txtobj
								(vla-addMtext
									(vla-get-ModelSpace adoc) 
									(vlax-3d-point (trans pt2 1 0))
									ColumnWidth
									str
								) ;_ end of vla-addtext
							) ;_ end of setq txtobj
							(vla-put-Height txtobj TextHeight)
						) ;_ end of progn
					) ;_end of cond #2
					(	(setq ss (ssget "_C" (polar pt2 (/ pi 4) 3) (polar pt2 (/ (* 5 pi) 4) 3) '((0 . "TEXT")))) ;_cond #3
						(progn
							(setq TargetObj (vlax-ename->vla-object (ssname ss 0)))
							(vla-put-TextString TargetObj str)
						) ;_ end of progn
					) ;_end of cond #3
					(	(setq ss (ssget "_C" (polar pt2 (/ pi 4) 3) (polar pt2 (/ (* 5 pi) 4) 3) '((0 . "MTEXT")))) ;_cond #4
						(progn
							(setq TargetObj (vlax-ename->vla-object (ssname ss 0)))
							(vla-put-TextString TargetObj "-")
							(vla-put-TextString TargetObj str)
						) ;_ end of progn
					) ;_end of cond #4
					(	(setq ss (ssget "_C" (polar pt2 (/ pi 4) 3) (polar pt2 (/ (* 5 pi) 4) 3) '((0 . "MULTILEADER")))) ;_cond #5
						(progn
							(setq TargetObj (vlax-ename->vla-object (ssname ss 0)))
							(vla-put-TextString TargetObj (strcat "\\pxse0.76;" str))
							(command "_.UPDATEFIELD" ss "")
							(setq jstf (vla-get-TextJustify TargetObj))
							(vla-put-TextJustify TargetObj 1)
							(vla-put-TextJustify TargetObj jstf)
						) ;_ end of progn
					) ;_end of cond #5
				) ;_ end of cond
			) ;_ end of progn
			(progn
				(setvar "OSMODE" 0)
				(setq pt (getpoint "\nЭто не таблица!\nВыберите ячейку таблицы <Отмена>:"))
				(setvar "OSMODE" oldOSMODE)
				(setq row nil)
				(if (null pt) (progn (princ "\nОтменено пользователем") (exit)))
			) ;_ end of progn
		) ;_ end of if
	) ;_ end of while
	(vla-EndUndomark adoc)
	(princ)
) ;_ end of defun C:TextCellField


;;--------------------------------------------------------
;; Команда обновляет свойства чертежа (dwgprops) и поля, созданные 
;; командой TextCellField (см. выше) в соответствии с содержимым ячейки таблицы
(defun C:UTCF nil (C:UpdateTextCellFields))
(defun C:UpdateTextCellFields ( / adoc DWGPROP n tblobj ExcellColumn row col)
	(setq adoc (vla-get-activedocument (vlax-get-acad-object)))
	(setq DWGPROP (_dwgru-dwgprops-get-all-prop nil))
	(setq n 0)
	(foreach item DWGPROP
		(cond 
			(	(wcmatch (car item) "Table*")
				(progn
					(setq tblobj (vlax-ename->vla-object (handent (substr (dwgru-string-left-part (car item) "_") 6))))
					(setq ExcellColumn (dwgru-string-right-part (car item) "_"))
					(setq row (cadr (_dwgru-str->list ExcellColumn)))
					(setq col (Alpha2Number (car (_dwgru-str->list ExcellColumn))))
					(if (and tblobj (>= (vla-get-columns tblobj) col) (>= (vla-get-rows tblobj) row))
						(progn
							(_dwgru-dwgprops-set-custom-prop 
								(car item) 
								(get_cell_value tblobj ExcellColumn)
								nil_
							)
						) ;_ end of progn
						(progn
							(vla-RemoveCustomByKey (vla-Get-SummaryInfo adoc) (car item))
							(setq n (1+ n))
						) ;_ end of progn
					) ;_ end of if
				) ;_ end of progn
			)
		) ;_ end of cond
	) ;_ end of foreach
	(if (> n 0) (alert (strcat "Количество удаленных ячеек, на которые ссылались поля: " (vl-princ-to-string n))))
	(vla-regen adoc AcAllViewports)
	(princ)
) ;_ end of defun C:UpdateTextCellFields


;;--------------------------------------------------------
;; Функция получает ячейку таблицы по указанной точке
;; Если точка внутри таблицы, возвращает список вида (<vla-объект таблицы> <номер строки> <номер столбца>)
;; если вне таблицы - возвращает nil
(defun get_cell_by_pick (pt / )
				(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
				(if (and tblobj row col) (list tblobj row col) nil)
) ;_ end of defun (get_cell_by_pick)


;;--------------------------------------------------------
;; Функция получает строку - значение ячейки таблицы
(defun get_cell_value (tblobj ExcellColumn /)
;;; tblobj - vla-object 
;;; ExcellColumn - string - "A1" B2"
;;; Use
;;; (get_cell_value (vlax-ename->vla-object(car(entsel))) "A2")
	(apply
		'(lambda (col row)
			(LM:UnFormat (vla-GetText tblobj (1- row) (1-(Alpha2Number  col))) nil)
		)
		(_dwgru-str->list (strcase ExcellColumn))
	)
) ;_ end of defun get_cell_value


;;; ************************************************************************
;;; * Библиотека DWGruLispLib Copyright ©2007  DWGru Programmers Group
;;; *
;;; * _dwgru-dwgprops-get-all-prop
;;; *
;;; * 23/07/2008 Версия 0002. Makswell
;;; * 27/12/2007 Версия 0001.  Владимир Азарко   (VVA)
;;; ************************************************************************
(defun _dwgru-dwgprops-get-all-prop (Doc / si ret nc key value)
;;; Возвращает свойства файла, установленные командой _dwgprops
;;; Возвращается ассоциативный список, где ключом служит:
;;;      - для свойств, созданных пользователем (закладка ПРОЧИЕ)
;;;          ИМЯ СВОЙСТВА
;;;     - для стандартных свойств (закладка ДОКУМЕНТ)
;;;             Поле                  Ключ  
;;;             НАЗВАНИЕ           - *TITLE*
;;;             АВТОР              - *AUTHOR*
;;;             ТЕМА               - *SUBJECT*
;;;             КЛЮЧЕВЫЕ СЛОВА     - *KEYWORDS*
;;;             ЗАМЕТКИ            - *COMMENTS*
;;;             БАЗА ГИПЕРССЫЛКИ   - *HYPERLINK*
;;; Doc - указатель на обрабатываемый документ, nil - текущий

  ;|
;;; Пример
(_dwgru-dwgprops-get-all-prop nil) ;;;(("*AUTHOR*" "VVA") ("*COMMENTS*" "Заметка") ("*HYPERLINK*" "База")
                               ;;;("*KEYWORDS*" "Ключ") ("*TITLE*" "Назван") ("*SUBJECT*" "Тема") ("UNIQKEY" "Key"))
|;
  (and
    (or	Doc
	(setq Doc (vla-get-activeDocument (vlax-get-acad-object)))
    )
    (setq si (vla-get-SummaryInfo Doc))
    (setq ret (list
		(list "*AUTHOR*" (vla-get-author si))
		(list "*COMMENTS*" (vla-get-comments si))
		(list "*HYPERLINK*" (vla-get-HyperlinkBase si))
		(list "*KEYWORDS*" (vla-get-keywords si))
		(list "*TITLE*" (vla-get-Title si))
		(list "*SUBJECT*" (vla-get-Subject si))
	      )
    )
    (setq nc (vla-numcustominfo si))
    (while (> nc 0)
      (vla-GetCustomByIndex si (- nc 1) 'key 'value)
      (setq ret (append ret (list (list key value))))
      (setq nc (1- nc))
    )
    (vlax-release-object si)
  )
  ret
) ;_end of defun (_dwgru-dwgprops-get-all-prop)


;;; ************************************************************************
;;; * Библиотека DWGruLispLib Copyright ©2007  DWGru Programmers Group
;;; *
;;; * _dwgru-dwgprops-get-custom-prop
;;; *
;;; * 27/12/2007 Версия 0001.  Владимир Азарко   (VVA)
;;; ************************************************************************
(defun _dwgru-dwgprops-get-custom-prop (key Doc / app counter counter2 counter3 doc dwgprops k v)
;;; Возвращает значение свойства, созданного пользователем (команда _dwgprops)
;;; Возвращается ассоциативный список, где ключом служит:
;;;      - для свойств, созданных пользователем (закладка ПРОЧИЕ)
;;;    key - строка ИМЯ СВОЙСТВА (закладка ПРОЧИЕ)
;;;        - для стандартных свойств (закладка ДОКУМЕНТ)
;;;              Поле                  Ключ  
;;;             НАЗВАНИЕ           - *TITLE*
;;;             АВТОР              - *AUTHOR*
;;;             ТЕМА               - *SUBJECT*
;;;             КЛЮЧЕВЫЕ СЛОВА     - *KEYWORDS*
;;;             ЗАМЕТКИ            - *COMMENTS*
;;;             БАЗА ГИПЕРССЫЛКИ   - *HYPERLINK*
;;;
;;; Использует функцию библиотеки
;;;                 _dwgru-dwgprops-get-all-prop
;;;                 _dwgru-assoc  (_dwgru-assoc-multi)
 
;;; Doc - указатель на обрабатываемый документ, nil - текущий
 
 (cadr(_dwgru-assoc key (_dwgru-dwgprops-get-all-prop Doc)))
) ;_end of defun (_dwgru-dwgprops-get-custom-prop)


;;; ************************************************************************
;;; * Библиотека DWGruLispLib Copyright ©2007  DWGru Programmers Group
;;; *
;;; * _dwgru-dwgprops-set-custom-prop
;;; *
;;; * 23/07/2008 Версия 0002. Makswell
;;; * 27/12/2007 Версия 0001.  Владимир Азарко   (VVA)
;;; ************************************************************************
(defun _dwgru-dwgprops-set-custom-prop (key value Doc / si)
;;;Создает в свойствах рисунка (команда _dwgprops закладка ПРОЧИЕ)
;;; Свойство с ключом key и значение value
;;; Если свойства не было, оно создается, иначе изменяется
;;;    key - строка ИМЯ СВОЙСТВА (закладка ПРОЧИЕ)
;;;    value - строка (string) - значение свойства  
;;; Использует функцию библиотеки
;;;                 _dwgru-dwgprops-get-custom-prop
;;; Doc - указатель на обрабатываемый документ, nil - текущий
;;; Возвращает - nil
  ;|
;;;Пример
(_dwgru-dwgprops-set-custom-prop "dwgru" "dwgru-dwgprops-set-custom-prop" nil)
|;
  (or Doc
      (setq Doc (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  )
  (setq si (vla-Get-SummaryInfo Doc))
  (if (_dwgru-dwgprops-get-custom-prop key Doc)
    (progn
      (setq key (car (_dwgru-assoc key (_dwgru-dwgprops-get-all-prop Doc))))
      (vla-SetCustomByKey si key value)
    )
    (vla-AddCustomInfo si key value)
  )
) ;_end of defun (_dwgru-dwgprops-set-custom-prop)


(defun _dwgru-assoc-multi (key lst)
  (if (= (type key) 'str)
    (setq key (strcase key))
    ) ;_ end of if
  (vl-remove-if-not
    (function
      (lambda (a / b)
        (and (setq b (car a))
             (or (and (= (type b) 'str) (= (strcase b) key)) (equal b key))
             ) ;_ end of and
        ) ;_ end of lambda
      ) ;_ end of function
    lst
    ) ;_ end of vl-remove-if-not
) ;_ end of defun (_dwgru-assoc-multi)
(defun _dwgru-assoc (key lst)
  (car (_dwgru-assoc-multi key lst))
) ;_ end of defun (_dwgru-assoc)


;;; ************************************************************************
;;; * Библиотека DWGruLispLib Copyright ©2007  DWGru Programmers Group
;;; *
;;; * _dwgru-string-some-part
;;; *
;;; * 03/12/2007 Версия 0001.  Сергей Зуев   (ShaggyDoc)
;;; ************************************************************************
(defun _dwgru-string-some-part
                              (string delim_char is_left_part / lst)
    ;;;  возврат левой (если is_left_part)или правой части
    ;;;  строки string с разделителем  delim_char
    ;;; Использует функцию библиотеки
    ;;;                 dwgru-string-to-list

    ;;; Параметры: 
    ;;; string     - исходная строка
    ;;; delim_char  - разделитель (string)
    ;;; is_left_part  - T или NIL. Если истина (T), то слева. Иначе справа. (boolean)
    ;;; Возврат:
    ;;;   строку (String)
  
    ;;; Пример:
  ;|
(_dwgru-string-some-part " M1:=100" "=" T) ;_Результат   " M1:"
(_dwgru-string-some-part " M1:=100" "=" NIL)  ;_Результат  "100"
(_dwgru-string-some-part " M= M1:=100" "=" T) ;_ Результат  " M"
(_dwgru-string-some-part " M= M1:=100" "=" NIL) ;_ Результат  "100"
(_dwgru-string-some-part "просто строка" "=" T)  ;_ Результат  "просто строка"
(_dwgru-string-some-part "просто строка" "=" NIL) ;_Результат   ""
|;
	(if (> (length	(setq lst
						(dwgru-string-to-list string delim_char)
					) ;_ end of setq
			) ;_ end of length
			1
		) ;_ end of >
		;; если список, иначе была просто строка
		(if is_left_part (car lst) (last lst))
		(if is_left_part string "")
	) ;_ end of  if
) ;_ end of defun (_dwgru-string-some-part)


;;--------------------------------------------------------
;; Функция разделяет строку на список текстовых и цифровых составляющих.
;; Запятая между цифрами, зменяется на точечный разделитель дробной части.
(defun _dwgru-str->list (s)
                 ;|
***************************************************************************************
*
* Программа разделяет строку на список текстовых и цифровых составляющих.
* Запятая между цифрами, зменяется на точечный разделитель дробной части.
* 
**************************************************************************************
*
* Написал Елпанов Евгений       (ElpanovEvgeniy)
*
* дата создания (13/10/2007 a 11:42)
* написано во время конкурса на форуме:
* http://www.cadxp.com/XForum+viewthread-fid-101-tid-16943-page-2.html
***************************************************************************************
* Пример использования и результатов работы:
* (_dwgru-str->list "point.25.4cm.")           => ("point." 25.4 "cm.")
* (_dwgru-str->list "point.25,4cm.")           => ("point." 25.4 "cm.")
* (_dwgru-str->list "point.3/8cm.")            => ("point." 0.375 "cm.")
* (_dwgru-str->list "qvf12qsdf125 5sf 56dfv2") => ("qvf" 12 "qsdf" 125 " " 5 "sf " 56 "dfv" 2)
***************************************************************************************
 |;
 (defun str->list1 (a b f)
  (cond
   ((null b)
    (list (if f
           (cond ((vl-position 46 a) (atof (vl-list->string (reverse a))))
                 ((vl-position 47 a) (distof (vl-list->string (reverse a))))
                 ((vl-position 44 a) (atof (vl-list->string (subst 46 44 (reverse a)))))
                 (t (atoi (vl-list->string (reverse a))))
           ) ;_ cond
           (vl-list->string (reverse a))
          ) ;_ if
    ) ;_ list
   )
   (f
    (if (or (= (car b) 44) (< 45 (car b) 58))
     (str->list1 (cons (car b) a) (cdr b) f)
     (cons (cond ((vl-position 46 a) (atof (vl-list->string (reverse a))))
                 ((vl-position 47 a) (distof (vl-list->string (reverse a))))
                 ((vl-position 44 a) (atof (vl-list->string (subst 46 44 (reverse a)))))
                 (t (atoi (vl-list->string (reverse a))))
           ) ;_ cond
           (str->list1 (list (car b)) (cdr b) nil)
     ) ;_ cons
    ) ;_ if
   )
   (t
    (if (< 47 (car b) 58)
     (cons (vl-list->string (reverse a)) (str->list1 (list (car b)) (cdr b) t))
     (str->list1 (cons (car b) a) (cdr b) nil)
    ) ;_ if
   )
  ) ;_ cond
 ) ;_ defun
 (setq s (vl-string->list s))
 (str->list1 (list (car s))
             (cdr s)
             (if (or (= (car s) 44) (< 45 (car s) 58))
              t
             ) ;_ if
 )
) ;_ end of defun (_dwgru-str->list)


;;; ************************************************************************
;;; * Библиотека DWGruLispLib Copyright ©2007  DWGru Programmers Group
;;; *
;;; * dwgru-string-to-list
;;; *
;;; * 03/12/2007 Версия 0001.  Сергей Зуев   (ShaggyDoc)
;;; ************************************************************************
(defun dwgru-string-to-list (str delimiter / pos)
;;; Возврат списка подстрок строки str с разделителем  delimiter 
;;; Использует функцию библиотеки
    ;;;                 dwgru-string-replace
    ;;; Параметры: 
    ;;; string     - исходная строка
    ;;; delimiter  - разделитель (string)
    ;;; Возврат:
    ;;;   строку (String)
  
    ;;; Пример:
    ;|
(dwgru-string-to-list "М:1=100" "=") ;_Результат ("М:1" "100")
(dwgru-string-to-list "М:1=" "=") ;_Результат  ("М:1" "")
(dwgru-string-to-list "" "=") ;_Результат  ("")
(dwgru-string-to-list "1 2 3   4   5" " ") ;_Результат  ("1" "2" "3" "4" "5")
 (dwgru-string-to-list "Я говорю, он говорит, они говорят" ",")
 ;_Результат ("Я говорю" " он говорит" " они говорят")
 (dwgru-string-to-list "123456789" "=") ;_Результат  ("123456789") 
|;
  ;;; для варианта, когда разделитель пробел надо
;;; заменить в строке все двойные пробелы на одинарные
    (if (= delimiter (chr 32))
        (setq str (dwgru-string-replace str (strcat (chr 32) (chr 32)) delimiter))
    ) ;_ end of if
    (if (setq pos (vl-string-search delimiter str))
        (cons
            (substr str 1 pos)
            (dwgru-string-to-list
                (substr
                    str
                    (+ (strlen delimiter) pos 1)
                ) ;_ end of substr
                delimiter
            ) ;_ end of ru-string-pl-string-to-list
        ) ;_ end of cons
        (cons str '())
    ) ;_ end of if
) ;_ end of defun (dwgru-string-to-list)


;;; ************************************************************************
;;; * Библиотека DWGruLispLib Copyright ©2007  DWGru Programmers Group
;;; *
;;; * dwgru-string-right-part
;;; *
;;; * 03/12/2007 Версия 0001.  Сергей Зуев   (ShaggyDoc)
;;; ************************************************************************
(defun dwgru-string-right-part (string delim_char)
;;; возврат правой половины строки после разделителя
;;; Использует функцию библиотеки
    ;;;                 _dwgru-string-some-part
    ;;; Параметры: 
    ;;; string     - исходная строка
    ;;; delim_char  - разделитель (string)
    ;;; Возврат:
    ;;;   строку (String)
  
    ;;; Пример:
  
;|
(dwgru-string-right-part " M1:=100" "=")   ;_Результат  "100"
(dwgru-string-right-part " M= M1:=100" "=") ;_Результат  "100"
(dwgru-string-right-part "просто строка" "=") ;_Результат   "просто строка"
(dwgru-string-right-part "просто=" "=")  ;_ ""
(dwgru-string-right-part "890" ".")  ;_Результат  ""
(dwgru-string-right-part ".2" ".")  ;_Результат  2
(dwgru-string-right-part "2" ".")  ;_Результат  "" 
(dwgru-string-right-part "2.400" ".") ;_Результат  "400"
|;
    (_dwgru-string-some-part string delim_char NIL)
) ;_ end of defun (dwgru-string-right-part)


;;; ************************************************************************
;;; * Библиотека DWGruLispLib Copyright ©2007  DWGru Programmers Group
;;; *
;;; * dwgru-string-left-part
;;; *
;;; * 03/12/2007 Версия 0001.  Сергей Зуев   (ShaggyDoc)
;;; ************************************************************************

(defun dwgru-string-left-part (string delim_char)
;;; возврат левой половины строки до разделителя delim_char
;;; Использует функцию библиотеки
    ;;;                 _dwgru-string-some-part

    ;;; Параметры: 
    ;;; string     - исходная строка
    ;;; delim_char  - разделитель (string)
    ;;; Возврат:
    ;;;   строку (String)
  
    ;;; Пример:
;|  
(dwgru-string-left-part " M1:=100" "=")  ;_Результат  " М1:"
(dwgru-string-left-part " M= M1:=100" "=")  ;_Результат  " М"
(dwgru-string-left-part "просто строка" "=") ;_Результат   "просто строка"
(dwgru-string-left-part "просто=" "=")  ;_Результат  "просто"
|;
(_dwgru-string-some-part string delim_char T)
) ;_ end of defun (dwgru-string-left-part)


;;-------------------=={ UnFormat String }==------------------;;
;;                                                            ;;
;;  Returns a string with all MText formatting codes removed. ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  str - String to Process                                   ;;
;;  mtx - MText Flag (T if string is for use in MText)        ;;
;;------------------------------------------------------------;;
;;  Returns:  String with formatting codes removed            ;;
;;------------------------------------------------------------;;

(defun LM:UnFormat ( str mtx / _replace rx )

    (defun _replace ( new old str )
        (vlax-put-property rx 'pattern old)
        (vlax-invoke rx 'replace str new)
    )
    (if (setq rx (vlax-get-or-create-object "VBScript.RegExp"))
        (progn
            (setq str
                (vl-catch-all-apply
                    (function
                        (lambda ( )
                            (vlax-put-property rx 'global     actrue)
                            (vlax-put-property rx 'multiline  actrue)
                            (vlax-put-property rx 'ignorecase acfalse) 
                            (foreach pair
                               '(
                                    ("\032"    . "\\\\\\\\")
                                    (" "       . "\\\\P|\\n|\\t")
                                    ("$1"      . "\\\\(\\\\[ACcFfHLlOopQTW])|\\\\[ACcFfHLlOopQTW][^\\\\;]*;|\\\\[ACcFfHLlOopQTW]")
                                    ("$1$2/$3" . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
                                    ("$1$2"    . "\\\\(\\\\S)|[\\\\](})|}")
                                    ("$1"      . "[\\\\]({)|{")
                                )
                                (setq str (_replace (car pair) (cdr pair) str))
                            )
                            (if mtx
                                (_replace "\\\\" "\032" (_replace "\\$1$2$3" "(\\\\[ACcFfHLlOoPpQSTW])|({)|(})" str))
                                (_replace "\\"   "\032" str)
                            )
                        )
                    )
                )
            )
            (vlax-release-object rx)
            (if (null (vl-catch-all-error-p str))
                str
            )
        )
    )
) ;_end of defun (LM:UnFormat)


(defun Number2Alpha (Num# / Val#)
;-------------------------------------------------------------------------------
; Number2Alpha - Converts Number into Alpha string
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
;   Num# = Number to convert
; Syntax example: (Number2Alpha 731) = "ABC"
;-------------------------------------------------------------------------------
	(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
);defun Number2Alpha


(defun Alpha2Number (Str$ / Num#)
;-------------------------------------------------------------------------------
; Alpha2Number - Converts Alpha string into Number
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
;   Str$ = String to convert
; Syntax example: (Alpha2Number "ABC") = 731
;-------------------------------------------------------------------------------
  (if (= 0 (setq Num# (strlen Str$)))
    0
    (+ (* (- (ascii (strcase (substr Str$ 1 1))) 64) (expt 26 (1- Num#)))
       (Alpha2Number (substr Str$ 2))
    );+
  );if
);defun Alpha2Number
(princ)

Вложения
Тип файла: lsp TextCellField.lsp (25.6 Кб, 1242 просмотров)


Последний раз редактировалось skkkk, 24.05.2018 в 15:21. Причина: Обновление
Просмотров: 125804
 
Непрочитано 23.10.2015, 12:39
#61
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
переписании функции get_cell_by_pick без использования метода HitTest, а также get_cell_value без GetText. Хотя, я сомневаюсь, что это вообще возможно
Да, это не возможно. Эти методы для этого и создавались.

Цитата:
Сообщение от RNB Посмотреть сообщение
И тут уже файл попадает к нам и мы делимся на 2 лагеря:
- у кого нет спдс-модуля - видят прокси-объект
- у кого есть - "Основную надпись".
на 99.99% так и есть
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 23.10.2015, 12:42
#62
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Offtop: RNB, видимо, на том компе, где я тестировал, СПДС все же установлен. Иначе я это объяснить не могу. Владелец им не пользуется (равно как и я, причем из-за таких вот проблем), он специально спросил сисадмина - тот не помнит. Да и в общем-то, не суть.

----- добавлено через ~17 мин. -----
Цитата:
Сообщение от VVA Посмотреть сообщение
Да, это не возможно.
Что и требовалось доказать.
Проверил на своем 2011-м (точно без СПДС) - там эта "недотаблица" (или "пере-"?) видится как прокси, код работает, и при попытке ткнуть в нее код справедливо ругается, что это не таблица.
Так что для работоспособности кода при установленном СПДС встает лишь задача "отфильтровать" такие объекты прежде, чем подсовывать набор HitTest'у. VVA, подскажи, пожалуйста свои мысли, как это можно лучше сделать, учитывая, что они выбираются ssget'ом при фильтре (0 . "ACAD_TABLE")? Создавать набор через vla-методы? Или фильтровать на основе какого-либо свойства из дампа, приведенного мною тремя постами выше?
skkkk вне форума  
 
Непрочитано 23.10.2015, 13:48
#63
allrather


 
Регистрация: 27.02.2011
Минск
Сообщений: 169
Отправить сообщение для allrather с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
В одном из листов дополнительная графа является таблицей СПДС. При ее удалении начинает работать.
Извиняюсь за фейл.

Цитата:
Сообщение от skkkk Посмотреть сообщение
При этом владелец этой машины утверждает, что никакого СПДС он не ставил. Как это проверить? Не мог же он случайно поставиться? Или может, он поставил, да забыл? Мистика...
Ничего подобного я не утверждал.

Меня смутило
Цитата:
Сообщение от skkkk Посмотреть сообщение
в котором судя по всему СПДС уже внедрен в коробку
поэтому я и написал
Цитата:
Сообщение от allrather Посмотреть сообщение
СПДС не внедрен и слава Богу!
потому как не понимаю, как он, вообще, может быть внедрен!

Цитата:
Сообщение от RNB Посмотреть сообщение
Пользователь скопировал у кого-либо форматку. Как она определяется (прокси-объект или "Основная надпись") у этого пользователя мы не знаем (или я пропустил мимо глаз?).
Я осознанно пользуюсь СПДС и стремлюсь отказаться от него!

Цитата:
Сообщение от RNB Посмотреть сообщение
Интересует то, что он хапнул ошибку при выполнении лиспа.
+
allrather вне форума  
 
Автор темы   Непрочитано 23.10.2015, 14:10
#64
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Цитата:
Сообщение от allrather Посмотреть сообщение
Ничего подобного я не утверждал.
Я имел в виду того, на чьей машине с 2015-м Автокадом я проверял работу программы. Это он утверждал. У меня только 2011-й под рукой, и я решил не конвертировать файл в версию 2010, а по удаленке проверить у него. В итоге повезло, что у него стоит-таки СПДС, так как без него TCF работает, и сконвертировав в 2010-ю версию, я бы, наверное, долго у себя еще искал бы причину. В общем, по возможности постараюсь доработать код, надо только понять, как решить вопросы из моего предыдущего поста.
skkkk вне форума  
 
Непрочитано 23.10.2015, 16:32
#65
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
VVA, подскажи, пожалуйста свои мысли, как это можно лучше сделать
Если СПДСовские таблицы так же отбираются как ACAD_TABLE, то добавил фильтрацию по наличию/отсутствию метода 'HitTest
Но нужно проверить на машине с СПДС.
Цитата:
(vlax-method-applicable-p x 'HitTest) ;_Добавил 2015.10.23
Код:
[Выделить все]
;;--------------------------------------------------------
;; Функция получает ячейку таблицы по указанной точке
;; Если точка внутри таблицы, возвращает список вида (<vla-объект таблицы> <номер строки> <номер столбца>)
;; если вне таблицы - возвращает nil
(defun get_cell_by_pick (pt / )
				(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-method-applicable-p x 'HitTest) ;_Добавил 2015.10.23
								(= :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
				(if (and tblobj row col) (list tblobj row col) nil)
) ;_ end of defun (get_cell_by_pick)
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 23.10.2015, 17:41
#66
d.mOnII

Проектирование
 
Регистрация: 22.01.2013
Минск
Сообщений: 123
Отправить сообщение для d.mOnII с помощью Skype™


VVA, есть ли у Вас возможность посодействовать решению этих вопросов, что б не ходить такими долгими путями через промежуточные элементы
Цитата:
Сообщение от d.mOnII Посмотреть сообщение
Вопрос1: как вставлять такое поле в атрибут динамического блока? можноли это реализовать?
Вопрос2: если файл с полями созданными через TCF вставить в другой как внешнюю ссылку - то поля превратятся в решетки, можно ли это исправить? (вопрос, как я понял, задаю уже повторно)

----- добавлено через ~8 мин. -----
пока что решение проблемы можно сделать так: создаем текстовые поля в объектах многострочного текста при исполнении лисп.команды TCF (как промежуточные), а затем в атрибут блока вставляем текстовое поле со значением содержимого промежуточного объекта [многострочный текст, созданный при исполнении лиспа] и на выходе получаем блок с атрибутом и текстовым полем, который в качестве внешней ссылки отображается корректно
d.mOnII вне форума  
 
Непрочитано 25.11.2015, 15:04
#67
valrond


 
Регистрация: 16.10.2013
Сообщений: 19


Потестил на 2015 автокаде, работает. Вопрос. Как бы сделать так, чтобы значение ячейки вставлялось в атрибут блока?
valrond вне форума  
 
Автор темы   Непрочитано 26.11.2015, 10:42
#68
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


d.mOnII, valrond, работаю над этим сейчас, но катастрофически не хватает рук.
VVA, проверил на машине с СПДС - это то, что надо, чтобы отсеять таблицы НЕ Автокада. Внедрю обязательно в следующем выпуске.
Поскольку в то время, когда я собирал с помощью VVA куски кодов со всей Сети, я только начинал вникать в лисп, и объединить все эти коды в один у меня получилось достаточно дилетантским образом. Хотя программа и выполняет поставленные задачи, мне не очень нравится момент, который я придумал тогда. А именно, при запросе второй точки для вставки поля запрашивается именно точка, а не объект. Сейчас это решение мне кажется корявым. С одной стороны я тогда стремился к универсальности: кликнул в пустое место - создался текстовый объект с полем; кликнул на текстовый объект - поле добавилось в него; кликнул в ячейке - и поле там. Но с другой стороны, допустим, если работать в строительных чертежах, где все в мм (я чаще всего работаю на подосновах и там метры), то алгоритм по обработке второго запроса дает сбои. Но эти сбои я уже нашел, как обработать. Поскольку я и коллеги сами этим кодом уже давно не пользуемся ввиду использования более продвинутых технологий под наши нужды, прошу совета пользователей данного лиспа, а также всех у кого есть мысли на этот счет - высказаться на предмет того, стоит ли оставить эту универсальность второго клика или ввести две или три команды: одна будет вставлять на пустом месте, вторая - в таблицу (оба запроса - точки), третья - в текстовый объект, в т.ч атрибут (запрос на выбор объекта), четвертая, например, вставляла бы содержимое поля в буфер обмена, ведь не всегда надо менять все содержимое текстового объекта? Первую со второй, конечно, можно объединить, но тогда несколько нарушается логичность интерфейса. Есть еще третий вариант, тоже универсальный, в противопоставление первому: ультимативно при запросе второй точки или объекта вместо перекрестья - прямоугольник выбора - и при указании на пустое место или ячейку таблицы обработать это тоже достаточно просто.

На днях попытался обработать атрибуты своим корявым, но универсальным методом вставки поля в текстовый объект, но код не заработал. Кто сможет объяснить, почему конструкция
Код:
[Выделить все]
 ;_cond #2: при указании второй точки под курсором объект "ATTRIB"
  (	(and ;если под точкой в прямоугольнике с диагональю 6мм есть блок и он один
		(setq ss (ssget "_C" (polar pt2 (/ pi 4) 3) (polar pt2 (/ (* 5 pi) 4) 3) '((0 . "INSERT")))) 
		(= 1 (sslength ss))
		(setq vla-block-ref (vlax-ename->vla-object (ssname ss 0))
			  ins-pt (cdr (assoc 10 (entget (ssname ss 0))))
		)
	)
	(mapcar ;то щупаем, на какой  объект мы указали
		(function ;и если это атрибут, назначаем ему строку с полем
			(lambda (x) 
				(if (wcmatch (cdr (assoc 0 (entget (vlax-vla-object->ename x)))) "ATTRIB")
					(progn
						(vla-GetBoundingBox x 'MinP 'MaxP)
						(setq MinP (vlax-safearray->list MinP)
							  MaxP (vlax-safearray->list MaxP)
							  p1 (polar ins-pt (angle '(0.0 0.0 0.0) MinP) (distance '(0.0 0.0 0.0) MinP))
							  p3 (polar ins-pt (angle '(0.0 0.0 0.0) MaxP) (distance '(0.0 0.0 0.0) MaxP))
							  p2 (list (car p1) (cadr p3) 0.0)
							  p4 (list (car p3) (cadr p1) 0.0)
							  pt-list (list p1 p2 p3 p4)
						)
						(if (IsPtInside pt2 pt-list)(setq TargetObj x))
					)
				)
			)
		) 
		(get-block-entity-list vla-block-ref)
	)
	
	
	(vla-put-TextString TargetObj "-")
	(vla-put-TextString TargetObj str)
  ) ;_end of cond #2

- не срабатывает с атрибутами (комментарии в коде)? Если вместо атрибута там текст или мтекст - все в порядке, а с атрибутом - ни в какую! Пытался также с "ATTDEF" - результата нет. Поскольку основные использованные функции тут от Kpblc'а и VVA, то с вас основной спрос .
skkkk вне форума  
 
Непрочитано 26.11.2015, 11:30
#69
d.mOnII

Проектирование
 
Регистрация: 22.01.2013
Минск
Сообщений: 123
Отправить сообщение для d.mOnII с помощью Skype™


если интересно и возможно реализовать, то как и в каде можно сделать:
вводится одна команда на создание поля
первое действие - выбираем объект из которого берем информацию (текст, ячейка таблицы и т.д.)
второе действие - по умолчанию ставится новый текст с полем, но есть возможность выбора (стрелками вверх/вниз вызывается контекстное меню) где пользователь выбирает нужную позицию и нажатием Ентер либо Пробел активирует дейсвие
ну а дальше ищет объект, который выбрал (атрибут либо ячейка таблицы и т.д.)
d.mOnII вне форума  
 
Непрочитано 26.11.2015, 11:35
#70
RNB

Проектирование мостов
 
Регистрация: 29.01.2014
Новосибирск
Сообщений: 433


Цитата:
Сообщение от d.mOnII Посмотреть сообщение
если интересно и возможно реализовать, то как и в каде можно сделать:
вводится одна команда на создание поля
первое действие - выбираем объект из которого берем информацию (текст, ячейка таблицы и т.д.)
второе действие - по умолчанию ставится новый текст с полем, но есть возможность выбора (стрелками вверх/вниз вызывается контекстное меню) где пользователь выбирает нужную позицию и нажатием Ентер либо Пробел активирует дейсвие
ну а дальше ищет объект, который выбрал (атрибут либо ячейка таблицы и т.д.)
Offtop: Прям мои мысли доступным текстом. Хотел написать, не смог сформулировать, забил. Спасибо!
RNB вне форума  
 
Автор темы   Непрочитано 26.11.2015, 13:33
#71
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Цитата:
Сообщение от d.mOnII Посмотреть сообщение
первое действие - выбираем объект из которого берем информацию (текст, ячейка таблицы и т.д.)
Во-первых, ключевые слова в задаче данного топика:
Цитата:
Сообщение от skkkk Посмотреть сообщение
текстовое значение ячейки таблицы.
и лично я бы рекомендовал пользоваться где возможно все же стандартными полями, как более общедоступными и надежными. В новой версии, которая сейчас у меня на карандаше и которая подверглась серьезным изменениям, но еще не готова к выпуску, я обработал уже вариант, когда пользователь жмет ячейку, а в ней число, а не текст, то вставляется стандартное поле. Оно и понятно стремление многих воспользоваться TCF даже при наличии стандартной возможности - ведь для того, чтобы вставить поле стандартными средствами, необходимо сделать куда больше кликов. Тому, кто согласен со мной в этих рассуждениях, рекомендую попробовать quickfield от Lee Mac. Там используются штатные поля. Все же не хочется заниматься повторением имеющегося функционала.
Во-вторых, если даже мы все же решим, и я захочу добавить в обработку текстовые объекты, то как это сделать? Опять те же грабли: штатный автокадовский выбор ячейки таблицы - крестик и запрос точки, а выбор объекта - квадратик и запрос объекта. Впрочем, пока я склоняюсь к тому, чтобы обрабатывать только ячейки таблиц. Если есть желание и мысли как, то попробуйте меня переубедить.

Цитата:
Сообщение от d.mOnII Посмотреть сообщение
второе действие - по умолчанию ставится новый текст с полем, но есть возможность выбора (стрелками вверх/вниз вызывается контекстное меню) где пользователь выбирает нужную позицию и нажатием Ентер либо Пробел активирует дейсвие
С самого начала создания (точнее сборки) этой программы так я планировалось (в шапке упоминал). Только немного наоборот. Я хотел, чтобы текст с полем висел на курсоре, и реализация мне была знакома и доступна: либо вставка из буфера, либо вставка блока. Но при этом средствами лисп нет возможности обработать нажатие правой кнопки мыши или стрелки вниз. Поэтому я стал хотеть сделать, чтобы по умолчанию выбор объекта либо выбор точки, с возможностью по правой кнопке или стрелке вниз вываливать меню вроде:
  • Вставить в ячейку/в текстовый объект (в зависимости от того, какое "умолчание")
  • Новый текст (а также и варианты, вроде мтекст, мвыноска...)
  • Скопировать поле в буфер
  • Выход
, - однако подумал, что это добавит универсальности, но уменьшит удобство использования, и решил сделать так как сделано сейчас: запрос точки, если в прямоугольник диагональю 6 ед.чертежа вокруг нее попадает текстовый объект, то он модифицируется - меняется его содержимое, а если пусто - вставляется новый текст. Теперь я рассчитал, что крестик надо делать не 6мм, а брать функцию в зависимости от размеров экрана в текущем режиме приближения и от размера прицела. То есть указывая точку воображаем вокруг нее привычный квадрат. Можно попробовать так, должно обрабатываться корректно вне зависимости от единиц чертежа.

Итак, имеем варианты (пока принимаем, что первый запрос - точка, и она должна быть указана только внутри таблицы):
1. Второй запрос - тоже точка, курсор в форме крестика (то, как сейчас, но дошлифованное с учетом всех выявленных багов, в т.ч. обработка атрибутов).
2. Второй запрос - объект, курсор в форме квадрата. Если выбран текстовый объект (в т.ч. атрибут, конечно), он модифицируется, если клик внутри ячейки таблицы - вставка в ячейку, при этом вставится в ту ячейку, где был центр квадрата в момент клика. Если клик на пустом месте - вставка нового объекта, - в общем все как сейчас, отличие только в форме курсора при втором запросе.
3. Второй запрос - точка, курсор в форме крестика, правая кнопка вызывает меню
4. Второй запрос - точка, курсор в форме крестика, стрелка вниз вызывает меню
5. Второй запрос - объект, курсор в форме квадрата, правая кнопка вызывает меню
6. Второй запрос - объект, курсор в форме квадрата, стрелка вниз вызывает меню.

В планах на развитие продумываю переход от использования пользовательских свойств чертежа к использованию словарей, попробую додумать возможность копирования таблицы-мамы с ее полями-детками в новый чертеж и исправить отображение таких полей во внешних ссылках. Правда скоро - не обещаю. Эти три пункта уже в следующих релизах, сейчас основная цель обработать атрибут и навести порядок в коде, используя новые знания по сравнению с моментом написания первой версии.

Прошу высказать мнения, по итогам я приплюсую к ним свое, продвинем вариант, одобренный большинством голосов.
skkkk вне форума  
 
Непрочитано 26.11.2015, 13:42
#72
RNB

Проектирование мостов
 
Регистрация: 29.01.2014
Новосибирск
Сообщений: 433


2й или 5й.
Один вопрос, при вставке в аттрибут/текст/ячейку - будет заменять её содержимое или добавлять в начало/конец содержимого?

UPD. Исправлена опечатка (вместо 5го изначально написал 6й)

Последний раз редактировалось RNB, 27.11.2015 в 05:42.
RNB вне форума  
 
Автор темы   Непрочитано 26.11.2015, 14:41
#73
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Цитата:
Сообщение от RNB Посмотреть сообщение
при вставке в аттрибут/текст/ячейку - будет заменять её содержимое или добавлять в начало/конец содержимого?
По идее - меняется полностью - как сейчас, так я думал и оставить, таким же образом и атрибут хочу прикрутить. А для того, чтоб добавить в любое место имеющегося текста я придумал внедрить занесение поля в буфер обмена. Нетрудно сделать, чтоб добавлялось в конце. Но кому-то нужно будет в начале. А кому-то через пробел, кому-то через точку с запятой. Дабы угодить всем, придется делать дополнительные запросы, а при частой работе с командой они раздражают. А так - кликнул ячейку, отменил команду, ничего не вставляя, сделал двойной клик на тексте, вставил в нужное место курсор, Ctrl+V. Вот еще тут вопрос: делать ли независимо ни от чего занесение поля в буфер обмена или же сделать отдельную команду для этого? Которая сделает все то же, но еще и занесет поле в буфер? Или вообще отдельную команду, которая сначала спросит ячейку, а затем просто добавит поле в буфер, а может, и предложит выбрать текстовый объект, который откроет по одному щелчку, как _.DDEDIT. Правда как тут поступить с атрибутом - вопрос. Не знаю программного способа, как открыть его в редакторе, наподобие того, как он открывается при двойном клике с зажатым CTRL. В случае с принудительным добавлением поля в буфер есть вероятность, что пользователь будет ожидать другого содержимого буфера, который он наполнил этим содержимым до вызова TCF.

Последний раз редактировалось skkkk, 26.11.2015 в 14:46.
skkkk вне форума  
 
Непрочитано 27.11.2015, 05:58
1 | #74
RNB

Проектирование мостов
 
Регистрация: 29.01.2014
Новосибирск
Сообщений: 433


Цитата:
Сообщение от skkkk Посмотреть сообщение
По идее - меняется полностью - как сейчас, так я думал и оставить, таким же образом и атрибут хочу прикрутить. А для того, чтоб добавить в любое место имеющегося текста я придумал внедрить занесение поля в буфер обмена. Нетрудно сделать, чтоб добавлялось в конце. Но кому-то нужно будет в начале. А кому-то через пробел, кому-то через точку с запятой. Дабы угодить всем, придется делать дополнительные запросы, а при частой работе с командой они раздражают. А так - кликнул ячейку, отменил команду, ничего не вставляя, сделал двойной клик на тексте, вставил в нужное место курсор, Ctrl+V.
Согласен, так будет удобнее.
Цитата:
Сообщение от skkkk Посмотреть сообщение
Вот еще тут вопрос: делать ли независимо ни от чего занесение поля в буфер обмена или же сделать отдельную команду для этого?
Думаю, будет удобно, если по умолчанию будет описанное выше, а копирование в буфер, допустим, из контекстного меню по правой кнопке мыши.
Цитата:
Сообщение от skkkk Посмотреть сообщение
Не знаю программного способа, как открыть его в редакторе, наподобие того, как он открывается при двойном клике с зажатым CTRL.
_ATTIPEDIT
И небольшое лирическое отступление, о том, как я получил эту команду. Может пригодится кому. Когда мне нужно узнать команду, которой пользуется Автокад при двойном клике, или, как в этом случае, двойном клике с CTRL, я начинаю запись макроса и провожу указанные действия. Команды отражаются в макросе. Так я, например, выяснил команду редактирования текста мультивыноски.
RNB вне форума  
 
Непрочитано 30.12.2015, 14:42
#75
hardbringer


 
Регистрация: 05.12.2014
Сообщений: 6


Скажите пожалуйста, что необходимо изменить в тексте программы TCF чтобы при выборе пустой ячейки таблицы выводить в текст не "----" а ""?
Или, если это невозможно, выводить те же "----", только с белым цветом шрифта?

Последний раз редактировалось hardbringer, 30.12.2015 в 14:57.
hardbringer вне форума  
 
Автор темы   Непрочитано 02.01.2016, 18:07
#76
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


hardbringer, подобное поведение, когда при пустой ячейке поле принимает вид "----", зашито в ядре программы, и изменить его лиспом нельзя.
С белым цветом шрифта можно сделать, но это несколько неразумно на мой взгляд. Как менять цвет обратно на черный, когда ячейка перестанет быть пустой? Вручную? Или назначать реактор на изменение таблицы? Не нравятся мне эти варианты.
Предлагаю иное решение. Если указанная ячейка-источник окажется пустой, то добавить в нее пробел (программно). Правда при этом поле "потеряется", точнее, текстовый объект, в котором оно находится, если в нем содержится только это поле и более ничего, пропадет из вида, и его нельзя будет выбрать мышкой. Аналогично тому, как если бы в мтексте оставить один пробел. При этом можно добавить скрытие заднего плана этого текстового объекта и цвет фона назначить 255,255,255 - то есть белый на печати. Тогда этот текстовый объект можно будет выбирать и редактировать. Попробуйте, если устроит такой вариант, сделаю.
skkkk вне форума  
 
Непрочитано 03.01.2016, 13:03
#77
allrather


 
Регистрация: 27.02.2011
Минск
Сообщений: 169
Отправить сообщение для allrather с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
В новой версии, которая сейчас у меня на карандаше и которая подверглась серьезным изменениям, но еще не готова к выпуску, я обработал уже вариант, когда пользователь жмет ячейку, а в ней число, а не текст, то вставляется стандартное поле. Оно и понятно стремление многих воспользоваться TCF даже при наличии стандартной возможности - ведь для того, чтобы вставить поле стандартными средствами, необходимо сделать куда больше кликов. Тому, кто согласен со мной в этих рассуждениях, рекомендую попробовать quickfield от Lee Mac. Там используются штатные поля. Все же не хочется заниматься повторением имеющегося функционала.
quickfield от Lee Mac - хорошая штука. Но, реально, было бы круто, чтобы в tcf была возможность создания и стандартного числового поля. Как я понял, скоро она появится? Когда, если не секрет?
Цитата:
Сообщение от skkkk Посмотреть сообщение
Во-вторых, если даже мы все же решим, и я захочу добавить в обработку текстовые объекты, то как это сделать? Опять те же грабли: штатный автокадовский выбор ячейки таблицы - крестик и запрос точки, а выбор объекта - квадратик и запрос объекта. Впрочем, пока я склоняюсь к тому, чтобы обрабатывать только ячейки таблиц.
Думаю, что и не надо они. Работа с ячейками таблицы и все. Зачем перебарщивать? Тут можно еще придумать миллион опций, которыми никто не будет пользоваться, и код будет писаться всю жизнь.
Цитата:
Сообщение от RNB Посмотреть сообщение
_ATTIPEDIT
И небольшое лирическое отступление, о том, как я получил эту команду. Может пригодится кому. Когда мне нужно узнать команду, которой пользуется Автокад при двойном клике, или, как в этом случае, двойном клике с CTRL, я начинаю запись макроса и провожу указанные действия. Команды отражаются в макросе. Так я, например, выяснил команду редактирования текста мультивыноски.
Делаю точно так же. Брат
allrather вне форума  
 
Непрочитано 04.01.2016, 09:52
#78
hardbringer


 
Регистрация: 05.12.2014
Сообщений: 6


Цитата:
Сообщение от skkkk Посмотреть сообщение
Предлагаю иное решение. Если указанная ячейка-источник окажется пустой, то добавить в нее пробел (программно). Правда при этом поле "потеряется", точнее, текстовый объект, в котором оно находится, если в нем содержится только это поле и более ничего, пропадет из вида, и его нельзя будет выбрать мышкой. Аналогично тому, как если бы в мтексте оставить один пробел. При этом можно добавить скрытие заднего плана этого текстового объекта и цвет фона назначить 255,255,255 - то есть белый на печати. Тогда этот текстовый объект можно будет выбирать и редактировать.
При таком варианте решения, в случае изменения значения ячейки таблицы с пустого на непустое при обновлении значений полей командой UTCF отобразится ли в поле новое значение?

upd. И как это сделать не подскажите?

Последний раз редактировалось hardbringer, 13.01.2016 в 17:22.
hardbringer вне форума  
 
Автор темы   Непрочитано 20.01.2016, 19:03
#79
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Цитата:
Сообщение от allrather Посмотреть сообщение
quickfield от Lee Mac - хорошая штука. Но, реально, было бы круто, чтобы в tcf была возможность создания и стандартного числового поля. Как я понял, скоро она появится? Когда, если не секрет?
Уже почти готова эта версия, но еще не все ошибки отловил. Надеюсь, в скором времени дойдут руки.
Цитата:
Сообщение от hardbringer Посмотреть сообщение
При таком варианте решения, в случае изменения значения ячейки таблицы с пустого на непустое при обновлении значений полей командой UTCF отобразится ли в поле новое значение?
Конечно, отобразится новое значение. Иначе какой во всем этом смысл?
Цитата:
Сообщение от hardbringer Посмотреть сообщение
И как это сделать не подскажите?
Боюсь, подсказать тут не получится, поскольку там вопрос не простой замены пары символов в коде, но внедрить эту возможность в ближайшее время также постараюсь. Вот только добавлять ли программно такому тексту белый фон? Убирать его в случае нужды после придется вручную. Или оставить без фона, и тогда одиночный мтекст, содержащий такое поле нельзя будет выбрать мышкой?
skkkk вне форума  
 
Непрочитано 21.01.2016, 08:46
#80
perpetule


 
Регистрация: 23.09.2008
Волгоград
Сообщений: 810
<phrase 1= Отправить сообщение для perpetule с помощью Skype™


Цитата:
Вот только добавлять ли программно такому тексту белый фон
Если добавлять то цвет Мтекста желательно принудительно менять, например один из немногих - цвет 20
одинаково хорошо читается и у тех кто работает на белом фоне, и утех кто на темном.
__________________
tc71
perpetule вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Готовые программы > LISP. Создание поля (field), ссылающегося на текстовое значение ячейки таблицы.

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Вставка в таблицу поля, соотвествующего площади примитива Profan Готовые программы 272 06.06.2021 23:12
Какой язык перспективен для инженера-конструктора с условием The_Mercy_Seat Программирование 705 17.03.2021 14:19
Считывание значение ячейки таблицы в виде Field в AutoLISP tokhot LISP 9 08.01.2017 17:54
Может ли поле принимать текстовое значение ячейки таблицы? Sergiy AutoCAD 23 01.08.2013 12:30