Quantcast
Channel: All Revit API Forum posts
Viewing all articles
Browse latest Browse all 66787

Re: Reload Revit Links From...

$
0
0

Hi ,

 

Thanks for your reply! Your methodology suggestion did actually put me on the right path and I managed to make the tool working!

 

The problem was that my revLinkType parameter was not pointing to the right thing so the script didn't know what to reload. I fixed the issue by pairing the ModelPath and the RevitLinkType through the Zip and Tuple.Create methods. I think it might be a bit of an overkill but I'm not much of an expert right now so I'm just glad it works. Any suggestion/comment is more than welcome

 

I'm copying here my final working script so that everyone with the same issue can have a look and it will maybe help someone:

 

namespace BatchReloadRVTLinks
{
    [Transaction(TransactionMode.Manual)]
    public class Command : IExternalCommand
    {
        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            // Get application and document objects

            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
            Autodesk.Revit.DB.Document doc = uidoc.Document;

            // NO TRANSACTION NEEDS TO BE OPENED

            try
            {
                using (Transaction tx = new Transaction(doc))
                {
                    // Collect files linked in current project

                    FilteredElementCollector collector = new FilteredElementCollector(doc);
                    ICollection<Element> linkInstances = collector.OfClass(typeof(RevitLinkType)).ToElements();

                    // Convert ICollection into a list of RevitLinkTypes

                    List<RevitLinkType> revLinkType = new List<RevitLinkType>();
                    foreach (RevitLinkType i in linkInstances)
                    {
                        revLinkType.Add(i);
                    }

                    // Put names of linked files into a list of strings

                    List<string> linkNames = new List<string>();
                    foreach (Element i in linkInstances)
                    {
                        linkNames.Add(i.Name.Split(' ')[0]);
                    }

                    // Prompt user with files selection dialog

                    Start:
                    OpenFileDialog openFileDialog1 = new OpenFileDialog();
                    openFileDialog1.InitialDirectory = (@"P:\");
                    openFileDialog1.Filter = "RVT|*.rvt";
                    openFileDialog1.Multiselect = true;
                    openFileDialog1.RestoreDirectory = true;

                    // If you select the files and hit OK (in the file browser)

                    if (openFileDialog1.ShowDialog() == DialogResult.OK)
                    {
                        // Show which files (path + version) has been selected before linking them

                        StringBuilder userSelectionWVersion = new StringBuilder();
                        foreach (string fp in openFileDialog1.FileNames)
                        {
                            userSelectionWVersion.AppendLine(
                                fp.ToString()
                                + " which was created with " +
                                BasicFileInfo.Extract(fp).SavedInVersion.ToString().ToUpper());
                        }

                        // Recap the user with his selection + Revit version of the file

                        DialogResult linkCorrect = MessageBox.Show(
                            userSelectionWVersion.ToString(),
                            "You selected the files:",
                            MessageBoxButtons.OKCancel);

                        // Put paths of files selected by user into a list

                        if (linkCorrect == DialogResult.OK)
                        {

                            List<string> userSelectionNames = new List<string>();
                            foreach (string fp in openFileDialog1.FileNames)
                            {
                                userSelectionNames.Add(fp.ToString());
                            }

                            // Check which of the files that the user selected have the same name of the files linked in the project

                            IEnumerable<string> elementsToReload = userSelectionNames.Where(a => linkNames.Exists(b => a.Contains(b)));

                            // Show which files need to be reloaded

                            StringBuilder intersection = new StringBuilder();
                            foreach (string fp in elementsToReload)
                            {
                                   intersection.AppendLine(fp.ToString());
                            }
                            DialogResult temp = MessageBox.Show(intersection.ToString(), "The following files need to be roloaded");

                            // Initialize + populate list of ModelPaths > path from where to reload

                            List<ModelPath> modPaths = new List<ModelPath>();

                            foreach (string fp in elementsToReload)
                            {
                                FileInfo filePath = new FileInfo(fp);
                                ModelPath linkpath = ModelPathUtils.ConvertUserVisiblePathToModelPath(filePath.ToString());
                                modPaths.Add(linkpath);
                            }

                            // Zip together file (as RevitLinkType) and the corresponding path to be reloaded from > Reload

                            foreach(var ab in revLinkType.Zip(modPaths, Tuple.Create))
                            {
                                ab.Item1.LoadFrom(ab.Item2, new WorksetConfiguration());
                            }
                        }

                return Result.Succeeded;
            }

            catch (Exception ex)
            {
                // If something went wrong return Result.Failed

                DialogResult genericException = MessageBox.Show(ex.Message, "Oops there was problem!");

                return Result.Failed;
            }
        }
    }
}

Any comment is highly appreciated as it will help me get better in the future!

 

Also, find attached the test file I was using in case you guys want to give it a try.

 

PS do you know if there is a class/method to get the status of a linked file? (as it appears in the Manage Links window inside of Revit where it says Status = Not Loaded). This would help me optimise the script so I could reload only the files with the Not Loaded Status and avoid useless calculations for the files that are already correctly loaded.

 

Thanks again for the advice.

 

Ciao,

 

Andrea


Viewing all articles
Browse latest Browse all 66787

Trending Articles