Use *.mnl to save path for *.mnu

Discussion in 'AutoCAD' started by sbrusco, Apr 6, 2005.

  1. sbrusco

    sbrusco Guest

    Hi,

    I am creating a pull-down menu that will present many details to be inserted, all from the same directory. I would prefer to *not* list the directory in *every* line of the mnu, in case that directory should change in the future.

    I was thinking about creating a variable in the mnl file and referencing that in the mnu file. Then if the path did change, I would modify one line in the mnl file and be done. How can I make this idea, or something like it, work? Will the following work?

    In the mnl:
    (setq prodDir "G:/Product/Profiles/Details/")

    In the mnu:
    [Base Detail]^C^C-insert (StrCat (prodDir) "Base");\;;

    Thanks,
    Sal
     
    sbrusco, Apr 6, 2005
    #1
  2. sbrusco

    Jim Claypool Guest

    [Base Detail]^C^C-insert (StrCat prodDir "Base");\;;
     
    Jim Claypool, Apr 6, 2005
    #2
  3. sbrusco

    Tom Smith Guest

    I went a step further and defined a general purpose block insertion routine in the mnl, and call that in all cases where a block is being inserted. This would eliminating the repetitive strcat in the menu, and you'd have something like

    [Base Detail]^C^C(myinsert "Base");\;;

    I did this in part because we have about 1000 blocks, in a whole tree of folders, not just one, and I didn't want to add all those folders to the search path. My insert routine searches those folders to find the block to insert.

    Of course if you add this folder to your search path, you can eliminate the path altogether. If the location changes, you can change the path in your profile.
     
    Tom Smith, Apr 6, 2005
    #3
  4. sbrusco

    sbrusco Guest

    Hi Tom,

    That sounds like a better idea. Would you care to share your "general purpose block insertion routine in the mnl"?

    Do you create a different insertion routine for each path?

    Thanks for the great idea and in advance for the routine.
    Sal
     
    sbrusco, Apr 6, 2005
    #4
  5. sbrusco

    Tom Smith Guest

    Sal, just to repeat, if you add this one special folder to your Acad search path, then you don't need to include its path at all, just insert the block name.

    [Base Detail]^C^C-insert "Base";\;;

    If it's just one folder for many details, I'd probably do that.

    Starting about R14 when I reorganized our blocks, I sorted them into a tree of folders for ease of maintenance, but I wasn't crazy about adding 8 or 10 more folders to the search path because of this, so I wrote a function to search those folders. Per your example this would be something like

    (defun findblock (blockname / extrafolder)
    (setq extrafolder "G:/Product/Profiles/Details/")
    (cond
    ((findfile (strcat blockname ".dwg")))
    ((findfile (strcat extrafolder blockname ".dwg")))))

    Which looks first on the search path, then in your other folder, and returns either a filename or nil if not found.

    Our block insert routine is general purpose for us in that it accomodates all of the ways in which we insert blocks -- your needs are probably different. You need to decide what things might be variable. Is the scale always the same? How about layer and rotation? You need a parameter for anything that varies.

    For instance if you always insert blocks at a scale of 1, but on different layers, and want the option of prompting for rotation, you could use:

    (defun ourblockinsert (blockname layer rotation / clayer cmdecho)
    (setq
    clayer (getvar 'clayer)
    cmdecho (getvar 'cmdecho))
    (if (setq filename (findblock blockname))
    (progn
    (setvar 'clayer layer)
    (setvar 'cmdecho 0)
    (prompt "\nInsertion point: ")
    (command "insert" filename pause 1 "")
    (if (not (numberp rotation))
    (prompt "\nRotation angle: "))
    (command rotation))
    (princ "\nFile not found."))
    (setvar 'clayer clayer)
    (setvar 'cmdecho cmdecho)
    (princ))

    Examples:

    (ourblockinsert "Door1" "door" pause) will place the door1 block on the door layer and prompt for insertion point and rotation.

    (ourblockinsert "Light1" "elec" 0) will place Light1 on the elec layer at a rotation of 0.

    Our actual routines are a lot more complex, for a variety of reasons. Note that if you're going to specify the layer like this, and the user cancels without placing the block, they'll be left on the new layer. To prevent that, you'd need an error handler included, which is a whole other subject.
     
    Tom Smith, Apr 7, 2005
    #5
  6. sbrusco

    sbrusco Guest

    Hi Tom,

    I guess i was unclear, but please forgive my mumbling. I also have a tree of directories that i didn't want to clutter my support files with, so the example you give is necessary for us also.

    Thanks for the code that is much more simple than i imagined.

    Thanks also for sharing with this ng family.

    Sal
     
    sbrusco, Apr 7, 2005
    #6
  7. sbrusco

    Tom Smith Guest

    Sorry I misunderstood Sal. The example I gave only provided for one "extra" folder. Here's more like what we really do...

    All of our block folders are nested under a subfolder of the Acad executable folder. I had to make a provision for the program being installed in different locations. So I have a function to return the Acad folder:

    (defun findacaddir (/ acaddir dirlen)
    (setq
    acaddir (findfile "acad.exe")
    dirlen (strlen acaddir))
    (substr acaddir 1 (- dirlen 8)))

    Our blocks are in folders such as Custom\Detail\Door and Custom\Detail\Elec. To search through this tree I have a function like (simplified a little)

    (defun findblock (blockname / ourprefix searchlist filename index)
    (setq
    ourprefix (strcat (findacaddir) "Custom\\Detail\\")
    searchlist '("door\\" "elec\\" "fixt\\" "tags\\" "win\\")
    index 0)
    (if (null (setq filename (findfile (strcat blockname ".dwg"))))
    (while (< index (length searchlist))
    (if (setq filename (findfile (strcat ourprefix (nth index searchlist) blockname ".dwg")))
    (setq index (length searchlist)))
    (setq index (1+ index))))
    filename)

    This will run a findfile on whatever folders are included in searchlist. You'll need to adjust the paths for your needs, of course.
     
    Tom Smith, Apr 7, 2005
    #7
  8. sbrusco

    sbrusco Guest

    Thanks Tom,

    This is what i was looking for and was going to develop myself, i just don't have time for re-inventing the wheel. And i'm sure you know what i mean.

    I will modify to suit my needs and post the result, in case you're interested in the spawn of your child.

    BTW, isn't it risky to put your programs in the AutoCAD directory? Do you have to restore them from a holding place with every upgrade?

    Thanks again,
    Sal
     
    sbrusco, Apr 8, 2005
    #8
  9. sbrusco

    Tom Smith Guest

    Sal, I've heard that caution a lot, and don't get it. On an uninstall/reinstall/repair, Acad won't touch anything other than the filenames that it installed. If you modify a standard Acad file, it will be overwritten on a reinstall or deleted on an uninstall. But if you put your own version of a standard file elsewhere, not in a standard folder, the uninstall/reinstall will leave it alone, whether or not its folder is located below Acad's. If I uninstall, Acad will leave my folder tree intact in an otherwise empty Acad folder, and report that there were things it couldn't remove.

    Our customizations change a good bit with every upgrade anyway. During a transition period, it's easier for me to maintain two separate master copies of our stuff temporarily than to try to make every little thing compatible with either versions. Once everyone's up to speed, I don't support the old version any more.Till now we've done standalone installations, but 2006 willl finally force a network license setup and I'll probably go to a centralized net setup of our customizations.

    Reading all the stuff that folks go through with the network install, I tend to think that the old fashioned standalone approach was a good bit simpler. On the server I keep a read-only master copy of our customization folder tree. It contains all our help docs, including a "how to install" memo, our default profile, and several configuration files related to printers etc. An installation consists of : install Acad with all defaults, drag the custom folder from the server into the Acad folder, and import the profile that comes with it. Done -- takes no time at all.

    For regular maintenance, I use an acad.lsp which loads once when Acad is started. It checks the local folder tree against the network master, and downloads anything that's more recent or wasn't there. If I change the menu, I simply post a revised mns (not mnu) and it will get downloaded and recompile automatically as the first drawing loads locally. That was one advantage of mns over mnu -- you didn't have to force a recompilation. All I do is send around a memo saying you might notice such and such changes have been made automatically.

    When we go centralized, I'll probably keep the working copy of our stuff in one location, and a backup master copy somewhere else, read-only. I may still put the "user" folder (in which people are allowed to customized a personal partial menu) on the local machine, since it's the user's responsibility to maintain.
     
    Tom Smith, Apr 8, 2005
    #9
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.