Archiv für das Jahr: 2024

“Wörter nicht übersetzen” in die Datenbank einlesen

Leider geht das nicht direkt über das Datenmodell.
Aber mein grandioser Kollege Daniel hatte die Idee es über den XML Import des Wörterbuchs mal zu probieren. Siehe da, dies funktioniert.

Somit brauchen wir DTO-Klasse für das Import-Format:

<?xml version="1.0" encoding="utf-8"?>
<EplanLanguageDbRoot>
  <NonTranslateSection>
    <NTW>Foo</NTW>
    <NTW>Bar</NTW>
  </NonTranslateSection>
</EplanLanguageDbRoot>
[XmlRoot("EplanLanguageDbRoot")]
public class EplanTranslationsDto
{
  [XmlArray("NonTranslateSection")]
  [XmlArrayItem("NTW")]
  public List<string> NonTranslatedWords { get; set; } = new();
}

Das ganze speichern wir als XML und importieren es über die Standard-Action, welche auch im Scripting verfügbar ist:

private static void ImportXmlToTranslations(string filename)
{
  ActionCallingContext acc = new ActionCallingContext();
  acc.AddParameter("TYPE", "IMPORTTOTRANSDB");
  acc.AddParameter("IMPORTFILE", filename);
  acc.AddParameter("CONVERTER", "XTrLanguageDbXmlConverterImpl");
  new CommandLineInterpreter().Execute("translate", acc);
}
Von |2024-10-28T08:18:52+01:002024-10-28|EPLAN, EPLAN-Scripts|

EPLAN 2025: Scripting Neuerungen

Folgende Änderungen gab es im Scripting:

  • XCCreateGravingtextAction Erzeugt einen Graviertext aus den BMK von Quelle und Ziel des Kabels. Die Bezeichnung wird entsprechend dem VASS-Standard (Volkswagen Audi Seat Skoda) gekürzt.
  • XCabCalculateEnclosureTotalWeightAction Berechnet das Gesamtgewicht eines Schrankes und schreibt es in die Eigenschaft „Gesamtgewicht“ (#36108 – FUNCTION3D_CABINET_TOTALWEIGHT)
Von |2024-10-17T06:56:57+02:002024-10-16|EPLAN, EPLAN-Scripts|

AutoSyncNavis

Mit diesem Script werden Navigatoren automatisch mit der aktuellen Selektion synchronisiert.
Vielen Dank an FrankS für das Erstellen 💖

Achtung: Je nachdem wie viele Navigatoren geöffnet sind und wie groß das Projekt ist, kann sich das Script negativ auf die Perfomance auswirken.

// AutoSyncNavis.cs
//
// Nachdem das Script geladen wurde kann das Synchronisieren aller Navigatoren mit dem
// ausgewählten Element im GED aktiviert werden.
//
// Es wird ein neuer Menüpunkt "AutoSync Navigatoren" in der Gruppe "Erweiterung" im Tab "Ansicht" angelegt,
// außerdem wird die aktuelle Einstellung gespeichert.
//
// Copyright by Frank Schöneck, 2024
//
// letzte Änderung:
// V1.0.0, 23.07.2024, Frank Schöneck, Projektbeginn

using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.Base;
using Eplan.EplApi.Gui;
using Eplan.EplApi.Scripting;
using System.Linq;

public class AutoSyncNavis
{
    private string sSettingName = "USER.SCRIPTS.AutoSyncNavis.AutoSyncState";

    //RibbonBar Einträge definieren
    string m_TabName = "Ansicht";
    string m_commandGroupName = "Erweiterungen";
    string m_commandName = "AutoSync";
    string m_SVGstringIconNavigator = @"<svg fill='#464646' height='800px' width='800px' version='1.1' id='XMLID_85_' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 24 24' enable-background='new 0 0 24 24' xml:space='preserve'>
        <path d='M21,24h-6v-6h6V24z M17,22h2v-2h-2V22z M15,22H6V8H3V0h8v8H8v4h7v2H8v6h7V22z M5,6h4V2H5V6z M21,16h-6v-6h6V16z M17,14h2 v-2h-2V14z'/>
        </svg>";


    [DeclareRegister]
    public void registerRibbonItems()
    {
        RibbonBar ribbonBar = new RibbonBar();
        var newTab = new Eplan.EplApi.Gui.RibbonBar().Tabs.FirstOrDefault(item => item.Name == m_TabName);
        if (newTab == null) //Tab noch nicht vorhanden, dann neu erzeugen
        {
            newTab = new Eplan.EplApi.Gui.RibbonBar().AddTab(m_TabName);
        }
        var commandGroup = newTab.CommandGroups.FirstOrDefault(item => item.Name == m_commandGroupName);
        if (commandGroup == null) //CommandGroup noch nicht vorhanden, dann neu erzeugen
        {
            commandGroup = newTab.AddCommandGroup(m_commandGroupName);
        }
        RibbonIcon ribbonIconNavigator = ribbonBar.AddIcon(m_SVGstringIconNavigator); //Icon festlegen
        commandGroup.AddCommand(m_commandName, "AutoSyncNavis", m_commandName, "AutoSync der Navigatoren ein- / ausschalten", ribbonIconNavigator);
    }

    [DeclareUnregister]
    public void unRegisterRibbonItems()
    {
        //Command entfernen
        var vTab = new Eplan.EplApi.Gui.RibbonBar().Tabs.FirstOrDefault(item => item.Name == m_TabName);
        if (vTab != null)
        {
            var commandGroup = vTab.CommandGroups.FirstOrDefault(item => item.Name == m_commandGroupName);
            if (commandGroup != null)
            {
                var command = commandGroup.Commands.Values.FirstOrDefault(item => item.Text == m_commandName);
                if (command != null)
                {
                    command.Remove();
                }
                //Wenn CommandGroup leer ist diese auch entfernen
                if (commandGroup.Commands.Count == 0)
                {
                    commandGroup.Remove();
                }
            }
            //Wenn Tab leer ist dieses auch entfernen
            if (vTab.Commands.Count == 0)
            {
                vTab.Remove();
            }
        }
        //Einstellungen löschen
        DeleteSettings();

    }

    [DeclareAction("AutoSyncNavis")]
    public void AutoSyncNavisAction()
    {
        Settings oSettings = new Settings();

        string sAutoSyncState = string.Empty;
        if (oSettings.ExistSetting(sSettingName))
        {
            sAutoSyncState = oSettings.GetStringSetting(sSettingName, 0);
        }

        //Prüfen ob AutoSync aktiviert ist
        if (sAutoSyncState == string.Empty | sAutoSyncState.ToUpper() != "ON")
        {
            //nicht aktiviert
            Decider eDecision = new Decider();
            EnumDecisionReturn eAnswer = eDecision.Decide(
                EnumDecisionType.eYesNoDecision,
                "Soll das Auto-Synchronisieren der Navigatoren eingeschaltet werden?",
                "AutoSyncNavis",
                EnumDecisionReturn.eYES,
                EnumDecisionReturn.eNO,
                string.Empty,
                false,
                EnumDecisionIcon.eQUESTION);
            if (eAnswer == EnumDecisionReturn.eYES)
            {
                //Einstellung speichern
                SetSettings("ON");
            }
        }
        else
        {
            Decider eDecision = new Decider();
            EnumDecisionReturn eAnswer = eDecision.Decide(
                EnumDecisionType.eYesNoDecision,
                "Soll das Auto-Synchronisieren der Navigatoren ausgeschaltet werden?",
                "AutoSyncNavis",
                EnumDecisionReturn.eYES,
                EnumDecisionReturn.eNO,
                string.Empty,
                false,
                EnumDecisionIcon.eQUESTION);
            if (eAnswer == EnumDecisionReturn.eYES)
            {
                //Einstellung speichern
                SetSettings("OFF");
            }
        }
        return;
    }

    //Einstellungen speichern
    private void SetSettings(string AutoSyncActive)
    {
        Settings oSettings = new Settings();
        if (!oSettings.ExistSetting(sSettingName))
        {
            oSettings.AddStringSetting(sSettingName,
                new string[] { },
                new string[] { },
                ISettings.CreationFlag.Insert);
        }
        oSettings.SetStringSetting(sSettingName, AutoSyncActive, 0);
    }

    //Einstellungen löschen
    public void DeleteSettings()
    {
        Settings oSettings = new Settings();
        if (oSettings.ExistSetting(sSettingName))
        {
            oSettings.DeleteSetting(sSettingName);
            new Decider().Decide(EnumDecisionType.eOkDecision,
                "Die Einstellung [" + sSettingName + "] wurde gelöscht.",
                "AutoSyncNavis",
                EnumDecisionReturn.eOK,
                EnumDecisionReturn.eOK,
                string.Empty,
                false,
                EnumDecisionIcon.eINFORMATION);
        }
        else
        {
            new Decider().Decide(EnumDecisionType.eOkDecision,
                "Die Einstellungen wurden nicht gefunden!",
                "AutoSyncNavis",
                EnumDecisionReturn.eOK,
                EnumDecisionReturn.eOK,
                string.Empty,
                false,
                EnumDecisionIcon.eFATALERROR);
        }
    }

    //Eine Element wurde markiert
    [DeclareEventHandler("onSelChanged")]
    public void MyEventOnSelChanged()
    {
        Settings oSettings = new Settings();
        string sAutoSyncState = string.Empty;
        if (oSettings.ExistSetting(sSettingName))
        {
            sAutoSyncState = oSettings.GetStringSetting(sSettingName, 0);
        }

        //Prüfen ob AutoSync aktiviert ist
        if (sAutoSyncState == string.Empty | sAutoSyncState.ToUpper() != "ON")
        {
            //Keine Aktion ausführen
            return;
        }
        else
        {
            //Setting existiert und AutoSync soll aktiviert werden
            new CommandLineInterpreter().Execute("XEsSyncPDDsAction");
        }
        return;
    }

    //Prüft ob Eplan gestartet wurde
    [DeclareEventHandler("Eplan.EplApi.OnMainStart")]
    public void MyEventEplanStart()
    {
        Settings oSettings = new Settings();
        string sAutoSyncState = string.Empty;

        //War AutoSync beim letzten mal aktiv?
        if (oSettings.ExistSetting(sSettingName))
        {
            sAutoSyncState = oSettings.GetStringSetting(sSettingName, 0);

            //wenn ja ("ON") dann AutoSync aktivieren
            if (sAutoSyncState.ToUpper() == "ON")
            {
                new CommandLineInterpreter().Execute("XEsSyncPDDsAction");
            }
        }
        return;
    }
}

 

Von |2024-07-25T10:40:08+02:002024-07-25|EPLAN, EPLAN-Scripts|

XPartsSetDataSourceAction: Artikelverwaltung Datenquelle wählen

Auch still und heimlich kam eine neue Action hinzu: XPartsSetDataSourceAction.
Mit dieser Action kann schnell und einfach die aktive Artikeldatenbank eingestellt werden.

Ihr findet alle Parameter mit Beschreibung hier in der EPLAN Hilfe.

Lokale Datenbank

XPartsSetDataSourceAction /DataSourceType:0 /DataBaseFileName:C:\Users\Public\EPLAN\Data\Article\COMPANY_NAME\Database.alk

 

SQL Datenbank: Windows Authentifizierung

XPartsSetDataSourceAction /DataSourceType:1 /SqlLogin:0 /SqlServer:SQL_SERVER_NAME /SqlCatalog:SQL_DATABASE

 

SQL Datenbank: SQL Authentifizierung

XPartsSetDataSourceAction /DataSourceType:1 /SqlLogin:1 /SqlServer:SQL_SERVER_NAME /SqlCatalog:SQL_DATABASE /SqlUserName:SQL_USERNAME /SqlPassword:SQL_PASSWORD

 

eStock

XPartsSetDataSourceAction /DataSourceType:3 /CollectionName:ESTOCK_COLLECTION_NAME /CollectionId:ESTOCK_COLLECTION_ID
Von |2024-03-27T12:46:06+01:002024-03-27|EPLAN, EPLAN-Scripts|

TransparencySlider

Mein Kollege Daniel hat wieder mal was schönes für uns gezaubert 🪄

Mit diesem Script könnt Ihr schnell und einfach die Transparenz von Bauteilen in Pro Panel verändern:

Warnung: Das Script nutzt Reflection um auf die Ebene des 3D Objekts zuzugreifen. Wir empfehlen klar solche Funktionen im Script nicht zu verwenden und stattdessen die API zu nutzen!

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Xml;
using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.Gui;
using Eplan.EplApi.Scripting;

namespace DanielPa.Scripting.Prototypes
{
  public class TransparencySlider
  {
    private const string ATTRIBUTE_LAYER_NAME = "A1424";
    private const string ATTRIBUTE_LAYER_TRANSPARENCY = "A1434";

    [Start]
    [DeclareAction("TransparencySlider")]
    public void Execute()
    {
      var layer = GetLayerNameAndDescription();
      
      var percentage = GetCurrentTransparencyState(layer.Key);
      ShowSlider(percentage, layer);
    }

    [DeclareMenu]
    [DeclareRegister]
    public void AddContextMenu()
    {
      //XCabPlacerTreePage 4010
      var contextMenu = new Eplan.EplApi.Gui.ContextMenu();
      ContextMenuLocation location = new ContextMenuLocation("XCabPlacerTreePage", "4010");
      contextMenu.AddMenuItem(location, MENU_NAME, ACTION_NAME, false, false);
    }

    [DeclareUnregister]
    public void RemoveContextMenu()
    {
      var contextMenu = new Eplan.EplApi.Gui.ContextMenu();
      ContextMenuLocation location = new ContextMenuLocation("XCabPlacerTreePage", "4010");
      contextMenu.RemoveMenuItem(location, MENU_NAME, ACTION_NAME, false, false);
    }

    private const string MENU_NAME = "Transparency...";
    private const string ACTION_NAME = "TransparencySlider";

    private KeyValuePair<string, string> GetLayerNameAndDescription()
    {
      // XEsGetPropertyAction /PropertyId:? /PropertyIndex:0
      string value = null;
      var context = new ActionCallingContext();
      context.AddParameter("PropertyId", "2000");
      context.AddParameter("PropertyIndex", "0");
      var cli = new CommandLineInterpreter(true, true);
      cli.Execute("XEsGetPropertyAction", context);
      context.GetParameter("PropertyValue", ref value);
      var obj = StorableObjectWrapper.FromStringIdentifier(value);
      var placement3D = new Placement3DWrapper(obj);
      var description = placement3D.Layer.Description.Split('@').Last().TrimEnd(';');
      return new KeyValuePair<string, string>(placement3D.Layer.Name, description);
    }

    private void ShowSlider(float percentage, KeyValuePair<string,string> layer)
    {
      var form = new System.Windows.Forms.Form();
      var stackPanel = new System.Windows.Forms.FlowLayoutPanel();
      var panel = new System.Windows.Forms.Panel();
      panel.BackColor = Color.SteelBlue;
      panel.Padding = new Padding(1); // This will create a 1px border
      panel.AutoSize = true;
      
      stackPanel.Dock = DockStyle.Fill; 
      stackPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
      stackPanel.BackColor = Color.White;
      
      stackPanel.AutoSize = true;
      stackPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
      panel.Controls.Add(stackPanel);
      form.Controls.Add(panel);
      var label = new System.Windows.Forms.Label();
      label.Text = string.Format("Transparency Slider [{0} - {1}]", layer.Key, layer.Value);
      label.AutoSize = true;
      label.Margin = new Padding(4, 4, 4, 4);
      stackPanel.Controls.Add(label);
      var slider = new System.Windows.Forms.TrackBar();
      slider.Width = 400;
      slider.Minimum = 0;
      slider.Maximum = 100;
      slider.TickFrequency = 10;
      slider.LargeChange = 10;
      slider.SmallChange = 10;
      slider.BackColor = Color.White;
      
      try
      {
        slider.Value = (int)(percentage * 100);
      }
      catch (Exception)
      {
        slider.Value = 0;
      }
      slider.TickStyle = System.Windows.Forms.TickStyle.Both;
      slider.ValueChanged += (sender, args) => SetTransparency(layer.Key, slider.Value / 100f);
      stackPanel.Controls.Add(slider);

      // Set form properties
      form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
      form.BackColor = Color.White;
      form.TopMost = true;
      form.AutoSize = true;
      form.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
      form.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
      form.Location = System.Windows.Forms.Cursor.Position;

      // Close form when it loses focus
      form.Deactivate += (sender, args) => form.Close();

      // Close form when Escape key is pressed
      slider.KeyDown += (sender, args) =>
      {
        if (args.KeyCode == System.Windows.Forms.Keys.Escape)
        {
          form.Close();
        }
      };
      form.KeyDown += (sender, args) =>
      {
        if (args.KeyCode == System.Windows.Forms.Keys.Escape)
        {
          form.Close();
        }
      };

      WindowWrapper windowWrapper = new WindowWrapper(Process.GetCurrentProcess().MainWindowHandle);
      form.Show(windowWrapper);
    }

    private void SetTransparency(string layerName, float sliderValue)
    {
      // changelayer /LAYER:560 /VISIBLE:1 /COLORID:9 /TRANSPARENCY:0.1
      var context = new ActionCallingContext();
      context.AddParameter("LAYER", layerName);
      context.AddParameter("TRANSPARENCY", sliderValue.ToString());
      new CommandLineInterpreter().Execute("changelayer", context);
    }

    private float GetCurrentTransparencyState(string layerName)
    {
      var fileName = ExportLayerTable();
      var transparency = GetTransparencyValue(fileName, layerName);
      return transparency;
    }

    private float GetTransparencyValue(string fileName, string layerName)
    {
      // <O76 Build="5313" A1="76/335" A3="0" A13="0" A14="0" R1421="14/1" A1422="1" A1423="1" A1424="EPLAN560" A1425="##_##@560/ESGraphics;??_??@3D-Grafik.Schrank;" A1426="560" A1427="0" A1428="274" A1429="0.5" A1430="-1" A1433="0" A1434="77" A1435="1">
      var document = new XmlDocument();
      document.Load(fileName);
      var xPathSelectElementByLayerName =
        string.Format("/EplanPxfRoot/O76[@{0}='{1}']", ATTRIBUTE_LAYER_NAME, layerName);
      var layerElement = document.SelectSingleNode(xPathSelectElementByLayerName);
      var transparencyByteValue = layerElement.Attributes[ATTRIBUTE_LAYER_TRANSPARENCY].Value;
      var transparencyPercentage = float.Parse(transparencyByteValue) / 255;
      return transparencyPercentage;
    }

    private string ExportLayerTable()
    {
      string fileName = Path.Combine(Path.GetTempPath(), "Layer.xml");
      if (File.Exists(fileName))
      {
        File.Delete(fileName);
      }
      var context = new ActionCallingContext();
      context.AddParameter("TYPE", "EXPORT");
      context.AddParameter("EXPORTFILE", fileName);
      new CommandLineInterpreter().Execute("graphicallayertable", context);
      return fileName;
    }
  }

  public class Placement3DWrapper
  {
    private readonly object _placement3D;

    public Placement3DWrapper(object o)
    {
      _placement3D = o;
    }

    public GraphicalLayerWrapper Layer
    {
      get
      {
        var layer = _placement3D.GetType().GetProperty("Layer");
        var value = layer.GetValue(_placement3D);
        return new GraphicalLayerWrapper(value);
      }
    }
  }

  public class GraphicalLayerWrapper
  {
    private readonly object _graphicalLayer;

    public GraphicalLayerWrapper(object value)
    {
      _graphicalLayer = value;
    }

    public string Name
    {
      get
      {
        var name = _graphicalLayer.GetType().GetProperty("Name");
        var value = name.GetValue(_graphicalLayer);
        return value.ToString();
      }
    }

    public string Description
    {
      get
      {
        var description = _graphicalLayer.GetType().GetProperty("Description");
        var value = description.GetValue(_graphicalLayer);
        return value.ToString();
      }
    }
  }

  public class StorableObjectWrapper
  {
    private static Assembly _dataModelAssembly;

    public static object FromStringIdentifier(string databaseId)
    {
      if (_dataModelAssembly == null)
      {
        _dataModelAssembly = AppDomain.CurrentDomain.GetAssemblies()
                                      .FirstOrDefault(a => a.FullName.StartsWith("Eplan.EplApi.DataModelu"));
      }

      var storableObjectType = _dataModelAssembly.ExportedTypes.FirstOrDefault(t => t.Name == "StorableObject");
      MethodInfo fromStringIdentifier = storableObjectType.GetMethod("FromStringIdentifier",
                                                                     BindingFlags.Public | BindingFlags.Static, null,
                                                                     new[] { typeof(string) }, null);
      var args = new object[] { databaseId };
      var storableObject = fromStringIdentifier.Invoke(null, args);
      return storableObject;
    }
  }

  public class WindowWrapper : IWin32Window
  {
    private readonly IntPtr _hwnd;

    public WindowWrapper(IntPtr handle)
    {
      _hwnd = handle;
    }

    public IntPtr Handle
    {
      get { return _hwnd; }
    }
  }
}

 

Von |2024-03-12T07:04:41+01:002024-03-12|EPLAN, EPLAN-Scripts|
Nach oben