EPLAN-API

Alles rund um die API in EPLAN

BackgroundWorker in der EPLAN API

… geht offiziell nicht. Steht auch so in der Dokumentation. Darum hier gleich der Vermerk: Es handelt sich um eine interne Funktionalität welche nicht supported wird.

Dennoch hat es genau mein Problem gelöst:
Ich habe eine ProgressBar welche über einen BackgroundWorker viel Arbeit macht. An paar Stellen brauche ich die EPLAN API. Hier hatte ich aber komisches Verhalten (DLLs wurden nicht gefunden, usw.).
Zurückzuführen war es darauf dass der EPLAN Thread nicht wusste wo er suchen soll.

Mit EplanMainThreadDispatcher  gibt es die Möglichkeit Code im Dispatcher und somit im Thread von EPLAN auszuführen. Hier ein Beispiel:

new EplanMainThreadDispatcher().ExecuteInMainThreadSync(o =>
{
  new CommandLineInterpreter().Execute("reports /TYPE:PROJECT");
  return null;
}, null);

Hab mir das mal bisl vereinfacht mit einer Helper-Klasse:

using Eplan.EplApi.Base.Internal;
using Action = System.Action;

namespace Suplanus.Sepla.Application
{
  public class EplanDispatcher
  {
    public static void ExecuteInMainThread(Action action)
    {
      new EplanMainThreadDispatcher().ExecuteInMainThreadSync(o =>
      {
        action.Invoke();
        return null;
      }, null);
    }
  }
}

Dann brauch ich nur noch:

EplanDispatcher.ExecuteInMainThread(() =>
  {
    new CommandLineInterpreter().Execute("reports /TYPE:PROJECT");
  }
);
Von |2018-07-19T10:53:25+02:002018-06-01|EPLAN, EPLAN-API|

EPLAN-API: Showcase 2018 April

Mit dem MacroTool ist es möglich schnell und einfach Makros zu erzeugen. Es spart viel Zeit bei der Erstellung von Bauteil-, Pro Panel-, Fenster- und Seitenmakros…
Hier mal die Funktionen / Actions im Überblick:

 

Create – Electric P8

  • Artikel anlegen / aktualisieren
  • Funktionsschablone erstellen
  • Seiten im Makroprojekt erstellen
  • Gerät im Makroprojekt einfügen
  • Makrokasten einfügen und alle notwendigen Eigenschaften füllen
  • Makro erzeugen
  • Link in Artikelverwaltung eintragen

 

Create – Pro Panel

  • Artikel anlegen / aktualisieren
  • Bauraum im Makroprojekt erstellen
  • Gerät im Bauraum einfügen
  • Makrodaten einfügen und alle notwendigen Eigenschaften füllen
  • Makro erzeugen
  • Link in Artikelverwaltung eintragen

 

CreateNeutral
Gleich zu Create mit dem Unterschied dass die Zielstruktur, in der das Makro gespeichert werden soll, angegeben wird.

 

NewVariant
Es wird ein Dialog angezeigt, zur Auswahl der Darstellungsart und Variante der neuen Makro-Variante. Es wird die nächste freie Variante der Darstellungsart automatisch ausgewählt. Nach bestätigen mit OK wird die Seite erzeugt und ein Makrokasten mit gefüllten Informationen eingefügt.

 

SelectMacro
Es wird das Makroprojekt geöffnet und an die Seite des Makros gesprungen.

 

Set
Makropfade und Eigenschaften werden an Makrokasten, Seite oder Bauraum geschrieben.

 

Es sind mehrere Videos in der Youtube Playlist:

Von |2018-07-19T10:54:38+02:002018-05-04|EPLAN, EPLAN-API|

LockingVector

Jeder der in der EPLAN API programmiert, kennt die Aufwände beim Locking. Es ist mir nicht immer ganz klar wann was zu verwenden ist. LockingVector sollte nur in Ausnahmefällen verwendet werden, es kann zu unschönen Verhalten kommen. Auch so in der API-Hilfe beschrieben.

Der LockingVector hebelt das Locking komplett aus und die API verhält sich ähnlich wie die Oberfläche. Hört sich gut an, aber wie gesagt für mich nur mit Vorsicht zu genießen.

Dennoch gibt es für mich einen Anwendungsfall: Interne EPLAN Action im API ausführen… Ja manchmal muss man das. Hatte mit Auswertungen aktualisieren den Fall:

LockingVector lockingVector = new LockingVector();
int manualLockStateId = lockingVector.PauseManualLock();

new CommandLineInterpreter().Execute("XFgUpdateEvaluationAction");

lockingVector.ResumeManualLock(manualLockStateId);

Wichtig ist dass ResumeManualLock()  nicht vergessen wird… Ich hab mir das mal in ein Using gepackt, das sich um alles kümmert und auch die Klasse auf GitHub bereitgestellt:

using (new LockingUtility.SeplaLockingVector())
{
  new CommandLineInterpreter().Execute("XFgUpdateEvaluationAction");
}
Von |2018-01-26T14:43:53+01:002018-01-24|EPLAN, EPLAN-API|

Artikel mit Funktionsschablone erzeugen

Schnell mal per API Artikel mit Funktionsschablone erzeugen war meine Aufgabe…
Naja nicht so einfach:

public static MDPart CreateOrUpdateWithFunctionTemplate(Function function)
{
    // Need to lock project
    var project = function.Project;
    project.SmartLock();
    function.SmartLock();

    // Init
    var partsDatabase = new MDPartsManagement().OpenDatabase();
    var articleReference = function.ArticleReferences.First();
    articleReference.SmartLock();
    var partNr = articleReference.PartNr;
    var partVariant = articleReference.VariantNr;
    MDPart part = partsDatabase.GetPart(partNr, partVariant);

    // Create new part
    if (part == null)
    {
        // LockingVector is needed because of locking exception from EPLAN action (no catch possible)
        LockingVector lockingVector = new LockingVector();
        int stateId = lockingVector.PauseManualLock();
        new CommandLineInterpreter().Execute("XPameCreateType");
        lockingVector.ResumeManualLock(stateId);

        partsDatabase = new MDPartsManagement().OpenDatabase(); // Second Call needed to get new part
        part = partsDatabase.GetPart(partNr, partVariant);                
    }
    else
    {
        // Rename part
        string suffix = "_temp";
        string partNrTemp = part.PartNr + suffix;
        try
        {
            articleReference.PartNr = partNrTemp;
            articleReference.StoreToObject();

            // Quiet create temp part
            var application = new EplApplication();
            var quiteMode = application.QuietMode;
            application.QuietMode = EplApplication.QuietModes.ShowNoDialogs;
            new CommandLineInterpreter().Execute("XPameCreateType");
            application.QuietMode = quiteMode;
        }
        finally
        {
            // Rename back
            articleReference.PartNr = partNr;
            articleReference.StoreToObject();
        }

        // Copy FunctionTemplate
        partsDatabase = new MDPartsManagement().OpenDatabase(); // Second Call needed to get new part
        MDPart partDuplicate = partsDatabase.GetPart(partNrTemp, partVariant);
        foreach (var partFunctionTemplatePosition in part.FunctionTemplatePositions)
        {
            part.RemoveFunctionTemplatePosition(partFunctionTemplatePosition);
        }
        foreach (var partDuplicateFunctionTemplatePosition in partDuplicate.FunctionTemplatePositions)
        {
            part.AddFunctionTemplatePosition(partDuplicateFunctionTemplatePosition);
        }

        partsDatabase.RemovePart(partDuplicate);


        // Check if article is in project
        var existingArticle = project.Articles
            .FirstOrDefault(obj =>
            obj.PartNr.Equals(partNrTemp) && obj.VariantNr.Equals(partVariant)
            );
        if (existingArticle != null)
        {
            existingArticle.SmartLock();
            existingArticle.Remove();
        }
    }

    // Load data
    var article = project.Articles
        .FirstOrDefault(obj =>
            obj.PartNr.Equals(partNr) && obj.VariantNr.Equals(partVariant)
        );
    if (article != null)
    {
        article.SmartLock();
        article.LoadFromMasterdata();
    }

    return part;
}

Es darf nur ein Artikel hinterlegt sein, sonst schlägt die Action XPameCreateType  fehl. Ist nicht schön, aber die Funktionsschablone von Hand zu erstellen ist mir zu heikel. Denn da kommt ja oftmals was neues dazu :^)

Von |2017-11-23T12:42:26+01:002017-11-22|EPLAN, EPLAN-API|

UndoStep & SafetyPoint

Man ist es gewohnt über Bearbeiten Rückgängig  zu arbeiten…
Aber das geht nicht von alleine, mann muss schon was dafür tun.

EPLAN stellt hier zwei Klassen bereit, welche das sehr gut implementieren. Muss sagen ich nutze für Schreiboperationen (ab sofort) immer Beide.
UndoStep lässt den User die Möglichkeit die Bearbeitung per API rückgängig zu machen. SafetyPoint stellt den Ursprung wieder her, falls eine Exception auftritt.

Toller Nebeneffekt, man muss sich nicht ums Locking der erzeugten Elemente kümmern :)

public void DoStuff()
{
    using (var undoStep = new UndoManager().CreateUndoStep())
    {
        undoStep.SetUndoDescription("DoStuff");
        using (SafetyPoint safetyPoint = SafetyPoint.Create())
        {
            try
            {
                // Do wild stuff
                safetyPoint.Commit();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                safetyPoint.Rollback();
            }
        }
    }
}
Von |2017-11-16T09:41:37+01:002017-11-16|EPLAN, EPLAN-API|
Nach oben