Archivo de la etiqueta: Workflow

Como lanzar un Workflow programaticamente en SharePoint

Tras un periodo de inactividad, vuelvo con un nuevo post… Esta vez se trata, de la necesidad de lanzar un nuevo Workflow a nivel de listas o biblioteca en todos los ítems, previamente creados. Si el Workflow se configura para que se lance a la creación o modificación del ítem, puede que haya muchos ítems, que por antigüedad, no se modifiquen y no se lance el Workflow asociado.

Para realizar esto desde el API de SharePoint, la forma mas sencilla es la siguiente:

static private void LanzarWorkflow()
{
  //definición de variables necesarias para la ejecución
  string SP_URL = "http://mi_sharepoint";
  string LIST_NAME = "Pages";
  //este es el GUID del BaseID del Workflow que queremos ejecutar
  Guid wfBaseId = new Guid("b81abdd8-faf4-4bed-86ca-a49d9cc9913e");
  //se ejecuta con privilegios elevados
  SPSecurity.RunWithElevatedPrivileges(delegate
  {
	try
	{
	  using (SPSite site = new SPSite(SP_URL))
	  {
		using (SPWeb web = site.OpenWeb())
		{
		  SPList list = web.Lists[LIST_NAME];
		  SPListItemCollection items = list.Items;
		  for (int i = 0; i < items.Count; i++)
		  {
			web.AllowUnsafeUpdates = true;  
			//selecciona el item actual
			SPListItem item = items[i];
			Console.WriteLine(string.Format("[Item] Lanzando workflow para el item Id: {0} ", item.ID));
			//obtiene el objeto plantilla de WF asociado a la lista que queremos
			SPWorkflowAssociation associationTemplate = list.WorkflowAssociations.GetAssociationByBaseID(wfBaseId);
			//lanzar el WF a nivel del item
			web.Site.WorkflowManager.StartWorkflow(item, associationTemplate, associationTemplate.AssociationData);
			web.AllowUnsafeUpdates = false; //bloquea cambios por codigo
		  }
		}
	  }
	}
	catch (Exception ex) { Console.WriteLine(string.Format("***ERROR*** {0}", ex.ToString())); }
  });
}

Los únicos parámetros que necesita esta función son:

  • SP_URL: Url del sitio de SharePoint donde se encuentra la lista que tiene asociada el Workflow que deseamos lanzar
  • LIST_NAME: Nombre de la lista o biblioteca que tiene el Workflow
  • wfBaseId: por ultimo el Base ID del Workflow (este GUID lo puedes ver, por ejemplo, desde SharePoint Designer, editando el archivo XML de configuración del propio Workflow)

 

Como obtener el estado del Workflow de un Item con C#

Una de las cosas que me ha surgido, ha sido la necesidad de obtener mediante programación, el estado de los items de una lista o biblioteca en SharePoint 2010.

Es un proceso muy sencillo, ya que hay que obtener la el valor del campo que se genera en la lista, cuando se le asocia un workflow, únicamente lo que debemos hacer posteriormente, es convertir el numero por un texto legible. En caso de ser necesario puedes hacer directamente la traducción en castellano de los estados, si eliminas la linea System.Enum.GetName(typeof(SPWorkflowStatus), WorkflowStatusValue) y la sustituyes por un switch por ejemplo…

Aquí os dejo una función que podrá serviros de ayuda, los unicos parametros que hay que pasar son:

siteUrl = Url del sitio
listName = Nombre de la lista o libreria a la cual esta asociado el workflow
itemId = Identificador, del item que queremos consultar
wfFieldName = Nombre del campo de la lista donde se muestra el estado del workflow

 

static string GetWorkflowStatud(string siteUrl, string listName, int itemId, string wfFieldName)
{
  string result = string.Empty;
  SPSecurity.RunWithElevatedPrivileges(delegate
  {
	try
	{
	  using (SPSite spSite = new SPSite(siteUrl))
	  {
		using (SPWeb spWeb = spSite.OpenWeb())
		{
		  //instancia la lista/biblioteca
		  SPList spList = spWeb.Lists[listName]; 
		  //recupera el item de la lista
		  SPListItem spListItem = spList.Items.GetItemById(itemId); 
		  //recupera el valor del campo del Workflow
		  Int32 WorkflowStatusValue = Convert.ToInt32(spListItem[wfFieldName]); 
		  //traduce el numero a texto
		  string WorkflowStatusString = System.Enum.GetName(typeof(SPWorkflowStatus), WorkflowStatusValue); 
		  //almacena el estado del Workflow
		  result = WorkflowStatusString;
		}
	  }
	}
	catch (Exception ex) { result = ex.Message; }
  });
  return result;
}

Para más información, puedes consultar el enumerador SPWorkflowStatus con los posibles estados del workflow.

 

SharePoint Designer: Unexpected error on server associating the workflow

Utilizando los workflows estándar de SharePoint 2010, nos ha aparecido el siguiente problema, cuando hemos intentado desde SharePoint Designer 2010 publicar un Workflow con múltiples pasos de aprobación: “Errors were found when compiling the workflow. The workflow files were saved but cannot be run. Unexpected error on server associating the workflow“. En la siguiente imagen podemos ver la pantalla de error del Designer:

Buceando en Internet, he encontrado que Microsoft tiene reportado en el siguiente articulo: http://support.microsoft.com/kb/2557533 este problema, en el que se indica que es necesario aumentar la propiedad UserDefinedWorkflowMaximumComplexity, para poder implementar workflows con muchos pasos.

El valor actual de dicha propiedad se encuentra por defecto en 7000 por lo que podríamos aumentarlo a 30000 para que no nos vuelva a pasar este problema… para ello lo único que debemos hacer es ejecutar este sencillo script de PowerShell , donde se aumenta el valor de UserDefinedWorkflowMaximumComplexity:

 

$app = get-spwebapplication http://miintranet.com
Write-Host "Limite actual: " $app.UserDefinedWorkflowMaximumComplexity
$app.UserDefinedWorkflowMaximumComplexity = 30000
$app.Update()
Write-Host "Nuevo limite: " $app.UserDefinedWorkflowMaximumComplexity

 

Por ultimo solo queda reiniciar el servicio IIS con un IISReset de todas las maquinas de la granja, y volver a publicar el workflow desde Designer…

Actualización: Otra solución a este problema, que personalmente no he probado, es la de realizar unas pequeñas modificaciones en el web.config de la aplicación, como se indica en Manjuke’s Blog sin necesidad de tener que tocar parámetros de objetos SharePoint.