XEsSettingsMasterDlgAction auch einen Dialog mit angeben. Damit wird direkt zum Einstellungsknoten in der UI gesprungen.XSDMasterDataSettingsPathDlg
public class SettingsDialogJumper
{
[Start]
public static void ToDirectories()
{
ActionCallingContext acc = new ActionCallingContext();
acc.AddParameter("SelectDialog", "XSDMasterDataSettingsPathDlg");
new CommandLineInterpreter().Execute("XEsSettingsMasterDlgAction", acc);
}
}
]]>xmlFile angeben.
Vielen Dank an Massimo für das Teilen 💖
string xmlFile = @"C:\Path\To\Your\SettingsFile.xml";
CommandLineInterpreter cli = new CommandLineInterpreter();
ActionCallingContext acc = new ActionCallingContext();
string project = "";
// Get project
acc.AddParameter("TYPE", "PROJECT");
cli.Execute("selectionset", acc);
acc.GetParameter("PROJECT", ref project);
// Import settings
acc.AddParameter("XMLFile", xmlFile);
acc.AddParameter("Project", project);
acc.AddParameter("Option", "OVERWRITE");
acc.AddParameter("Node", "FormGeneratorGui");
cli.Execute("XSettingsImport", acc);
// Complete master data
cli.Execute("XPrjActionProjectCompleteMasterData", acc);
// Update project settings
EventParameterString eventParameterString = new EventParameterString();
eventParameterString.String = "";
new EventManager().Send("PageManagement.ProjectSettings.Changed", eventParameterString);
]]>Da ich das Buch nun selbst vertreibe, bieten sich mehr Möglichkeiten:
Alles rund um das Buch findet Ihr hier: eplan-scripting.suplanus.de.
Changelog
Digitale Version auf interaktiven Website
Kompletter Inhalt Beginner kostenfrei
ListSelectDecisionContext
Remote Client komplett an das neue Framework angepasst
XML Kapitel optimiert
Debug Kapitel überarbeitet und Settings-Script hinzugefügt
| getrennt angegeben werden. Beispiel-Aufruf:
DeletePages /Pages:"=TEST/11|=TEST/12"
Ist eine angegebene Seite im Projekt nicht vorhanden, wird eine Systemmeldung ausgegeben.
using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.Base;
using Eplan.EplApi.Scripting;
public class DeletePages
{
[DeclareAction("DeletePages")]
public void Action(ActionCallingContext acc)
{
string pagesString = null;
acc.GetParameter("Pages", ref pagesString);
if (string.IsNullOrEmpty(pagesString))
{
new Decider().Decide(EnumDecisionType.eOkDecision, "Parameter 'Pages' missing.", "DeletePages",
EnumDecisionReturn.eOK, EnumDecisionReturn.eOK, null, false, EnumDecisionIcon.eFATALERROR);
return;
}
var pages = pagesString.Split('|');
foreach (var page in pages)
{
DeletePage(page);
}
}
private void DeletePage(string page)
{
ActionCallingContext accPage = new ActionCallingContext();
accPage.AddParameter("PAGENAME", page);
var isPageValid = new CommandLineInterpreter().Execute("edit", accPage);
if (isPageValid)
{
using (new QuietModeStep(QuietModes.ShowNoDialogs))
{
new CommandLineInterpreter().Execute("XGedSelectPageAction");
new CommandLineInterpreter().Execute("GfDlgMgrActionIGfWindDelete");
}
}
else
{
new BaseException("Page not found: " + page, MessageLevel.Error).FixMessage();
}
}
}
]]>mfToggleMainMenuAction kann das Menü auch in EPLAN 2025 eingeblendet werden.
]]>Somit brauchen wir eine 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);
}
]]>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)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;
}
}
]]>
XPartsSetDataSourceAction.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]]>
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;[email protected];" 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; }
}
}
}
]]>