Hello all,
I am newbie in .Net C# and learning. I have lisp wrote with att in block.
Can someone convert to C# so i can learn more in .Net
Thanks in advance.
This is my code lisp: (defun c:tcount_att (/ ss ob start_num inc_num sum ename new_value OLDER *error*) (vl-load-com) (setq OLDER *error* *error* myerror) (if (setq ss (ssget '((0 . "INSERT")))) (progn (initget 1 "X Y Select") (setq ob (getkword "\nSort selected objects by [X/Y/Select-order] <Select-order>: ")) (cond ((= ob "X") (setq ss (sort_x ss)) ) ((= ob "Y") (setq ss (sort_y ss)) ) ((= ob "Select") (setq ss (sort ss)) ) );cond (setq start_num (getint "\nSpecify starting number <1>: ")) (if (= start_num nil) (setq start_num 1) (setq start_num start_num) ) (setq inc_num (getint "\nSpecify increment number <1>: ")) (if (= inc_num nil) (setq inc_num 1) (setq inc_num inc_num) );if (setq sum 0) (setq sum (apply '+ (list sum start_num))) (setq ename (entnext (car ss))) (if (/= (cdr (assoc 0 (entget ename))) "SEQEND") (progn (setq new_value (rtos sum 2 0)) (entmod (subst (cons 1 new_value) (assoc 1 (entget ename)) (entget ename))) (entupd (car ss)) ) ) (mapcar '(lambda (obj) (setq sum (apply '+ (list sum inc_num))) (setq ename (entnext obj)) (if (/= (cdr (assoc 0 (entget ename))) "SEQEND") (progn (setq new_value (rtos sum 2 0)) (entmod (subst (cons 1 new_value) (assoc 1 (entget ename)) (entget ename))) (entupd obj) ) ) ) (cdr ss) ) );progn );if (setq *error* OLDER) (princ) );defun ;;;;;;;; (defun sort_x (sset / n ss1 ) (setq ss1 nil) (setq n 0) (repeat (sslength ss) (setq ss1 (append ss1 (list (ssname ss n)))) (setq n (1+ n)) );repeat (setq ss1 (vl-sort ss1 '(lambda (e1 e2) (< (car (cdr (assoc 10 (entget e1)))) (car (cdr (assoc 10 (entget e2)))) ) ) ) );setq ) ;;;;;;;; (defun sort_y (sset / n ss1 ) (setq ss1 nil) (setq n 0) (repeat (sslength ss) (setq ss1 (append ss1 (list (ssname ss n)))) (setq n (1+ n)) ) (setq ss1 (vl-sort ss1 '(lambda (e1 e2) (< (cadr (cdr (assoc 10 (entget e1)))) (cadr (cdr (assoc 10 (entget e2)))) ) ) ) );setq ) ;;;;;;;; (defun sort (sset / n ss1 ) (setq ss1 nil) (setq n 0) (repeat (sslength ss) (setq ss1 (append ss1 (list (ssname ss n)))) (setq n (1+ n)) ) ss1 ) ;;;;;;;;;;;;;;;;;;;;;; (defun myerror (s) (cond ((= s "quit / exit abort") (princ)) ((/= s "Function cancelled") (princ (strcat "\nError: " s))) ) (setq *error* OLDER) (princ) ) (princ "\nCommand: tcount_att ") (princ)
Solved! Go to Solution.
Solved by _gile. Go to Solution.
You'll get a better long term result if you attempt to make the translation yourself.
But first, have you tried writing C# code without the extra burden of translating lisp. ?
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper
Hi,
I totally agree with Kerry.
I could, like many others here, convert this LISP routine into C# but it would be the worst service to make you want to learn C# (.NET more accurately).
Learning .NET is a more difficult task than learning AutoLISP which cannot be content to read code written by others.
Start by learning the basics of .NET (Object Oriented Programming, Visual Studio,.NET Framework and C # syntax) outside of AutoCAD (standard Window programming) before trying to use AutoCAD .NET API.
PS: Are the author of the LISP routine ?
If so, before trying to convert it to C#, you could simplify/optimize some expressions as:
(setq sum 0) (setq sum (apply '+ (list sum start_num)))
or the way you iterate list of selected objects.
Hi,
I am reading some AutoCAD .NET Developer's Guide. And right some code: draw line, circle....function simple. Beginer 🙂
I know the way write C# different lisp.
Can you have example code C#: select block , and modify value att in block by getstring.?
I am still learning about it.
Thanks
Hi Gile,
I am learning basics of .NET
I mean convert lisp to C# then see how can write C# for object ACAD.
And simplify/optimize:
(setq sum 0) (setq sum (apply '+ (list sum start_num)))
change to:
(setq sum 0) (setq sum (+ sum start_num))
Thanks for repply.
Here's a C# conversion of the LISP routine.
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using System.Collections.Generic; namespace TCountAttribute { public class Commands { [CommandMethod("TCOUNT_ATT")] public void TCountAttCommand() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; // build a selection filter to select only block references with attributes // and prompt the user fo a selection TypedValue[] filter = { new TypedValue(0, "INSERT"), new TypedValue(66, 1) }; PromptSelectionResult selResult = ed.GetSelection(new SelectionFilter(filter)); // exit the command if none block selected if (selResult.Status != PromptStatus.OK) return; // start a transaction to open selected blocks using (Transaction tr = db.TransactionManager.StartTransaction()) { // build a list of block references from the selection set List<BlockReference> blocks = new List<BlockReference>(); foreach (SelectedObject so in selResult.Value) { BlockReference br = (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForRead); blocks.Add(br); } // prompt the user for a sorting option PromptKeywordOptions kwordOptions = new PromptKeywordOptions( "\nSort selected objects by [X/Y/Select-order]", "X Y Select-order"); kwordOptions.Keywords.Default = "Select-order"; PromptResult kwordResult = ed.GetKeywords(kwordOptions); if (kwordResult.Status != PromptStatus.OK) // <- cancel return; // sort the list by X or Y (already done for select order) switch (kwordResult.StringResult) { case "X": blocks.Sort((b1, b2) => b1.Position.X.CompareTo(b2.Position.X)); break; case "Y": blocks.Sort((b1, b2) => b1.Position.Y.CompareTo(b2.Position.Y)); break; } // prompt the user for the starting number PromptIntegerOptions intOptions = new PromptIntegerOptions("\nSpecify starting number: "); intOptions.DefaultValue = 1; intOptions.UseDefaultValue = true; PromptIntegerResult intResult = ed.GetInteger(intOptions); if (intResult.Status != PromptStatus.OK) // <- cancel return; int num = intResult.Value; // prompt the user for the increment number intOptions.Message = "\nSpecify increment number: "; intResult = ed.GetInteger(intOptions); if (intResult.Status != PromptStatus.OK) // <- cancel return; int incNum = intResult.Value; // set the first attribute value of each block reference in the list foreach (BlockReference br in blocks) { ObjectId firstAttId = br.AttributeCollection[0]; AttributeReference attRef = (AttributeReference)tr.GetObject(firstAttId, OpenMode.ForWrite); attRef.TextString = num.ToString(); num += incNum; // increment the value } tr.Commit(); } } } }
yep, you are right. 😄
And 1 more question.
How can add print str "command: TCOUNT_ATT" when netload .dll ? I was combine to dll .
i add line but not working
public void Test() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage("Command: TCOUNT_ATT"); }
To execute some code at DLL loading, you should have a class in your project which implements the IExtensionApplication interface.
This may be either a separate class (as below) or the same class as the one where the command is defined (as in upper link sample).
public class Initialization : IExtensionApplication { public void Initialize() { var ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.WriteMessage("\nCommand: TCOUNT_ATT"); } public void Terminate() { // do nothing here, but the Terminate() method must be explicitly implemented } }