How can make any entity as last entity in Autocad Autolisp - autocad

I am working with AutoCAD electrical 2016. there is "c:aeballoon" command which can be applied to last entity via lisp. if I want to apply this command to any other entity (say Nth entity) in the drawing. so there is one solution if any how make Nth entity as last entity. so this c:aeballoon command can successfully applied to that Nth Entity.
Thank in advance

You can create the following AutoCADLisp Program.
copy the following to notepad
(defun c:makelast() (command ".copy" "si" (setq kk (car (entsel))) "0,0" "" ".erase" kk "")(princ))
save the file as makelast.lsp
Use Appload command to load the program.
RUn the new command Makelast to select the object you want to make it last.

Related

Mtext. Autolisp returns "Invalid point" but typing the point in the command windows works

I'm new to autolisp and setting my first macro. I want to create a rectangle, label it with some text centered on it and then convert both entities into a block (this is for optimizing the loading of packaged items into a trailer).
I've succeed building the rectangle but I'm stuck on the mtext part. This is what I have done so far:
(defun c:caja ()
;Switch OFF System Variables
(setvar "osmode" 0)
;Switch OFF snap
;(setvar "blipmode" 0)
;Switch OFF Blipmode
*******************************************************
;User Inputs
(setq pt1 (getpoint "\nSelect start point: "));lower left corner
(setq Long (getdist "\nLength m : "))
(setq Ancho (getdist "\nWidth : "))
;(setq Alto (getdist "\nHeight : "))
;(setq Peso (getdist "\nWeight : "))
*******************************************************
(setq pt2 (polar pt1 0 Long )) ;lower right corner
(setq pt3 (polar pt2 (* pi 0.5) Ancho));upper right corner
*******************************************************
(command"rectang" pt1 pt3"")
(command "mtext" "!pt1" "!pt3" "potato")
When executing the last line of the code I get:
Invalid point. ; error: Function cancelled.
However autocad lets me keep working on the mtext command and asks me to "specify first corner". If I type !pt1 there it Works.
My understanding is that in autolisp I must write between quotes "" every answer that I would normally type in the command prompt so I don't know what I'm doing wrong.
Using the exclaimation mark prefix allows you to evaluate global AutoLISP variables directly at the AutoCAD command-line, outside of any AutoLISP program.
However, when used within a program, such variables will be evaluated as part of the evaluation of the AutoLISP program, and therefore the exclaimation mark prefix is not required.
You have already implemented this successfully when calling the RECTANG command:
(command "rectang" pt1 pt3 "")
Therefore, you can use the same logic for the MTEXT command:
(command "mtext" pt1 pt3 "potato" "")
I would also make the following recommendations:
Store the current values of system variables before changing them, so that you may reset them back to their original values (otherwise the user will lose all of their Object Snap settings, for example).
Implement a local error handler to automatically reset system variables in the event of an error or the user pressing Esc. Refer to my tutorial here for more information on how to accomplish this.
Use an underscore (_) & period (.) to prefix command names, e.g.:
(command "_.rectang" ... )
The underscore ensures that the command is interpreted in English in non-English versions of AutoCAD. The period ensures that the standard definition of the command is used, not a redefinition.
Test for valid user input using an if statement before proceeding.
Declare your local variables to ensure that you variables are not inadvertently overwritten by other programs defining symbols in the document namespace. See my tutorial here for more information on this.

Enable "dynamic input" when measuring distance

I have a LISP routine which measures between two points using getpoint, it then creates a table and (well, it will once I've finished anyway) populate the table with figures, based on the measured value.
The problem is when I select the first point, there is no visual feedback of where I selected, such as there is when using the built in distance tool. For example, in both of the below screenshots, I have chosen my first point to measure from, but not the second where I want to measure to;
Using the distance tool;
Using my tool;
How, in LISP, can I add this "dynamic input" (I think thats the correct term?) to give my user some kind of visual feedback that the tool is working as they expect?
The function (getpoint [pt] [msg]) actually has two optional parameters. It looks like you're already using the msg parameter to display your custom message ("Choose second point"), but you can pass the previous point as the first parameter to get a nice reference line between that point and the crosshairs. For example:
(setq P1 (getpoint "Choose first point: "))
(setq P2 (getpoint P1 "Choose second point: "))
Additionally, there's a (getdist [pt] [msg]) function, which behaves similarly but previews and returns a distance.
(setq P1 (getpoint "Choose first point: "))
(setq P2 (getdist P1 "Choose second point: "))

How to list the names of all the blocks of a .dwg file in AutoCAD CORE console?

i will get custom block in a .dwg file from a list of blocks which I will parse programmatically in Java.
You can use the command INSERT with the option ?
cd C:\Program Files\Autodesk\AutoCAD 2016
accoreconsole.exe /i "Sample\Database Connectivity\Floor Plan Sample.dwg"
Command: _INSERT
Enter block name or [?]: ?
Enter block(s) to list <*>:
Defined blocks.
"CHAIR7"
"COMPUTER"
"DESK2"
"DESK3"
"DOOR"
"DR-36"
"DR-69P"
"DR-72P"
"FC15X27A"
"FC42X18D"
"FNPHONE"
"IBMAT"
"KEYBOARD"
"NCL-HL"
"RECTANG"
"RMNUM"
"SOFA2"
User Unnamed
Blocks Blocks
17 0
I am not familiar with Core Console but for listing all block in a DWG file, you need to use LISPs. Something like axBlock from jtbworld . You may also mock around with LISP code and call it via a SCRIPT.
Edit:
Copy and paste following code in Notepad and save it as axBlock.lsp in the root fo your C drive (for instance):
(defun c:axblocks (/ b bn tl)
(vlax-for b (vla-get-blocks
(vla-get-ActiveDocument (vlax-get-acad-object))
)
(if (= (vla-get-islayout b) :vlax-false)
(setq tl (cons (vla-get-name b) tl))
)
)
(reverse tl)
)
I just tweaked jtbworld's code a little bit to make it easier for you.
Now you have your LISP code ready and you only need to load it into AutoCAD. You have couple of options for that:
Use APPLOAD command in AutoCAD and browse for axBlock.lsp which
you just created
Drag axBlock.lsp over your AutoCAD window.
Call axBlock.lsp via a script file. And scripts are nothing
really
but a simple textual file with *.scr extension. For that you just
need this line of code to be in your script file:
(load "C:\\axBlock.lsp")
After doing any of above three methods, as long as you type axBlock in AutoCAD and hit Enter, you will see the list of existing blocks.
Moreover, if you followed approach no.3 from above list, you can make a shortcut and call axBlock within the script file as well i.e. you load and call the function in one hit. If you want to do so, just add axBlock in the second line of your script code. Note there an extra SPACE after axBlock

Copying file details from Explorer as tabular text

I am looking for a way to easily copy the file details that appear in a Windows Explorer (details view) and paste it as tabular text.
Ideally, the procedure would be to select some files in an Explorer, make a choice in the context menu (or use a shortcut key), and the list would be copied to the clipboard. When pasting, the tabular format would be preserved so that Excel would recognize the columns or Word keep tabs (or create a table).
I would like to have a solution that transfers the available columns, and not just a predefined set a details such as name + size + date.
Do you think that there is an easy way to achieve this functionality ? I am ready to program in any language if necessary but I need a path to follow. I also need a procedure to integrate it in Windows (Vista and later) so that a few clicks suffice.
1) Create context menu shell extension. It must implement IShellExtInit, IContextMenu(2,3) and IObjectWithSite. Register your shell extension on HKCR\AllFilesystemObjects key.
2) Before Explorer calls IContextMenu.InvokeCommand it calls IObjectWithSite.SetSite. Save Site value.
3) Inside IContextMenu.InvokeCommand:
Site.QueryInterface(IServiceProvider, ServiceProvider)
ServiceProvider.QueryService(SID_SFolderView, IColumnManager, ColumnManager)
ColumnManager.GetColumnCount(CM_ENUM_VISIBLE, Count)
GetMem(Keys, SizeOf(PPropertyKey) * Count)
ColumnManager.GetColumns(CM_ENUM_VISIBLE, Keys, Count)
Now you have array of all visible columns.
4) Extract IShellFolder of current folder from IDataObject passed to your handler in IShellExtInit.Initialize.
5) Extract PItemIDList of every file in IDataObject.
6) For every PItemIDList:
6.1) Call ShellFolder.BindToObject(Child, nil, IPropertyStore, PropertyStore) to get PropertyStore of item.
6.2) For every PropertyKey in Keys array:
6.2.1) Call PropertyStore.GetValue(PropertyKey, Value);
6.2.2) Convert Value to string with PropVariantToStringAlloc function.
6.2.3) Store string representation of Value in you internal txt storage.
7) Copy your txt storage to clipboard.
8) Free all resources.
Update 1
Also you can try to use IShellFolder2.GetDetailsEx instead of using IPropertyStore.
Update 2
In case of using IPropertyStore you can additionally call IPropertySystem.FormatForDisplayAlloc to format the value. For example for PKEY_Size PropertyStore.GetValue return "100000" but PropertySystem.FormatForDisplayAlloc will format value to "100 KB".
Update 3
It was quite interesting task so I created my own shell extension which copies details to clipboard. It can be downloaded via link http://www.shellace.com/bin/CopyDetails.zip

Is there a way with org-capture-templates to not insert a line if initial content is blank

I would like to have org-capture-template that does not insert certain text if a %-escape is blank. I am actually using the template with org-protocol and :immediate-finish, so I don't have the ability to manually edit and delete the blank line in a buffer. And sometimes I may select text on the web page and sometimes I may not. I am also just generally interested being able to make more dynamic templates.
Take this capture template as an example
(setq org-capture-templates
(quote (("w" "capture" entry (file "~/org/refile.org")
"* [[%:link][%:description]] :NOTE:\n%i\n%U\n" :immediate-finish t))))
With org-protocol://capture://w/http%3A%2F%2Fstackoverflow.com%2F/Stack%20Overflow/Hot%20Network%20Questions.
I get this which is fine.
* [[http://stackoverflow.com/][Stack Overflow]] :NOTE:
Hot Network Questions
[2014-01-12 Sun 13:01]
But if I don't have text selected like this example org-protocol://capture://w/http%3A%2F%2Fstackoverflow.com%2F/Stack%20Overflow/.
I get this:
* [[http://stackoverflow.com/][Stack Overflow]] :NOTE:
[2014-01-12 Sun 12:58]
I would like to know how to get rid of the blank line in this last example without having to use two templates.
My thought is to somehow use quote to build the string dynamically at template creation time, but I don't know how to get the value of %i to eval.
Use this auxiliary function:
(defun v-i-or-nothing ()
(let ((v-i (plist-get org-store-link-plist :initial)))
(if (equal v-i "")
""
(concat v-i "\n"))))
And this as capture template:
("w" "capture" entry (file "~/refile.org")
"* [[%:link][%:description]] :NOTE:\n%(v-i-or-nothing)%U\n"
:immediate-finish t)

Resources