Skip to content

Attributes

As we have already seen, a script can execute a wide variety of functions. That is why we have to specify in the program code which function the script provides. There can also be several actions in a script. For example, a label can be generated automatically. In addition, a separate command can be created for this action in the ribbon. This is all possible within one file. In this case, it also makes sense, as the command cannot be executed without the corresponding action. However, it makes no sense to pack all actions into one file, as it quickly becomes confusing.

For our first example, we use the [Start] attribute. This is the quickest way to test several scripts. The question often arises as to when a script needs to be loaded and what needs to be runable. We can find this out quickly and easily using the attributes. This is a list of the attributes for execution and loading:

  • Execute: [Start]
  • Load:
    • [DeclareAction]
    • [DeclareEventHandler]
    • [DeclareMenu]
    • [DeclareRegister]
    • [DeclareUnregister]

Scripte                   |

Start

The [Start] attribute is usually used if a script is only needed once or rarely. We have to go to the backstage view every time we start the action in order to run the script. Alternatively, we use the commands created in our tab. In the development environment, we switch to the code window and view the first lines. To do this, we double-click on the 01_Start.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

The using command describes which references are to be used. Certain program commands are saved in a so-called Using directive and can be called up if they are loaded. The following references are required for the first script:

  • System.Windows.Forms

  • Eplan.EplApi.Scripting

Not all references are always required. Nevertheless, it is advisable to create a template that contains all the Using directives that are important to us. We can later remove the elements that are not required. The following EPLAN namespaces are available in scripting:

  • Eplan.EplApi.ApplicationFramework

  • Eplan.EplApi.Base

  • Eplan.EplApi.MasterData

  • Eplan.EplApi.Scripting

  • Newtonsoft.Json

  • System

  • System.Drawing

  • System.IO.Compression.FileSystem

  • System.Net.Http

  • System.Windows.Forms

  • System.xml

  • System.Linq

When typing the code, a small dialog with various terms appears. This dialog is called IntelliSense. It is an option for word completion of individual terms in programming. The tool developed by Microsoft is available in almost all development environments for all programming languages. When you enter a term, matching results are displayed. We can now use the arrow keys on the keyboard to select the desired term. To complete what we have typed, we press the Tab key. If IntelliSense is not visible, the dialog can be shown again with the keyboard shortcut Ctrl+Space.

IntelliSense

In C#, a code sequence is always ended with a semicolon (;). Anyone who has ever programmed in Visual Basic knows that this is the line break there. In C#, we can insert any number of line breaks in the code.

The structure of a program code in C# can be imagined as an onion. There are different layers that are delimited by curly brackets. However, the structure is not so complicated that the onion will make us cry.

 graph LR
   subgraph id1["Namespace"]
        subgraph id2["Class (Class)"]
            id3["Method (Void)"]
        end
   end

The "outer shell" is the namespace:

namespace Namespace
{

}

The "middle shell" is the class:

class Class
{

}

The function that is executed is referred to as a method. Methods are identified with void. We add the following lines to the program code:

void Function()
{

}

The function now contains the actual program code (What should EPLAN do?). We display a message box to determine whether our script has been executed. This is the structure of the command in brief:

  • What should be done? → MessageBox

  • What should be done with it? → Show (show)

  • What should be displayed? → Scripting is great!

The individual classes and methods are separated by a dot. We imagine a staircase for this purpose. There are different rooms with different functions on each level. At the beginning, it is often difficult to find the desired function immediately, but with time you will understand the structure of the .NET framework.

Example structure of a method call:

Level0.Level1.Level2.Method();

If we take an activity at a location as an example, this should be specified as follows:

Munich.Theresienwiese.Oktoberfest.rollercoaster.ride();

Text in the program code is always in quotation marks ("quotation marks"):

Munich.station.conductor.calls("All off!");

Comments can be inserted with two slashes:

// I am a comment

This lets the program know that it is a comment that does not need to be processed.

In Visual Studio there are ready-made buttons for inserting comments. If this toolbar is not visible, we can show it via Toolbar > Contextmenu > Text Editor. The complete line that is currently active is then commented in or out.

image-20250508084334586

The following code is required to display a MessageBox:

MessageBox.Show("Scripting is great!"); // Comment

A function is concluded with return.

return;

We should remove unused references to make the script clearer. This is done automatically by right-clicking and executing the Remove Unnecessary Usings function in Visual Studio.

image-20250508084539147

Now we put our "shells" together. The complete example can always be found at the end of a lesson:

using Eplan.EplApi.Scripting;
using System.Windows.Forms;

namespace Namespace
{
  public class Class
  {
    [Start]
    public void Function()
    {
      MessageBox.Show("Scripting is great!"); // Comment
      return;
    }
  }
}

We now switch to the EPLAN software and test the script via Run scripts in our tab. We select the script in the following dialog. The script file is located in the Visual Studio project folder.

Script ausführen

If the program code was executed without errors, you will see the dialog shown in .

image-20250508091420034

Several errors can occur when writing the program code. We comment out the initialization of the using directives as a test:

//using System.Windows.Forms;
//using Eplan.EplApi.Scripting;

You may have noticed when commenting out the Using statements that some errors have been added to the Visual Studio error window. This results from the fact that the development environment cannot find the expressions due to missing references. This error list is structured similarly to the EPLAN message management. A distinction is also made here between:

  • Errors
  • Warnings
  • Messages

image-20250508091547482

If the window is not visible, we can show it via View > Error List.

image-20250508092236680

If we now execute the script, an error should actually also occur in EPLAN. In the case of the missing Using directives, however, this is not always the case, as these may already be loaded in EPLAN.

To quickly find any errors that may occur, we can also use the Tools > Options > Text Editor > C# in Visual Studio to show the line numbers if they are not yet visible.

image-20250508092356514

Now we want to provoke another error: Especially at the beginning, we often forget to end the code with a semicolon. If the error list is displayed, we can already see this before executing in EPLAN. The position is underlined in red in the code window.

image-20250508104200216

EPLAN also checks the code before it is loaded or executed.

image-20250508104247000

image-20250508104328327

DeclareAction

If we want to use an action more frequently, it makes sense to load it permanently. To do this, we copy the script 01_Start.cs via Ctrl+C or via the context menu and insert it at project level.

We now rename the file to 02_DeclareAction.cs. Then we open the file with a double click. The program code logically looks the same as in the first example. In the tab bar you can see which file is being edited.

Datei kopieren/einfügen

To define the new attribute, we edit the line [Start]. We rewrite this to [DeclareAction("ActionName")]. To avoid conflicts between the same classes, we use a unique name for each script in the project. In the following examples, we always use the combination of folder name and file name for the class. The namespace is optional and is omitted in the examples for simplicity. If it is not necessary, we also omit the return command at the end of the script.

Info

No leading numbers may be used for a namespace or classes. For this reason, for example, _01_FirstSteps is written and not 01_FirstSteps.

using System.Windows.Forms;
using Eplan.EplApi.Scripting;

public class _01_FirstSteps_02_DeclareAction
{
  [DeclareAction("ActionName")]
  public void Function()
  {
    MessageBox.Show("Scripting is great!");
  }
}

DeclareAction shows that a new action is being added to EPLAN. ActionName is the name of the new action.

Now we load the script into EPLAN using the load script command in the ribbon. EPLAN does not provide any feedback on the successful loading of a script. However, in the event of an error, the system messages are displayed as described above. If this is the case, we analyze or compare line by line. As a final solution, we can use the finished script. We change the program code and reload the script until no more errors are displayed in the system messages. Especially at the beginning of script programming, it often happens that a script does not work right away.

We now add a new command to our Test command group. To do this, we insert any command from the Actions category. We select My action as the display name and replace the content of the Command line text box with ActionName. Image, tooltip and description are not necessary. If you press the button, the MessageBox appears again.

image-20250508105306889

We can unload individual scripts via Unload scripts in our tab. We will work with the same action name in the following sections. It is therefore advisable to always unload all scripts as soon as we have completed a section.

Script entladen

DeclareEventHandler

EPLAN provides an attribute to execute an action at a specific time. We copy our template again and rename it to 03_DeclareEventHandler.cs. We add the following as an attribute:

[DeclareEventHandler("onActionStart.String.XPrjActionProjectClose")]

If you want to execute the action when closing a project, for example, this event can be intercepted.

  • DeclareEventHandler indicates that an event must be intercepted
  • onActionStart.String.XPrjActionProjectClose indicates which event is involved

But where do we get the name of the internal EPLAN action? Unfortunately, there is no overview or anything similar in the help. However, there is a diagnostics dialog in EPLAN that shows us the last action. We switch to EPLAN and execute the desired action. We access the diagnostics dialog by pressing Ctrl+\. For example, if we want to find out the action for closing a project, we close any project and then press Ctrl+\. The diagnostics dialog now appears.

Info

The key combination Ctrl+\ only works with a US keyboard layout. EPLAN uses the virtual key code VK_OEM_5 here.

In this example, only the first line is important for us:

Last called action from (context)menu: XPrjActionProjectClose

Here we find the name of the action. For the interception, however, you still have to tell EPLAN what type it is, e.g:

  • onActionStart before executing the actual action (close project)
  • onActionEnd after executing the actual action (close project)

With String we indicate that it is a character string. We do this with onActionStart.String:

using System.Windows.Forms;
using Eplan.EplApi.Scripting;

public class _01_FirstSteps_03_DeclareEventHandler
{
  [DeclareEventHandler("onActionStart.String.XPrjActionProjectClose")]
  public void Function()
  {
    MessageBox.Show("Scripting is great!");
  }
}

We now load the script into EPLAN. If you close any project, the dialog should appear again.

DeclareRegister and DeclareUnregister

The two attributes DeclareRegister and DeclareUnregister actually also catch one event each. However, these events are dependent on the script.

  • DeclareRegister is executed when the script is loaded.

  • DeclareUnregister is executed when the script is unloaded.

This allows files, data and settings to be created or deleted, for example.

We copy our template again (01_Start.cs) and assign the name 04_DeclareRegisterUnregister.cs. This time we have to make several adjustments to the code. First, we replace [Start] with [DeclareRegister] and change the text of the MessageBox to Script loaded. The method is named Register:

[DeclareRegister]
public void Register()
{
  MessageBox.Show("Script loaded.");
}

Next, we copy the complete method and insert it after the curly brackets as method Register(). We name this method UnRegister(). This is because there must not be several methods with the same name in one class.

Now we insert the attribute [DeclareUnregister] before this method. The text of the MessageBox is changed to Unload script. If we look at the code, we can perhaps already guess what happens when the script is loaded or unloaded:

using System.Windows.Forms;
using Eplan.EplApi.Scripting;

public class _01_FirstSteps_04_DeclareRegisterUnregister
{
  [DeclareRegister]
  public void Register()
  {
    MessageBox.Show("Script loaded.");
  }

  [DeclareUnregister]
  public void UnRegister()
  {
    MessageBox.Show("Script unloaded.");
  }
}