Ir al contenido

Capítulo 14: ActionCallingContext

Parte II: Introducción a EPLAN API - Sección 3: Primeros pasos con EPLAN - Nivel: Intermedio


Al finalizar este capítulo serás capaz de:

  • Entender qué es ActionCallingContext y para qué sirve
  • Pasar parámetros a scripts desde la línea de comandos
  • Recibir parámetros dentro del script con GetParameter
  • Agregar parámetros de salida con AddParameter
  • Crear scripts parametrizables desde la GUI de EPLAN
  • Validar parámetros de entrada de forma robusta
  • Usar valores por defecto cuando no se pasan parámetros
  • Construir herramientas flexibles que se adaptan a diferentes escenarios

Antes de comenzar este capítulo debes:

  • ✅ Haber completado el Capítulo 13
  • ✅ Saber crear scripts básicos con [Start]
  • ✅ Conocer SelectionSet y Project
  • ✅ Entender manejo de errores con try-catch

Exportador Parametrizable de PDF

Al final de este capítulo habrás construido un script que:

  • Acepta parámetros desde línea de comandos o GUI
  • Permite especificar: ruta de salida, nombre de archivo, páginas a exportar
  • Valida todos los parámetros de entrada
  • Usa valores por defecto inteligentes
  • Exporta PDF usando CommandLineInterpreter
  • Devuelve el resultado (éxito/error) mediante parámetros de salida
  • Es completamente reutilizable en diferentes contextos

Tiempo estimado: 70-80 minutos


1. Introducción: ¿Qué es ActionCallingContext?

Sección titulada «1. Introducción: ¿Qué es ActionCallingContext?»

Script sin parámetros (rígido):

[Start]
public void Ejecutar()
{
// Valores fijos "hardcodeados"
string rutaSalida = @"C:\Exportaciones\planos.pdf";
// No se puede cambiar sin editar el código
ExportarPDF(rutaSalida);
}

Problemas:

  • ❌ Hay que editar el código para cambiar la ruta
  • ❌ No se puede reutilizar fácilmente
  • ❌ No se puede llamar desde otros scripts
  • ❌ No se puede integrar en workflows

Script con parámetros (flexible):

[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Leer parámetro de entrada
string rutaSalida = ctx.GetParameter("RUTA_SALIDA");
if (string.IsNullOrEmpty(rutaSalida))
{
rutaSalida = @"C:\Exportaciones\planos.pdf"; // Valor por defecto
}
ExportarPDF(rutaSalida);
}

Ventajas:

  • ✅ Ruta configurable desde fuera
  • ✅ Reutilizable en diferentes contextos
  • ✅ Se puede llamar desde GUI o CLI
  • ✅ Fácil de integrar

ActionCallingContext es un objeto contenedor de parámetros que permite:

  • Pasar información al script (parámetros de entrada)
  • Recibir información del script (parámetros de salida)
  • Comunicación bidireccional entre scripts y EPLAN

Analogía: Como argumentos de una función, pero para scripts completos.

// Función normal
public void ProcesarArchivo(string ruta, bool validar)
{
// Parámetros directos
}
// Script con ActionCallingContext
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
string ruta = ctx.GetParameter("RUTA");
bool validar = ctx.GetParameter("VALIDAR") == "true";
// Parámetros desde contexto
}

2.1 Declarar el método con ActionCallingContext

Sección titulada «2.1 Declarar el método con ActionCallingContext»
using Eplan.EplApi.ApplicationFramework;
public class MiScript
{
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// ctx está disponible aquí
}
}

Importante:

  • El parámetro se llama típicamente ctx o context
  • Es opcional: Si no necesitas parámetros, no lo declares
  • Tipo: ActionCallingContext de Eplan.EplApi.ApplicationFramework
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Leer parámetro como string
string valor = ctx.GetParameter("NOMBRE_PARAMETRO");
// Verificar si existe
if (string.IsNullOrEmpty(valor))
{
// Parámetro no fue pasado
valor = "valor_por_defecto";
}
}

Características:

  • GetParameter() siempre devuelve string
  • Devuelve null o "" si el parámetro no existe
  • Los nombres de parámetros suelen estar en MAYÚSCULAS (convención)
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Hacer algo...
bool exito = ProcesarDatos();
// Agregar parámetro de salida
ctx.AddParameter("RESULTADO", exito ? "OK" : "ERROR");
ctx.AddParameter("ARCHIVOS_PROCESADOS", "15");
}

Uso:

  • Para devolver información al llamador
  • Útil cuando otros scripts llaman a tu script
  • También para logging y debugging

[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Parámetro string
string nombre = ctx.GetParameter("NOMBRE");
// Parámetro numérico (convertir)
string numeroStr = ctx.GetParameter("NUMERO_PAGINAS");
int numero = string.IsNullOrEmpty(numeroStr) ? 10 : int.Parse(numeroStr);
// Parámetro booleano
string activarStr = ctx.GetParameter("ACTIVAR");
bool activar = activarStr == "true" || activarStr == "1";
}
private string ObtenerParametro(ActionCallingContext ctx,
string nombreParam,
string valorDefecto)
{
string valor = ctx.GetParameter(nombreParam);
if (string.IsNullOrEmpty(valor))
{
return valorDefecto;
}
return valor;
}
// Uso
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
string ruta = ObtenerParametro(ctx, "RUTA_SALIDA", @"C:\Temp\salida.pdf");
int paginas = int.Parse(ObtenerParametro(ctx, "NUM_PAGINAS", "10"));
}
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Obtener parámetro requerido
string rutaSalida = ctx.GetParameter("RUTA_SALIDA");
// Validar que no esté vacío
if (string.IsNullOrEmpty(rutaSalida))
{
new BaseException(
"Error: Falta el parámetro RUTA_SALIDA\n\n" +
"Uso: script /RUTA_SALIDA:\"C:\\salida.pdf\"",
MessageLevel.Error).FixMessage();
return;
}
// Validar que sea una ruta válida
if (!System.IO.Path.IsPathRooted(rutaSalida))
{
new BaseException(
"Error: RUTA_SALIDA debe ser una ruta absoluta\n\n" +
"Ejemplo: C:\\Exportaciones\\planos.pdf",
MessageLevel.Error).FixMessage();
return;
}
// Continuar con el procesamiento...
}
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Leer múltiples parámetros
string rutaSalida = ctx.GetParameter("RUTA_SALIDA");
string formato = ctx.GetParameter("FORMATO");
string paginasStr = ctx.GetParameter("PAGINAS");
string blanconegroStr = ctx.GetParameter("BLANCO_NEGRO");
// Valores por defecto
if (string.IsNullOrEmpty(formato))
formato = "PDF";
if (string.IsNullOrEmpty(blanconegroStr))
blanconegroStr = "false";
// Convertir tipos
bool blanconegro = blanconegroStr.ToLower() == "true";
// Parsear lista de páginas
string[] paginas = null;
if (!string.IsNullOrEmpty(paginasStr))
{
paginas = paginasStr.Split(',');
}
}

[Start]
public void Ejecutar(ActionCallingContext ctx)
{
try
{
// Hacer procesamiento
int archivosGenerados = ExportarDocumentacion();
// Devolver resultado exitoso
ctx.AddParameter("RESULTADO", "OK");
ctx.AddParameter("ARCHIVOS_GENERADOS", archivosGenerados.ToString());
ctx.AddParameter("TIMESTAMP", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
}
catch (Exception ex)
{
// Devolver resultado de error
ctx.AddParameter("RESULTADO", "ERROR");
ctx.AddParameter("MENSAJE_ERROR", ex.Message);
}
}
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Parámetros de progreso
ctx.AddParameter("ESTADO", "INICIANDO");
// Procesar...
ctx.AddParameter("ESTADO", "PROCESANDO");
ctx.AddParameter("PROGRESO", "50");
// Finalizar
ctx.AddParameter("ESTADO", "COMPLETADO");
ctx.AddParameter("PROGRESO", "100");
}
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Analizar proyecto
Project proyecto = ObtenerProyectoActual();
int totalPaginas = proyecto.Pages.Length;
int totalFunciones = 0;
int totalDispositivos = 0;
foreach (Page pagina in proyecto.Pages)
{
totalFunciones += pagina.Functions.Length;
totalDispositivos += pagina.Devices.Length;
}
// Devolver múltiples estadísticas
ctx.AddParameter("TOTAL_PAGINAS", totalPaginas.ToString());
ctx.AddParameter("TOTAL_FUNCIONES", totalFunciones.ToString());
ctx.AddParameter("TOTAL_DISPOSITIVOS", totalDispositivos.ToString());
ctx.AddParameter("PROMEDIO_FUNCIONES",
(totalPaginas > 0 ? (double)totalFunciones / totalPaginas : 0).ToString("F2"));
}

En la consola de comandos de EPLAN:

script MiScript /RUTA_SALIDA:"C:\Exportaciones\planos.pdf" /FORMATO:PDF

5.2 Desde otro script con CommandLineInterpreter

Sección titulada «5.2 Desde otro script con CommandLineInterpreter»
using Eplan.EplApi.ApplicationFramework;
[Start]
public void Ejecutar()
{
// Crear contexto
ActionCallingContext ctx = new ActionCallingContext();
// Agregar parámetros
ctx.AddParameter("RUTA_SALIDA", @"C:\Exportaciones\planos.pdf");
ctx.AddParameter("FORMATO", "PDF");
ctx.AddParameter("BLANCO_NEGRO", "true");
// Llamar script
CommandLineInterpreter cli = new CommandLineInterpreter();
cli.Execute("script:MiScript", ctx);
// Leer resultado
string resultado = ctx.GetParameter("RESULTADO");
if (resultado == "OK")
{
new BaseException("Exportación exitosa",
MessageLevel.Message).FixMessage();
}
else
{
string error = ctx.GetParameter("MENSAJE_ERROR");
new BaseException("Error: " + error,
MessageLevel.Error).FixMessage();
}
}
// En un Add-in o aplicación externa
ActionManager actionMgr = new ActionManager();
ActionCallingContext ctx = new ActionCallingContext();
ctx.AddParameter("RUTA_SALIDA", @"C:\salida.pdf");
Action action = actionMgr.FindAction("script:MiScript");
action.Execute(ctx);
string resultado = ctx.GetParameter("RESULTADO");

6.1 Patrón: Script con parámetros opcionales

Sección titulada «6.1 Patrón: Script con parámetros opcionales»
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Parámetros con valores por defecto
string rutaSalida = ObtenerParametroString(ctx, "RUTA_SALIDA",
@"C:\Exportaciones\planos.pdf");
string formato = ObtenerParametroString(ctx, "FORMATO", "PDF");
bool blanconegro = ObtenerParametroBool(ctx, "BLANCO_NEGRO", false);
// Procesar...
ExportarDocumentacion(rutaSalida, formato, blanconegro);
}
// Métodos auxiliares
private string ObtenerParametroString(ActionCallingContext ctx,
string nombre,
string valorDefecto)
{
string valor = ctx.GetParameter(nombre);
return string.IsNullOrEmpty(valor) ? valorDefecto : valor;
}
private bool ObtenerParametroBool(ActionCallingContext ctx,
string nombre,
bool valorDefecto)
{
string valor = ctx.GetParameter(nombre);
if (string.IsNullOrEmpty(valor))
return valorDefecto;
return valor.ToLower() == "true" || valor == "1";
}
private int ObtenerParametroInt(ActionCallingContext ctx,
string nombre,
int valorDefecto)
{
string valor = ctx.GetParameter(nombre);
if (string.IsNullOrEmpty(valor))
return valorDefecto;
int resultado;
if (int.TryParse(valor, out resultado))
return resultado;
return valorDefecto;
}

6.2 Patrón: Validación completa de parámetros

Sección titulada «6.2 Patrón: Validación completa de parámetros»
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Validar parámetros
if (!ValidarParametros(ctx, out string mensajeError))
{
new BaseException("Parámetros inválidos:\n\n" + mensajeError,
MessageLevel.Error).FixMessage();
ctx.AddParameter("RESULTADO", "ERROR");
ctx.AddParameter("MENSAJE_ERROR", mensajeError);
return;
}
// Parámetros válidos, continuar...
}
private bool ValidarParametros(ActionCallingContext ctx, out string mensajeError)
{
mensajeError = "";
// Validar RUTA_SALIDA
string rutaSalida = ctx.GetParameter("RUTA_SALIDA");
if (string.IsNullOrEmpty(rutaSalida))
{
mensajeError = "Falta parámetro RUTA_SALIDA";
return false;
}
if (!System.IO.Path.IsPathRooted(rutaSalida))
{
mensajeError = "RUTA_SALIDA debe ser una ruta absoluta";
return false;
}
// Validar FORMATO
string formato = ctx.GetParameter("FORMATO");
if (!string.IsNullOrEmpty(formato))
{
string[] formatosValidos = {"PDF", "DXF", "DWG"};
if (!formatosValidos.Contains(formato.ToUpper()))
{
mensajeError = string.Format(
"FORMATO inválido: {0}. Formatos válidos: {1}",
formato, string.Join(", ", formatosValidos));
return false;
}
}
return true;
}
// Permite llamar el script con o sin parámetros
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
if (ctx == null)
{
// Llamado sin parámetros - usar defaults
EjecutarConDefaults();
}
else
{
// Llamado con parámetros
EjecutarConParametros(ctx);
}
}
private void EjecutarConDefaults()
{
// Valores por defecto hardcodeados
string ruta = @"C:\Exportaciones\planos.pdf";
ExportarPDF(ruta);
}
private void EjecutarConParametros(ActionCallingContext ctx)
{
string ruta = ctx.GetParameter("RUTA_SALIDA");
ExportarPDF(ruta);
}

//
// Proyecto: Exportador Parametrizable de PDF
// Capítulo: 14 - ActionCallingContext
// Descripción: Script completo que exporta PDF con parámetros configurables
// Autor: C.D. López
// Fecha: Enero 2025
//
// Uso:
// Desde línea de comandos de EPLAN:
// script ExportadorPDF /RUTA_SALIDA:"C:\Salida\planos.pdf" /BLANCO_NEGRO:true
//
// Desde otro script:
// ActionCallingContext ctx = new ActionCallingContext();
// ctx.AddParameter("RUTA_SALIDA", @"C:\Salida\planos.pdf");
// cli.Execute("script:ExportadorPDF", ctx);
//
using System;
using System.IO;
using Eplan.EplApi.Base;
using Eplan.EplApi.ApplicationFramework;
using Eplan.EplApi.DataModel;
public class ExportadorPDF
{
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
try
{
// ====================================
// 1. LEER Y VALIDAR PARÁMETROS
// ====================================
if (!ValidarParametros(ctx, out string mensajeError))
{
new BaseException("Error en parámetros:\n\n" + mensajeError,
MessageLevel.Error).FixMessage();
ctx.AddParameter("RESULTADO", "ERROR");
ctx.AddParameter("MENSAJE_ERROR", mensajeError);
return;
}
// ====================================
// 2. OBTENER PARÁMETROS
// ====================================
string rutaSalida = ObtenerParametroString(ctx, "RUTA_SALIDA",
@"C:\Temp\exportacion.pdf");
bool blanconegro = ObtenerParametroBool(ctx, "BLANCO_NEGRO", false);
string paginas = ObtenerParametroString(ctx, "PAGINAS", "");
// ====================================
// 3. EXPORTAR PDF
// ====================================
ExportarPDF(rutaSalida, blanconegro, paginas);
// ====================================
// 4. DEVOLVER RESULTADO EXITOSO
// ====================================
ctx.AddParameter("RESULTADO", "OK");
ctx.AddParameter("ARCHIVO_GENERADO", rutaSalida);
ctx.AddParameter("TIMESTAMP", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
new BaseException(
string.Format("PDF exportado exitosamente:\n\n{0}", rutaSalida),
MessageLevel.Message).FixMessage();
}
catch (Exception ex)
{
string mensajeError = "Error durante exportación: " + ex.Message;
new BaseException(mensajeError, MessageLevel.Error).FixMessage();
ctx.AddParameter("RESULTADO", "ERROR");
ctx.AddParameter("MENSAJE_ERROR", mensajeError);
}
}
// ====================================
// VALIDAR PARÁMETROS
// ====================================
private bool ValidarParametros(ActionCallingContext ctx, out string mensajeError)
{
mensajeError = "";
// RUTA_SALIDA es requerida
string rutaSalida = ctx.GetParameter("RUTA_SALIDA");
if (string.IsNullOrEmpty(rutaSalida))
{
mensajeError = "Falta el parámetro RUTA_SALIDA";
return false;
}
// Validar que sea ruta absoluta
if (!Path.IsPathRooted(rutaSalida))
{
mensajeError = "RUTA_SALIDA debe ser una ruta absoluta (ej: C:\\salida.pdf)";
return false;
}
// Validar que la carpeta destino exista
string carpeta = Path.GetDirectoryName(rutaSalida);
if (!Directory.Exists(carpeta))
{
mensajeError = string.Format("La carpeta no existe: {0}", carpeta);
return false;
}
return true;
}
// ====================================
// EXPORTAR PDF
// ====================================
private void ExportarPDF(string rutaSalida, bool blanconegro, string paginas)
{
CommandLineInterpreter cli = new CommandLineInterpreter();
ActionCallingContext exportCtx = new ActionCallingContext();
// Configurar parámetros de exportación
exportCtx.AddParameter("TYPE", "PDF");
exportCtx.AddParameter("EXPORTFILE", rutaSalida);
if (blanconegro)
{
exportCtx.AddParameter("BLACKWHITE", "1");
}
if (!string.IsNullOrEmpty(paginas))
{
exportCtx.AddParameter("PAGES", paginas);
}
// Ejecutar exportación
cli.Execute("export", exportCtx);
}
// ====================================
// MÉTODOS AUXILIARES
// ====================================
private string ObtenerParametroString(ActionCallingContext ctx,
string nombre,
string valorDefecto)
{
if (ctx == null)
return valorDefecto;
string valor = ctx.GetParameter(nombre);
return string.IsNullOrEmpty(valor) ? valorDefecto : valor;
}
private bool ObtenerParametroBool(ActionCallingContext ctx,
string nombre,
bool valorDefecto)
{
if (ctx == null)
return valorDefecto;
string valor = ctx.GetParameter(nombre);
if (string.IsNullOrEmpty(valor))
return valorDefecto;
return valor.ToLower() == "true" || valor == "1";
}
private int ObtenerParametroInt(ActionCallingContext ctx,
string nombre,
int valorDefecto)
{
if (ctx == null)
return valorDefecto;
string valor = ctx.GetParameter(nombre);
if (string.IsNullOrEmpty(valor))
return valorDefecto;
int resultado;
if (int.TryParse(valor, out resultado))
return resultado;
return valorDefecto;
}
}

// Sin ActionCallingContext
[Start]
public void Ejecutar()
{
// No acepta parámetros
}
// Con ActionCallingContext
[Start]
public void Ejecutar(ActionCallingContext ctx)
{
// Acepta parámetros
}
// Ambos son válidos, elige según necesites

Convención EPLAN:

  • MAYÚSCULAS con guiones bajos
  • Descriptivos y claros
  • Ejemplos: RUTA_SALIDA, BLANCO_NEGRO, NUM_PAGINAS

TODO se devuelve como string, debes convertir:

// Números
string numStr = ctx.GetParameter("NUMERO");
int numero = int.Parse(numStr);
// Booleanos
string boolStr = ctx.GetParameter("ACTIVADO");
bool activado = boolStr == "true";
// Fechas
string fechaStr = ctx.GetParameter("FECHA");
DateTime fecha = DateTime.Parse(fechaStr);

En este capítulo aprendiste:

  • ActionCallingContext: Contenedor de parámetros
  • GetParameter: Leer parámetros de entrada
  • AddParameter: Agregar parámetros de salida
  • Validación: Verificar parámetros antes de usar
  • Valores por defecto: Fallback cuando no se pasa parámetro
  • Llamadas: Desde CLI, otros scripts, o código externo
  • Patrones: Scripts flexibles y reutilizables
  • Proyecto completo: Exportador parametrizable

Conceptos clave:

  • ActionCallingContext permite scripts flexibles
  • Los parámetros son siempre strings (debes convertir)
  • Siempre valida parámetros de entrada
  • Usa valores por defecto para parámetros opcionales
  • Devuelve resultados mediante parámetros de salida

Capítulo 13: Tu primer script EPLAN

Capítulo 15: Logging y debugging

En el próximo capítulo aprenderás técnicas profesionales de logging, debugging, barras de progreso, y cómo rastrear la ejecución de tus scripts para encontrar y corregir errores rápidamente.


  • 📖 EPLAN API Documentation: ActionCallingContext class
  • 📖 CommandLineInterpreter: Cómo ejecutar acciones con parámetros
  • 💻 Código completo: code/cap-14/

P: ¿Es obligatorio usar ActionCallingContext?

Sección titulada «P: ¿Es obligatorio usar ActionCallingContext?»

R: No. Solo si necesitas que tu script acepte parámetros. Si no lo necesitas, omítelo.

P: ¿Puedo pasar objetos complejos como parámetros?

Sección titulada «P: ¿Puedo pasar objetos complejos como parámetros?»

R: No directamente. Todo se pasa como strings. Para objetos complejos, serializa a JSON string.

P: ¿Cómo paso múltiples valores en un solo parámetro?

Sección titulada «P: ¿Cómo paso múltiples valores en un solo parámetro?»

R: Usa delimitadores:

// Pasar: "valor1,valor2,valor3"
string valores = ctx.GetParameter("LISTA");
string[] items = valores.Split(',');

R: Sí, es case-sensitive. Usa siempre MAYÚSCULAS por convención.

P: ¿Puedo llamar mi script desde fuera de EPLAN?

Sección titulada «P: ¿Puedo llamar mi script desde fuera de EPLAN?»

R: Sí, desde Add-ins o aplicaciones externas que referencien EPLAN API.


Antes de pasar al siguiente capítulo, asegúrate de:

  • Entender qué es ActionCallingContext
  • Saber leer parámetros con GetParameter
  • Poder agregar parámetros de salida con AddParameter
  • Validar parámetros de entrada
  • Usar valores por defecto
  • Haber ejecutado el ExportadorPDF
  • Poder llamar scripts con parámetros desde otro script
  • (Opcional) Crear tu propio script parametrizable

¡Felicitaciones! Ahora puedes crear scripts flexibles y reutilizables. 🎉

Tus scripts pueden adaptarse a diferentes escenarios sin cambiar el código.

¿Listo para logging y debugging profesional? ¡Vamos al Capítulo 15! 🚀


Última actualización: Enero 2025 Tiempo de lectura estimado: 70-80 minutos Código de ejemplo: code/cap-14/

Todos los scripts de este capítulo están disponibles en GitHub:

📥 Ver código en GitHub →

Los scripts son 100% funcionales y usan únicamente APIs gratuitas de EPLAN.


🔓 Desbloquea el Contenido Completo

¿Te gustó este capítulo? Hay 25 capítulos más esperándote con:

  • ✅ Scripts profesionales completos
  • ✅ Casos de estudio reales
  • ✅ Suite de automatización integrada
  • ✅ Ahorra 80-95% de tiempo en tareas repetitivas