In ETAS INCA, is there a way to quickly retrieve an item from an arbitrary path in an ASAP2Project?

折月煮酒 提交于 2021-02-07 11:12:53

问题


I'm trying to connect to INCA through the .NET API in order to navigate the folder structure of an ASAP2 project. Specifically, I want to get an object that represents the "Target" folder that I've highlighted below.

enter image description here

This is proving pretty tricky--The API provides a ton of classes that have the name "Folder" in them: Folder, Asap2ProjectFolder, and IncaFolder. So what do I need to know in order to retrieve the "Target" folder?


回答1:


Your first impulse might be to think of the Target folder as existing on a long path like USER A\Demo\Demo03\Foo\Bar\Baz\Target. Unfortunately, INCA doesn't have a mechanism to do this--instead, you have to retrieve the lowest item in the Database Objects portion of the path, and then query that item for the Datasets portion of the path.

From the database root, we need to drill down to Demo03, which is an Asap2Project:

USER A\Demo\Demo03

From within Demo03, we then need to drill down to Target, which is an Asap2ProjectFolder:

Foo\Bar\Baz\Target

The first part is pretty simple--we can connect to INCA and get the Demo03 Asap2Project in just a few lines of code:

Asap2ProjectFolder targetFolder = null;
Inca myIncaInstance = new Inca();
DataBase myDB = myIncaInstance.GetCurrentDataBase();
DataBaseItem tempItem = myDB.GetItemInFolder("Demo03", "USER A\\Demo");

if ((tempItem != null) && 
    (tempItem.IsAsap2Project()))
   {
   Asap2Project demoProject = (Asap2Project)tempItem;

   // Next step: grab the "Target folder!"
   }

Now, here's where things get a bit tricky.

If we were trying to get a DataSet like Demo03_1, we could use a call like demoProject.GetDataSetForName("Demo03\\Demo03_1"). The problem is, this method only works for objects of type DataSet. So we can't use it to retrieve a folder like Foo\Bar\Baz\Target. If you've poked around in the API a bit, you might have tried something like this:

Asap2ProjectFolder tempProjFolder = demoProject.GetTopFolderNamed("Foo");
tempItem = tempProjFolder.GetDataBaseItem("Bar\\Baz\\Target");  // Won't work.
tempItem = tempProjFolder.GetSubFolder("Bar\\Baz\\Target");     // This won't either.

Turns out that we need to be a bit more resourceful. Let's make GetItemInFolder() extension methods for the Asap2Project and Asap2ProjectFolder classes, so those classes will have the same item-retrieval flexibility as the DataBase class:

namespace IncaExtensions
   {
   public static class GetItemInFolderExtensions
      {
      /// <summary>
      /// Gets a DataBaseItem from an Asap2Project in an arbitrary subfolder.
      /// </summary>
      /// <param name="project">The current Asap2Project</param>
      /// <param name="itemName">The name of the item that we want to retrieve</param>
      /// <param name="folderName">The path, delimited by backslashes ('\\')</param>
      /// <returns>A DataBaseItem matching the request.  
      /// If no matching item is found, or if the path is invalid, return null.
      /// </returns>
      public static DataBaseItem GetItemInFolder(this Asap2Project project, 
                                                 string itemName, 
                                                 string folderName)
         {
         DataBaseItem returnItem = null;

         if ((folderName != null) &&
             (itemName != null))
            {
            string folderToken = PluckPathToken(ref folderName);
            Asap2ProjectFolder subFolder = 
               project.GetTopFolderNamed(folderToken);

            if (subFolder != null)
               {
               returnItem = subFolder.GetItemInFolder(itemName, folderName); 
               }
            }

         return returnItem;
         }


      /// <summary>
      /// Recursive call that returns a DataBaseItem in the target path.
      /// </summary>
      /// <param name="folder">The Asap2ProjectFolder to drill down</param>
      /// <param name="itemName">The name of the item that we want to retrieve</param>
      /// <param name="folderName">The path, delimited by backslashes ('\\')</param>
      /// <returns>A DataBaseItem matching the request.  
      /// If no matching item is found, or if the path is invalid, return null.
      /// </returns>
      public static DataBaseItem GetItemInFolder(this Asap2ProjectFolder folder, 
                                                 string itemName, 
                                                 string folderName)
         {
         DataBaseItem returnItem = null;

         if ((folderName != null) &&
             (itemName != null))
            {
            string folderToken = PluckPathToken(ref folderName);
            Asap2ProjectFolder subFolder = 
               (Asap2ProjectFolder)folder.GetSubFolder(folderToken);

            if (subFolder != null)
               {
               returnItem = subFolder.GetItemInFolder(itemName, folderName);
               }
            }
         else
            {
            returnItem = folder.GetDataBaseItem(itemName);
            }

         return returnItem;
         }


      /// <summary>
      /// Removes a backslash-delimited token from a string and shortens the
      /// input string.
      /// </summary>
      /// <param name="folderName">Backslash-delimited path.  This will be 
      /// shortened each time a token is removed.</param>
      /// <returns>The latest path token</returns>
      static string PluckPathToken(ref string folderName)
         {
         int slashIdx = folderName.IndexOf('\\');

         // If folderName has path tokens, extract the first token and
         // shorten folderName accordingly.
         string folderToken = (slashIdx > -1) ? 
            folderName.Substring(0, slashIdx) : folderName;
         folderName = (slashIdx > -1) ? 
            folderName.Substring(slashIdx + 1) : null;

         return folderToken;
         }
      }
   }

This makes it super-easy to grab items out of an Asap2Project or Asap2ProjectFolder. To grab the Target folder, we only need the following calls:

using IncaExtensions;
...
Asap2ProjectFolder targetFolder = null;
Inca myIncaInstance = new Inca();
DataBase myDB = myIncaInstance.GetCurrentDataBase();
DataBaseItem tempItem = myDB.GetItemInFolder("Demo03", "USER A\\Demo");

if ((tempItem != null) && 
    (tempItem.IsAsap2Project()))
   {
   Asap2Project demoProject = (Asap2Project)tempItem;
   targetFolder = (Asap2ProjectFolder)demoProject.GetItemInFolder("Target", "Foo\\Bar\\Baz");
   }


来源:https://stackoverflow.com/questions/18214951/in-etas-inca-is-there-a-way-to-quickly-retrieve-an-item-from-an-arbitrary-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!