Author Topic: Repath xrefs with new path  (Read 22642 times)

0 Members and 1 Guest are viewing this topic.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Repath xrefs with new path
« Reply #30 on: July 21, 2006, 12:52:23 PM »
Tim

Command: REPATHXREF
  Error--> ActiveX Server returned the error: unknown name: FullName
Command:

Gary
Sorry about that, that part was written from memory, guess I was wrong.  Change this spot in the RePathXref sub
Code: [Select]
(if SaveChanges
; (SaveAsEx (vla-get-FullName Doc))
 (vla-SaveAs Doc (vla-get-FullName Doc))
)
to
Code: [Select]
(if SaveChanges
; (SaveAsEx (vla-get-Name Doc))
 (vla-SaveAs Doc (vla-get-Name Doc))
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Repath xrefs with new path
« Reply #31 on: July 21, 2006, 02:18:23 PM »
Tim

Wow, works perfectly...check is being mailed.

Gary
Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Repath xrefs with new path
« Reply #32 on: July 21, 2006, 02:22:39 PM »
Tim

Wow, works perfectly...check is being mailed.

Gary
You're welcome.  Check your pm's before you send any check.   :wink:
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Repath xrefs with new path
« Reply #33 on: July 21, 2006, 02:35:47 PM »
Tim

Thanks, thanks again. This is a great time saver, well worth the cost.

Gary
Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Repath xrefs with new path
« Reply #34 on: July 21, 2006, 02:41:29 PM »
Tim

Wow, works perfectly...check is being mailed.

Gary
What can I say, but THANKS.  :oops:
I still don't think I deserve it, but if you have made up you mind, there is nothing I can do.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Repath xrefs with new path
« Reply #35 on: July 21, 2006, 04:08:21 PM »
Tim,
Would you deny Gary the pleasure of giving?
After all that is why you give isn't it?  8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Repath xrefs with new path
« Reply #36 on: July 21, 2006, 04:25:56 PM »
Now that it's done (good job Tim, and no surprise) let me illuminate a little on the ProjectName variable with regards to some bulk xref repathing I had to do a couple years back.

I worked on a project that had in excess of 5000 (it may have been 11000, that number seems to be familiar) production drawings that referenced some 500 or so different models (xreferences). Each xref would reside in a directory like:

    drive\project\discipline\plant\model.dwg

e.g.

    X:\999\elec\21\21-E-0001.dwg
    X:\999\elec\21\21-E-0002.dwg
    X:\999\elec\21\21-E-0003.dwg
    X:\999\elec\37\37-E-0001.dwg
    X:\999\elec\42\42-E-0001.dwg
    X:\999\elec\63\63-E-0001.dwg

    etc. for the civil, piping, inst ... disciplines


For reasons I won't detail all xrefs were copied to a different drive and folder structure for another need (read "relative xref paths" wouldn't be a quick fix).

e.g.

    z:\client\models\elec\21-E-0001.dwg
    z:\client\models\elec\21-E-0002.dwg
    z:\client\models\elec\21-E-0003.dwg
    z:\client\models\elec\37-E-0001.dwg
    z:\client\models\elec\42-E-0001.dwg
    z:\client\models\elec\63-E-0001.dwg

    etc. for the civil, piping, inst ... disciplines


So --

I wrote a routine to repath the xrefs based on the paths associated with the current ProjectName, as said variable will host multiple paths, not just one.

e.g. ProjectName "Repath999" might have had these paths --

    z:\client\models\elec
    z:\client\models\civil
    z:\client\models\piping
    z:\client\models\inst


Stored in the registry as --

    "z:\client\models\elec;z:\client\models\civil;z:\client\models\piping;z:\client\models\inst"

I could have done it differently, but it served other repathing needs that emerged about the same time that could also exploit the ProjectName variable, i.e. have the user select a ProjectName value from a list (i.e. read the resistry and display all the valid ProjectName values) and then repath all xrefs accordingly.

Anyway --

As the code was written for a client I just bashed this all out anew to demonstrate (hopefully no bugs). First the core code which knows nothing of the ProjectName variable, it just blithely repaths each xref in the supplied document (read objectDbx compatible) to the first path that resolves and repaths without error in a list of alternate paths.

Code: [Select]
(defun _RepathXrefs ( document paths / _GetXrefNames _RepathXref _Main )

    ;;  repath each xref in the document to the first path
    ;;  in the list of supplied paths that resolves and repaths
    ;;  without error

    (defun _GetXrefNames ( document / result )

        ;;  get the document's xref names

        (vlax-for block (vla-get-blocks document)
            (if (eq :vlax-true (vla-get-isxref block))
                (setq result
                    (cons (vla-get-name block)
                        result
                    )
                )
            )
            result
        )
    )

    (defun _RepathXref ( xref paths )

        ;;  attempt to repath the xref to the first path in
        ;;  the supplied alternate paths that hosts the xref's
        ;;  filename AND can be remapped to w/out error
        ;;
        ;;  note, each path in the paths argument is expected
        ;;  to be valid and clean, no terminating back or forward
        ;;  slashes

        (   (lambda ( filename )
                (vl-some
                   '(lambda ( candidatePath / tryPath result )
                        (cond
                            (   (findfile
                                    (setq tryPath
                                        (strcat
                                            candidatePath
                                            "\\"
                                            filename
                                        )
                                    )
                                )
                                (vl-catch-all-apply
                                   '(lambda ( )
                                        (vla-put-path xref tryPath)
                                        (setq result t)
                                    )
                                )
                                result
                            )
                        )
                    )
                    paths
                )
            )
            (strcat (vl-filename-base (vla-get-path xref)) ".dwg")
        )
    )

    (defun _Main ( document paths / xrefNames )

        ;;  get the document's xref names

        (setq xrefNames (_GetXrefNames document))

        ;;  iterate the xrefs in the document, trying to
        ;;  remap 'em to the first valid path found in the
        ;;  supplied paths

        (vlax-for layout (vla-get-layouts document)
            (vlax-for object (vla-get-block layout)
                (if (eq "AcDbBlockReference" (vla-get-objectname object))
                    (if (member (vla-get-name object) xrefNames)
                        (_RepathXref object paths)
                    )
                )
            )
        )
    )

    (_Main document paths)

)

Now an example program that repaths xrefs in the current document to the first valid path in the paths associated with the ProjectName's current value.

Code: [Select]
(defun c:Example ( / _GetProjectPath _SearchPathToList _Main *debug* )

    ;;  use the paths associated with the projectname
    ;;  variable as an alternate path for each xref
    ;;  in the current document

    (defun _GetProjectPath ( name )

        ;;  get the paths associate with the project
        ;;  name (note: result if non nil will be semi
        ;;  colon delimited string)

        (vl-registry-read
            (strcat "HKEY_CURRENT_USER\\"
                (vlax-product-key)
                "\\Profiles\\"
                (getvar "cprofile")
                "\\Project Settings\\"
                Name
            )
            "RefSearchPath"
        )
    )

    (defun _SearchPathToList ( searchPath / path result )

        (foreach code (reverse (vl-string->list searchPath))
            (if (eq 59 code) ;; ascii ";" = 59
                (if path
                    (setq
                        result (cons path result)
                        path   nil
                    )
                )
                (setq path (cons code path))
            )
        )

        (mapcar
           '(lambda (lst) (vl-string-right-trim "/\\" (vl-list->string lst)))
            (if path (cons path result) result)
        )

    )

    (defun _Main ( document / paths )

        ;;  if there are paths associated with
        ;;  the current projectname ...

        (cond
            (
                (setq paths
                    (_GetProjectPath
                        (vlax-invoke
                            document
                           'GetVariable
                           "projectname"
                        )
                    )
                )

                ;;  do it

                (_RepathXrefs
                    document
                    (_SearchPathToList paths)
                )

                ;;  reload all xrefs

                (vlax-for block (vla-get-blocks document)
                    (if (eq :vlax-true (vla-get-isxref block))
                        (vla-reload block)
                    )
                )

                ;;  force a regen

                (vla-regen
                    document
                    acAllViewports
                )
            )
        )

        (princ)

    )

    (_Main
        (vla-get-activedocument
            (vlax-get-acad-object)
        )
    )

)

Hope it makes sense.

:)
« Last Edit: July 21, 2006, 06:47:17 PM by mp »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Repath xrefs with new path
« Reply #37 on: July 21, 2006, 05:02:04 PM »
Tim,
Would you deny Gary the pleasure of giving?
After all that is why you give isn't it?  8-)
I'm modest about stuff that I'm not good at, so I don't feel the need is there, that is all I'm trying to say.  I argued with him all I could, and I gave in to what he wants.  You make a good point Alan.

Now that it's done (good job Tim, and no surprise) let me illuminate a little on the ProjectName variable with regards to some bulk xref repathing I had to do a couple years back.

<snip>

Hope it makes sense.

:)
Good explaination Michael, and good example of coding it.  Oh yea, thanks for the kudos. :wink:
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Repath xrefs with new path
« Reply #38 on: July 21, 2006, 05:04:27 PM »
Anyway --

As the code was written for a client I just bashed this all out anew to demonstrate (hopefully no bugs). First the core code which knows nothing of the ProjectName variable, it just blithely repaths each xref in the supplied document (read objectDbx compatible) to the first path that resolves and repaths without error in a list of alternate paths.


Hope it makes sense.

:)

Michael

I'm lost. So how is this routine to be used?

Gary
Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Repath xrefs with new path
« Reply #39 on: July 21, 2006, 05:04:51 PM »
One thing I should note about the ProjectName variable, and something that's annoying (which my coding addresses).

Say you have a bunch of xrefs that don't resolve because their paths have changed. You create a ProjectName c/w the new paths and make it active. Save the drawing then re-open it. Now all the xrefs resolve =BUT= AutoCAD does not update each xre's path. That is, if you check its properties it still points to the invalid path.

But back to Gary's original inquirey, using the code I previously supplied his challenge could be solved via the following pseudo code --

Code: [Select]
(defun c:PseudoCode ( / axDbDocument )
    (foreach fullpath (MyGetFilesFunction "F:\\Jobs\\2005\\050112\\*.dwg")
        (if (setq axDbDocument (MyOpenAxDbDocument fullpath))
            (progn           
                (_RepathXrefs AxDbDocument '("F:\\Jobs\\2006\\060614"))
                (MySaveAxDbDocument axDbDocument fullpath)
                (vlax-release-object axDbDocument)
            )
        )
    )
    (princ)
)

FWIW; cheers.

PS: As I was posting this Tim snuck in a post: Thanks and my pleasure Tim => you're a generous friend and resource to all swampers. So did Gary: See snip above.

:)
« Last Edit: July 21, 2006, 05:06:16 PM by mp »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Repath xrefs with new path
« Reply #40 on: July 21, 2006, 05:07:48 PM »
On a side note, Tony T. also provide the source code for the arx file (at least I think it is), so it can be recompiled for future releases.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Repath xrefs with new path
« Reply #41 on: July 21, 2006, 05:11:06 PM »
On a side note, Tony T. also provide the source code for the arx file (at least I think it is), so it can be recompiled for future releases.

Even though I don't use it a nod of appreciation to Mr. Tanzillo.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Repath xrefs with new path
« Reply #42 on: July 21, 2006, 05:14:06 PM »
On a side note, Tony T. also provide the source code for the arx file (at least I think it is), so it can be recompiled for future releases.

Even though I don't use it a nod of appreciation to Mr. Tanzillo.
I still read his post, because he knows a lot, and has helped me out a lot.  I wonder if he has calmed down since you were on the Adesk site.  I come across some post where you two would battle with ideas and opinions when searching for stuff.  I like those because I can learn a lot of different ways to skin a cat. :-D
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

GDF

  • Water Moccasin
  • Posts: 2081
Re: Repath xrefs with new path
« Reply #43 on: July 21, 2006, 05:28:17 PM »
One thing I should note about the ProjectName variable, and something that's annoying (which my coding addresses).

Say you have a bunch of xrefs that don't resolve because their paths have changed. You create a ProjectName c/w the new paths and make it active. Save the drawing then re-open it. Now all the xrefs resolve =BUT= AutoCAD does not update each xre's path. That is, if you check its properties it still points to the invalid path.

But back to Gary's original inquirey, using the code I previously supplied his challenge could be solved via the following pseudo code --

Code: [Select]
(defun c:PseudoCode ( / axDbDocument )
    (foreach fullpath (MyGetFilesFunction "F:\\Jobs\\2005\\050112\\*.dwg")
        (if (setq axDbDocument (MyOpenAxDbDocument fullpath))
            (progn           
                (_RepathXrefs AxDbDocument '("F:\\Jobs\\2006\\060614"))
                (MySaveAxDbDocument axDbDocument fullpath)
                (vlax-release-object axDbDocument)
            )
        )
    )
    (princ)
)

FWIW; cheers.

PS: As I was posting this Tim snuck in a post: Thanks and my pleasure Tim => you're a generous friend and resource to all swampers. So did Gary: See snip above.

:)

Michael

MyGetFilesFunction?
MySaveAxDbDocument?
MyOpenAxDbDocument?

Gary





Why is there never enough time to do it right, but always enough time to do it over?
BricsCAD 2020x64 Windows 10x64

Bob Wahr

  • Guest
Re: Repath xrefs with new path
« Reply #44 on: July 21, 2006, 05:29:11 PM »
It's not how one skins the cat but the sauce one serves it with which matters most.
I should write fortune cookies