Jump to content

A "Help me with this drawing" email link


brawleyman

Recommended Posts

I am constantly getting requests to help others with their drawings. Pretty much every time, I could get into the drawing, make the change or fix it and save out before the other person can even begin to troubleshoot the problem.

 

Basically, I am looking for a big "Help Me!" button that I can put on everyone's shared toolbar that will automatically send an email to me with a link to the file they are working in. I have a couple of lines of code that almost get me to where I want, but, I am having trouble with the "%20" for spaces in the file path. When you just get the path, it stops at the first space, using vl-string-translate spaces to %20 messes up the path totally, and using underscore won't get me anywhere either.

 

You can copy each line separately in order in my code below to quickly test and see what the issue is I am having with it.

 

(setq dwglocation (strcat (getvar "dwgprefix")(getvar "dwgname")))
(command "start" (strcat "mailto:me.myself.and.i@someemail.com?body=Here%20is%20the%20file:%20file:///"(vl-string-translate " " "_" dwglocation)))

 

I guess I am basically needing a different way to translate the string or something so that it populates properly in Outlook for the hyperlink.

 

Oh, and also, for whatever reason, I cannot get mailto to put in a subject and body at the same time, it is either one or the other, so I just left off the subject for now.

Link to comment
Share on other sites

  • Replies 25
  • Created
  • Last Reply

Top Posters In This Topic

  • brawleyman

    7

  • Lee Mac

    5

  • rlx

    4

  • jpcadconsulting

    3

Maybe:

 

(defun _mailfile ( filepath )
   (while (vl-string-position 32 filepath)
       (setq filepath (vl-string-subst "%20" " " filepath))
   )
   (setq filepath (vl-string-translate "\\" "/" filepath))
   (command "_.start"
       (strcat
           "mailto:me.myself.and.i@someemail.com?body=Here%20is%20the%20file:%20file:///"
           filepath
       )
   )
   (princ)
)

Link to comment
Share on other sites

Thanks for the quick response Lee! I am trying to call it from a macro and it says it is an unknown command. I tried changing it to c:_mailfile and still doesn't come up. How do I need to call this command?

 

 

***EDIT***

Okay, I added a line to set the filepath to the dwgprefix and dwgname to find the drawing. When I try to run the command "emailme", it creates the link and displays the full path, but only underlines and creates the link out of the path up to the first space.

 

(defun c:emailme ()
   (setq filepath (strcat (getvar "dwgprefix")(getvar "dwgname")))
   (while (vl-string-position 32 filepath)
       (setq filepath (vl-string-subst "%20" " " filepath))
   )
   (setq filepath (vl-string-translate "\\" "/" filepath))
   (command "_.start" (strcat"mailto:me.myself.and.i@someemail.com?body=Here%20is%20the%20file:%20file:///" filepath))
   (princ)
)

 

Here is an example of a filepath: "E:\\FP Department\\Group Resources FP\\_FP CAD Standards\\CUI\\LISP\\MEP Design\\CIRCUIT TYPICAL.dwg".

 

The resulting link in Outlook comes out like this: "Here is the file: file:///E:/FP Department/Group Resources FP/_FP CAD Standards/CUI/LISP/MEP Design/CIRCUIT TYPICAL.dwg".

 

What am I doing wrong?

Edited by brawleyman
Link to comment
Share on other sites

I am trying to call it from a macro and it says it is an unknown command. I tried changing it to c:_mailfile and still doesn't come up. How do I need to call this command?

 

The code I posted is a function that requires a single argument: the filename of the file to be linked, hence you would call it:

 

(_mailfile "C:\\Your File.dwg")

Or:

 

(_mailfile (strcat (getvar 'dwgprefix) (getvar 'dwgname)))

When I try to run the command "emailme", it creates the link and displays the full path, but only underlines and creates the link out of the path up to the first space.

 

What am I doing wrong?

 

I hadn't tested it, but I guess this is the behaviour of the mail client. Maybe you need to enclose the filepath with quotes, or some other special character.

Link to comment
Share on other sites

Ah, I understand how that works now with the parentheses after the defun, thanks Lee!

 

Well, I suppose now I just have to figure out how to enclose the filepath. I don't know if it is going to be something specific to LISP or Outlook to input the file path correctly.

 

 

From what little I can find, Outlook uses "" to enclose links with spaces as one whole link. I have been trying to incorporate these symbols into the mailto link in lisp, but it comes up nil. I don't know if I am putting it into the right place or what.

Edited by brawleyman
Link to comment
Share on other sites

Sweet! I got it figured out! Here is my code that allows you to accomplish what I was wanting to do:

 

(defun c:emailme ()
 (setq getemail "me.myself.and.i@someemail.com");input email of helper
 (setq filepath (strcat "<file:///" (getvar "dwgprefix")(getvar "dwgname") ">"))

 ;;Conversion Table
 (while (vl-string-position 32 filepath)
   (setq filepath (vl-string-subst "%20" " " filepath))
 );end while
;  (while (vl-string-position 35 filepath)
;    (setq filepath (vl-string-subst "%23" "#" filepath))
;  );end while
 (while (vl-string-position 38 filepath)
   (setq filepath (vl-string-subst "%26" "&" filepath))
 );end while
 (while (vl-string-position 39 filepath)
   (setq filepath (vl-string-subst "%27" "'" filepath))
 );end while
 (while (vl-string-position 44 filepath)
   (setq filepath (vl-string-subst "%2C" "," filepath))
 );end while
 (while (vl-string-position 58 filepath)
   (setq filepath (vl-string-subst "%3A" ":" filepath))
 );end while
 (while (vl-string-position 60 filepath)
   (setq filepath (vl-string-subst "%3C" "<" filepath))
 );end while
 (while (vl-string-position 62 filepath)
   (setq filepath (vl-string-subst "%3E" ">" filepath))
 );end while
 (while (vl-string-position 92 filepath)
   (setq filepath (vl-string-subst "%5C" "\\" filepath))
 );end while

 (command "_.start" (strcat "mailto:" getemail "?Body=Here%20is%20the%20file%3A%20" filepath))
);end defun

 

Basically, you have to code for every possible symbol that may be used in a file path. The only one I cannot get to work is the "#" hash tag/pound/number sign. Apparently, it is a very special character in mailto links. When you have a file path with that symbol, it appears correct in the email, but clicking on it says "cannot find file". After looking at the actual address created from it when you edit the hyperlink, for some reason there is no space put before the "#" sign, even if %20 or a space is in front of it or you add an extra %20 before the %23 in the conversion setup.

 

Very perplexing. I guess we won't be able to use that symbol in our folders, but it would be nice to be able to include it somehow. Anybody know?

Link to comment
Share on other sites

Thanks Tharwat! I am newer and self-taught with LISP. What exactly does localizing variables do? Does it still allow for other routines to reference values from other routines?

Link to comment
Share on other sites

One reason , is that If you do not localize variables into your routine , variables would become globally into your current opened drawing , and if you have any other codes

that are running in the same drawing and may have the same variable 's names , things would be mixed up and outcome of codes might become odd and illogically .

Link to comment
Share on other sites

Does it still allow for other routines to reference values from other routines?

Those are called global variables and a recommended practice is to surround them by "*" characters.

*GlobalVariableName*

Link to comment
Share on other sites

Thanks for the info guys! Now, if I can just figure out the "#" sign thing. Oh well, I just talked with our project coordinator and the project folders that have the "#" sign in them can be renamed with just the store numbers like the other projects instead of including that sign. Makes thing easier, but it would be nice to have something so that this can become a more user friendly code.

Link to comment
Share on other sites

Now, if I can just figure out the "#" sign thing.

 

Try this brawleyman:

 

(defun c:emailme ( / body email )
   (setq email "me.myself.and.i@someemail.com"
         body  (strcat "Here is the file: <file:///" (getvar 'dwgprefix) (getvar 'dwgname) ">")
   )
   (command "_.start"
       (strcat "mailto:" email "?body="
           (vl-list->string
               (apply 'append
                   (mapcar
                       (function
                           (lambda ( c )
                               (cond
                                   (
                                       (cdr
                                           (assoc c
                                              '(
                                                   (32 37 50 48)
                                                   (35 37 50 53 37 51 50 37 51 51)
                                                   (38 37 50 54)
                                                   (39 37 50 55)
                                                   (44 37 50 67)
                                                   (58 37 51 65)
                                                   (60 37 51 67)
                                                   (62 37 51 69)
                                                   (92 37 53 67)
                                               )
                                           )
                                       )
                                   )
                                   (   (list c)   )
                               )
                           )
                       )
                       (vl-string->list (vl-string-translate "\\" "/" body))
                   )
               )
           )
       )
   )
   (princ)
)

 

You were having trouble because the message is encoded in HTML and the hash symbol is an ID selector in HTML.

Link to comment
Share on other sites

Wow Lee Mac, that was great! So I suppose that everything under assoc c includes multiple symbols that may show up in folder paths? I just wanted to make sure that all my bases are covered.

 

With your help on this, I don't suppose you would be able to take a look at this other thread I started last week about an electrical wiring program? http://www.cadtutor.net/forum/showthread.php?69030-Electrical-Wiring-Program. I just updated the code in my last post with what I have currently.

Link to comment
Share on other sites

Wow Lee Mac, that was great! So I suppose that everything under assoc c includes multiple symbols that may show up in folder paths? I just wanted to make sure that all my bases are covered.

 

Yes, I incorporated all of the symbols from your previous post into the list, this way, the function only iterates over the characters in the string once, instead of checking the string for each of the special symbols.

Link to comment
Share on other sites

  • 6 years later...

Hi gang,

 

This thread has been very helpful.  I feel like I'm one step away from what I need.

 

I'm looking for a command that:

 

Opens the email client (working)

Creates a new email with "Here's the file you were asking about" in the subject (working)

Places the path and name of the current AutoCAD file in the body of the email (not working)

 

I have this code (thanks to you guys and others) which copies the file path and name to the clipboard so users can issue the command and then just press Ctrl-V to paste the path in the body, but you know... I'd love to do it all in one step.

 

Any help is appreciated, as always.

 

(vl-load-com)
(defun c:Path2email ( / en FileLocation html) 
  (and (princ (setq FileLocation (strcat (getvar "dwgprefix") (getvar "dwgname"))))
       (vlax-invoke (vlax-get (vlax-get (setq html (vlax-create-object "htmlfile")) 'ParentWindow) 'ClipBoardData) 'setData "Text" FileLocation)
       (vlax-release-object html)
       )
  (command"Start" "mailto:cadguy@cadbiz.com?Subject=Here's%20the%20location%20of%20file%20you%20asked%20me%20about.")
  (princ)
)

 

Link to comment
Share on other sites

40 minutes ago, jpcadconsulting said:

Hi gang,

 

This thread has been very helpful.  I feel like I'm one step away from what I need.

 

I'm looking for a command that:

 

Opens the email client (working)

Creates a new email with "Here's the file you were asking about" in the subject (working)

Places the path and name of the current AutoCAD file in the body of the email (not working)

 

I have this code (thanks to you guys and others) which copies the file path and name to the clipboard so users can issue the command and then just press Ctrl-V to paste the path in the body, but you know... I'd love to do it all in one step.

 

Any help is appreciated, as always.

 

 

 

I haven't tested it or used it but the very first google link came up with this and it looks interesting :

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/send-email-using-autolisp-or-visuallisp/td-p/973543

 


(defun C:CreateMail  () ; Who's going to get the mail
  (setq recipients_list (list "MyName@MyDomain.com")) ;  What is the subject
  (setq subject "Subject of the mail") ; What is the body
  (setq body "Body of the mail") ; What are the attachments
  (setq attachments_list (list "MyDrawing.dwg"))
  (create-email recipients_list subject body attachments_list 1) ; Do send this mail immediately
  ; (create-email recipients_list subject body attachments_list 0)
  ; Do not yet send this mail (princ) )
  (defun create-email  (recipients_list   subject           body              attachments_list
                        email_send        /                 acadapp           acaddoc
                        outlookapp        mail_object       recipients_collection
                        attachments_collection              temp              ret
                        item              cadz3d_function)
    ;; Load the extended AutoLISP functions and ActiveX support
    (vl-load-com)
    ;; Get the application and current document objects
    (setq acadapp (vlax-get-acad-object)
          acaddoc (vlax-get-property acadapp 'activedocument))
    ;; Get the existing outlook application object
    (if
      (or
        (= (setq outlookapp (vl-catch-all-apply 'vlax-get-object (list "Outlook.Application")))
           nil)
        (/= (type outlookapp) 'vla-object))
       (progn (alert (strcat
                       "Microsoft Outlook must already be running\n"
                       "to create and send the email. This will be\n"
                       "improved in future versions.\n\n"
                       "Please start Microsoft Outlook and then close\n"
                       "this dialog box to create the email."))
              (setq outlookapp (vl-catch-all-apply 'vlax-get-object (list "Outlook.Application")))))
    (if (= (type outlookapp) 'vla-object)
      (if ;; Create new email object
          (setq mail_object (vlax-invoke-method outlookapp 'createitem 0))
        (if ;; Get the recipients collection
            (setq recipients_collection (vlax-get-property mail_object 'recipients))
          (progn
            ;; Add the recipients properties to the email
            (foreach item  recipients_list
              (if (= (type item) 'str)
                (vlax-invoke-method recipients_collection 'add item)))
            ;; Add the subject properties to the email
            (if (= (type subject) 'str)
              (vlax-put-property mail_object 'subject subject))
            ;; Add the body properties to the email
            (if (= (type body) 'str)
              (vlax-put-property mail_object 'body body))
            ;; Add the attachements properties to the email
            (if
              (and (vl-consp attachments_list)
                   (setq attachments_collection (vlax-get-property mail_object 'attachments)))
               (foreach item  attachments_list
                 (if (and (setq temp (findfile item)) (vl-file-systime temp))
                   (vlax-invoke-method attachments_collection 'add temp))))
            ;; If the email_send equals 1 and the recipients_list, subject, and body were passed to the
            ;; function then send the email, otherwise display the email for the user to finish
            (if (and (= email_send 1)
                     (vl-consp recipients_list)
                     subject
                     body
                     (/= subject "")
                     (/= body ""))
              (vlax-invoke-method mail_object 'send)
              (vlax-invoke-method mail_object 'display))
            (setq ret t))
          (princ "\nCould not get the recipients collection from the new mail item"))
        (princ "\nCould not create a new mail item through Outlook"))
      (princ "\nCould not create a new instance of Outlook"))
    ;; Release the objects
    (if (and (= (type attachments_collection) 'vla-object)
             (= (vlax-object-released-p attachments_collection) nil))
      (vlax-release-object attachments_collection))
    (if (and (= (type recipients_collection) 'vla-object)
             (= (vlax-object-released-p recipients_collection) nil))
      (vlax-release-object recipients_collection))
    (if (and (= (type mail_object) 'vla-object) (= (vlax-object-released-p mail_object) nil))
      (vlax-release-object mail_object))
    (if (and (= (type outlookapp) 'vla-object) (= (vlax-object-released-p outlookapp) nil))
      (vlax-release-object outlookapp))
    (if (and (= (type acaddoc) 'vla-object) (= (vlax-object-released-p acaddoc) nil))
      (vlax-release-object acaddoc))
    (if (and (= (type acadapp) 'vla-object) (= (vlax-object-released-p acadapp) nil))
      (vlax-release-object acadapp))
    (princ)
    ret))

Link to comment
Share on other sites

Hmmm. Not working.

 

It throws:

 

"; error: no function definition: CREATE-EMAIL"

 

Anyway, I think I must be missing something simple in the syntax of the Mailto: code:

 

(command"Start" "mailto:cadguy@cadbiz.com?Subject=Here's%20the%20location%20of%20file%20you%20asked%20me%20about.")

I can get it to pre-populate the body by changing "Subject=" to "Body=":

(command"Start" "mailto:cadguy@cadbiz.com?Body=Here's%20the%20location%20of%20file%20you%20asked%20me%20about.")

But It seems that I can't do both:

 

(command"Start" "mailto:cadguy@cadbiz.com?Subject=Here's%20the%20location%20of%20file%20you%20asked%20me%20about.?Body=TEST")

It results in the following text in the subject line:

 

Here's the location of file you asked me about.?Body=TEST

 

Link to comment
Share on other sites

Fyi,

 

Some research suggests that and Ampersand should be the delimiter between "Subject=" and "Body="

https://www.labnol.org/internet/email/learn-mailto-syntax/6748/

 

But this code also did not work.  Nothing in the body.

 

(command"Start" "mailto:cadguy@cadbiz.com?Subject=Here's%20the%20location%20of%20file%20you%20asked%20me%20about.?Body=TEST")
(command"Start" "mailto:cadguy@cadbiz.com?Subject=Here's%20the%20location%20of%20file%20you%20asked%20me%20about.&Body=TEST")

 

 

 

Link to comment
Share on other sites

code in link is poorly formatted (but still haven't tested it)


;;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/send-email-using-autolisp-or-visuallisp/td-p/973543

(defun C:CreateMail  ()
  ;;; Who's going to get the mail
  (setq recipients_list (list "MyName@MyDomain.com"))
  ;;;  What is the subject
  (setq subject "Subject of the mail")
  ;;; What is the body
  (setq body "Body of the mail")
  ;;; What are the attachments
  (setq attachments_list (list "MyDrawing.dwg"))
  ;;; Do send this mail immediately
  (create-email recipients_list subject body attachments_list 1)
  ;;; Do not yet send this mail
  ;;; (create-email recipients_list subject body attachments_list 0)
  (princ)
)

(defun create-email  (recipients_list subject body attachments_list email_send / acadapp acaddoc
                      outlookapp mail_object recipients_collection attachments_collection temp ret
                      item cadz3d_function)
  ;;; Load the extended AutoLISP functions and ActiveX support
  (vl-load-com)
  ;;; Get the application and current document objects
  (setq acadapp (vlax-get-acad-object)
        acaddoc (vlax-get-property acadapp 'activedocument))
  ;;; Get the existing outlook application object
  (if (or (= (setq outlookapp (vl-catch-all-apply 'vlax-get-object (list "Outlook.Application"))) nil)
          (/= (type outlookapp) 'vla-object))
     (progn
       (alert (strcat "Microsoft Outlook must already be running\nto create and send the email."
                      " This will be\nimproved in future versions.\n\nPlease start Microsoft Outlook"
                      " and then close\nthis dialog box to create the email."))
       (setq outlookapp (vl-catch-all-apply 'vlax-get-object (list "Outlook.Application")))))
  (if (= (type outlookapp) 'vla-object)
    (if (setq mail_object (vlax-invoke-method outlookapp 'createitem 0));;; Create new email object
      (if (setq recipients_collection (vlax-get-property mail_object 'recipients)) ;;; Get the recipients collection
        (progn
          ;;; Add the recipients properties to the email
          (foreach item  recipients_list (if (= (type item) 'str) (vlax-invoke-method recipients_collection 'add item)))
          ;;; Add the subject properties to the email
          (if (= (type subject) 'str) (vlax-put-property mail_object 'subject subject))
          ;;; Add the body properties to the email
          (if (= (type body) 'str) (vlax-put-property mail_object 'body body))
          ;;; Add the attachements properties to the email
          (if (and (vl-consp attachments_list) (setq attachments_collection (vlax-get-property mail_object 'attachments)))
             (foreach item  attachments_list
               (if (and (setq temp (findfile item)) (vl-file-systime temp))
                 (vlax-invoke-method attachments_collection 'add temp))))
          ;;; If the email_send equals 1 and the recipients_list, subject, and body were passed to the
          ;;; function then send the email, otherwise display the email for the user to finish
          (if (and (= email_send 1) (vl-consp recipients_list) subject body (/= subject "") (/= body ""))
            (vlax-invoke-method mail_object 'send) (vlax-invoke-method mail_object 'display))
          (setq ret t)
        )
        (princ "\nCould not get the recipients collection from the new mail item"))
      (princ "\nCould not create a new mail item through Outlook"))
    (princ "\nCould not create a new instance of Outlook"))
  ;;; Release the objects
  (if (and (= (type attachments_collection) 'vla-object) (= (vlax-object-released-p attachments_collection) nil))
    (vlax-release-object attachments_collection))
  (if (and (= (type recipients_collection) 'vla-object) (= (vlax-object-released-p recipients_collection) nil))
    (vlax-release-object recipients_collection))
  (if (and (= (type mail_object) 'vla-object) (= (vlax-object-released-p mail_object) nil))
    (vlax-release-object mail_object))
  (if (and (= (type outlookapp) 'vla-object) (= (vlax-object-released-p outlookapp) nil))
    (vlax-release-object outlookapp))
  (if (and (= (type acaddoc) 'vla-object) (= (vlax-object-released-p acaddoc) nil))
    (vlax-release-object acaddoc))
  (if (and (= (type acadapp) 'vla-object) (= (vlax-object-released-p acadapp) nil))
    (vlax-release-object acadapp))
  (princ)
  ret
)


 

will try it myself tomorrow

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...