Category Archives: 17198

Sharepoint 2010 + Infopath 2010: The operation could not be completed

En un formulario de Infopath, al crear una nueva conexión de extracción de datos, se presentó el siguiente mensaje de error:

En mi escenario, se creó un solo sitio de Project Web Application y un sitio secundario con una biblioteca de formularios. El mensaje de error se presenta cuando no se encuentra creada una colección de sitios en el sitio raiz de IIS.

Para solucionar el problema ejecutar el siguiente procesimiento:

– Utilizar la consola de Administración Central de Sharepoint para crear una colección de sitios en el sitio raiz de IIS (Sitio Web por Defecto).

– Crear nuevamente la conexión de recepción de información en el formulario de Infopath.

 

 

Como siempre espero esta información sea de su utilidad.

Sharepoint 2010 – Infopath 2010: Check-In y Check-Out automático de un formulario.

Al igual que cualquier documento que puede ser abierto y modificado por varias personas, es importante controlar que solo una persona a la vez pueda tomar el control de un documento (desproteger) y realizar los cambios necesarios, asegurando que cualquier otro usuario que abra el mismo documento solo tenga una vista de lectura. Al finalizar el proceso de edición, el usuario que tomó el control debe grabar y cerrar el documento (proteger) de tal forma que otro usuario pueda tomar el control de mismo cuando lo requiera.

Para el caso de los formularios de Infopath 2010, y sobre todo cuando trabajamos con un workflow relacionado a la biblioteca de formularios, es importante que este proceso de desprotección y protección sea transparente para el actor (usuario) de la actividad actual.

Para lograr este objetivo hay que ejecutar los siguiente pasos:

1. Crear dos conexiones relacionados a los servicios web Checkoutfile y Checkinfile. Ambos servicios web los expone directamente Sharepoint.

 

 

 

Algunos enlaces importantes:

http://www.infopathdev.com/blogs/mel_balsamo/archive/2011/05/15/create-an-xtp-to-check-in-and-check-out-forms-using-udc-files.aspx

http://www.infopathdev.com/forums/p/16360/61173.aspx

http://www.infopathdev.com/forums/t/7603.aspx

Como enviar archivos adjuntos de Infopath 2010 como adjuntos de correo electrónico.

El reto de hoy es generar el código necesario para poder enviar un documento adjunto de un formulario de Infopath 2010 como un adjunto de un correo electrónico. Como base es necesario tener al menos un control de tipo adjunto y un botón en el formulario. En el botón es necesario ingresar el siguiente código:

– Importante incluir las siguientes referencias:

using System.IO;
using System.Net.Mail;
using System.Text;

– Algunas variables y constantes necesarias para el proceso:

private const int SP1Header_Size = 20;
private const int FIXED_HEADER = 16;
private int fileSize;
private int attachmentNameLength;
private string attachmentName;
private byte[] decodedAttachment;

– Dos funciones principales que cumplen la función de decodificadores del archivo adjunto:

public void InfoPathAttachmentDecoder(string theBase64EncodedString)
  {
   byte [] theData = Convert.FromBase64String(theBase64EncodedString);
   using(MemoryStream ms = new MemoryStream(theData))
   {
    BinaryReader theReader = new BinaryReader(ms);   
    DecodeAttachment(theReader);
   }
  }

  private void DecodeAttachment(BinaryReader theReader)
  {
   //Position the reader to obtain the file size.
   byte[] headerData = new byte[FIXED_HEADER];
   headerData = theReader.ReadBytes(headerData.Length);

   fileSize = (int)theReader.ReadUInt32();
   attachmentNameLength = (int)theReader.ReadUInt32() * 2;
   
   byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength);
   //InfoPath uses UTF8 encoding.
   Encoding enc = Encoding.Unicode;
   attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength – 2);
   decodedAttachment = theReader.ReadBytes(fileSize);
  }

– Y finalmente la llamada a los procedimientos en el botón del formularios, este código aplica cuando es un solo campo de documento adjunto:

 XPathNavigator Adjunto = this.MainDataSource.CreateNavigator().SelectSingleNode(“/my:misCampos/my:Adjuntos/my:Documento”, this.NamespaceManager);
String textoAdjunto = Adjunto.Value;
if (textoAdjunto.Length > 0)
{
                InfoPathAttachmentDecoder(textoAdjunto);
                MemoryStream streamAdjunto = new MemoryStream(decodedAttachment);
                Attachment adjuntoCorreo = new Attachment(streamAdjunto, attachmentName);
                MailMessage mail = new MailMessage();
                SmtpClient SMTPServer = new SmtpClient(“servidor_correo”);
                mail.From = new MailAddress(“remitente@midominio.com“);
                mail.To.Add(“destinatario@otrodominio.com“);
                mail.Subject = “Adjunto desde Infopath”;
                mail.Body = “prueba”;
                mail.Attachments.Add(adjuntoCorreo);
                SMTPServer.Send(mail);
}

– Este código aplica cuando es una tabla de repetición:

XPathNavigator root = MainDataSource.CreateNavigator();
XPathNodeIterator RepTable = root.Select(“/my:misCampos/my:Adjuntos”, NamespaceManager);
MailMessage mail = new MailMessage();
SmtpClient SMTPServer = new SmtpClient(“servidor_correo”);
mail.From = new MailAddress(“remitente@midominio.com“);
mail.To.Add(“destinatario@otrodominio.com“);
mail.Subject = “Adjuntos desde infopath”;
mail.Body = “prueba”;
while (RepTable.MoveNext())
{
                XPathNavigator Adjunto = RepTable.Current.SelectSingleNode(“my:Documento”, NamespaceManager);
                String textoAdjunto = Adjunto.Value;               
                if (textoAdjunto.Length > 0)
                {
                    InfoPathAttachmentDecoder(textoAdjunto);
                    MemoryStream streamAdjunto = new MemoryStream(decodedAttachment);
                    Attachment adjuntoCorreo = new Attachment(streamAdjunto, attachmentName);
                    mail.Attachments.Add(adjuntoCorreo);                   
                }
}
SMTPServer.Send(mail);

Algunos enlaces de referencia:

http://support.microsoft.com/kb/2517906

http://support.microsoft.com/kb/892730

http://www.csharp411.com/c-convert-string-to-stream-and-stream-to-string/

http://social.msdn.microsoft.com/Forums/en-US/sharepointinfopath/thread/87e79f00-0277-4dbe-9092-c9e9bafe23a0/

Error en ejecución de flujo de trabajo – Sharepoint 2010 – Infopath 2010

Escenario: una biblioteca de formularios con una plantilla de infopath publicada. Un flujo de trabajo creado en SPD 2010 que actualiza varios campos de la biblioteca (set current item field value) y se ejecuta automáticamente cuando se crea un nuevo documento.

El problema: randómicamente durante el proceso de ejecución del flujo de trabajo éste no continua. Al revisar la ejecución del flujo me encuentro con lo siguiente:

Algunos puntos a tomar en cuenta:

– La biblioteca de formularios está configurada para que no requiera que se desprotejan (check-out) los elementos para que se modifiquen.

– El flujo de trabajo tiene como primera tarea esperar por 1 minuto antes de continuar.

– Se ejecutó ya el comando: stsadm -o setproperty -propertyname “job workflow” -propertyvalue “every 1 minutes between 0 and 59” -url http://sitio, según algunos foros que he podido visitar el colocar una acción de pausa  podría provocar este problema.

– El mensaje de error, de acuerdo al gráfico, es: “Actualmente está bloqueada la edición del elemento. En espera de la protección del elemento o de la liberación del bloqueo”, traducido al inglés: “The item is currently locked for editing. Waiting for item to be checked in or for the lock to be released.“, sin embargo, al momento de guadar el formulario de Infopath exite una acción de cerrar el mismo por lo que se asegura que el elemento no está abierto durante la ejecución del flujo.

Acciones por ejecutar:

De acuerdo a algunos foros que he podido visitar sugieren hacer lo siguiente:

– Revisar que durante la ejecución del flujo de trabajo no se haga referencia a la asignación de valores de campos que hayan sido eliminados.

– Cambiar la acción de “detener el flujo por un minuto” por la acción “Wait for document to be Unlocked by document editor“.

 

 

– Cada vez que se publica un flujo se mantiene una  versión en la biblioteca, se recomienda eliminar todos los flujos y volverlos a publicar.

Voy a proceder con la ejecución de estas recomendaciones y estaré actualizando este post muy pronto con los resultados.

Algunos enlaces importantes / referencia:

http://social.technet.microsoft.com/Forums/en-US/sharepoint2010customization/thread/fc4e1073-d67f-449a-b443-e5805f5358c7/

http://social.msdn.microsoft.com/Forums/ta/sharepoint2010general/thread/36d8d3bb-8d15-4d7c-aa93-7117dfa253a1

http://sharepoint.stackexchange.com/questions/16261/unable-to-update-field-with-sp-designer-2010-workflow

http://www.sharepointed.com/2012/02/23/the-item-is-currently-locked-for-editing-waiting-for-item-to-be-checked-in-or-for-the-lock-to-be-released/

Infopath 2010 al utilizar el método currentview.export pierde el foco del formulario actual

Tengo un formulario simple de InfoPath 2010 con un campo de texto y un botón. El código personalizado que tiene el botón es el siguiente:

 public void CTRL2_5_Clicked(object sender, ClickedEventArgs e)
        {
            // Escriba aquí su código.
           
            try
            {
                generaDocumento();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void generaDocumento()
        {
            this.CurrentView.Export(@”C:\temp\prueba.pdf”, ExportFormat.Pdf);
        }

 

Curiosamente cuando hago clic en el botón, el formulario InfoPath pierde foco y se presenta la última ventana que se visitó antes de ejecutar el formulario. Para solucionar de alguna forma este problema hice el siguiente cambio:

 public void CTRL2_5_Clicked(object sender, ClickedEventArgs e)
        {
            // Escriba aquí su código.
           
            try
            {
                generaDocumento();
                MessageBox.Show(“documento generado”);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

Agregué una línea de código para que se presente un cuadro de mensaje y el foco se mantuvo, claro que el cuadro del mensaje jamás se presentó. Intenté crear un nuevo hilo de ejecución (Thread) sin éxito, es más, con esta opción dejó de funcionar. No se si InfoPath tiene soporte para ejecución de hilos.

De todas formas les dejo este post y esperando sus comentarios.

Modificación del campo "Creado por" de una lista de Sharepoint 2010

Por defecto el campo “Creado por”, al igual que algunos otros dentro de una lista de SharePoint 2010, no pueden ser modificados por medio de una interfaz gráfica por defecto de SharePoint o un workflow, sin embargo, por medio de Powershell es posible hacerlo ejecutando algunos comandos.

Comparto con ustedes esta secuencia de comandos que funcionaron para mi en SharePoint 2010 con una lista llamada “Gestión Documental” y un campo secuencial “Código del documento” que sirve como identificador adicional de cada documento.

Las líneas “Read-Host” solicitan al usuario que ejecuta el script que ingrese el código del documento a modificar y el usuario con el cual se va a actualizar.

$Codigo = Read-Host “Ingrese el código del documento”
$Usuario = Read-Host “Ingrese el nombre del propietario”
$Web = Get-SPWeb http://sitiosharepoint
$List = $Web.Lists[“Gestión Documental”]
$items = $List.Items

Foreach($item in $items)
{
if($item[“Código del documento”] -eq $Codigo)
{
$item[“Creado por”]=$usuario
$item[“UsuarioCambios”]=”dominio\nombre_usuario”
$item.Update()
}
}

El formato del usuario debe ser ingresado como: ID;#nombre_usuario. Para obtener esta información el usuario debe estar registrado en SharePoint. Se puede obtener esta información con la siguiente secuencia de comandos:

$web=Get-SPWeb http://sitiosharepoint
$user=$web.SiteUsers[“dominio\nombre_usuario”]
$user.id
42

En el caso de actualizaciones masivas es posible utilizar sentencias o consultas CAML para poder filtrar la cantidad de registros a retornar, por ejemplo (Extraído del sitio http://get-spscripts.com/2010/09/get-all-column-values-from-sharepoint.html):

#Check if the item is a file or list item and run a different query accordingly
    if ($list.BaseType -eq “DocumentLibrary”) {
        $queryString = “<Where><Eq><FieldRef Name=’FileLeafRef’ /><Value Type=’File’>” + $ItemName + “</Value></Eq></Where>”
    }
    else
    {
        $queryString = “<Where><Eq><FieldRef Name=’Title’ /><Value Type=’Text’>” + $ItemName + “</Value></Eq></Where>”
    }

    #Create the CAML query to find the item
    $query = New-Object Microsoft.SharePoint.SPQuery
    $query.Query = $queryString
    $item = $list.GetItems($query)[0]

Para poder construir las consultas CAML utilizando la herramienta “U2U CAML Query Builder” que se lo puede descargar de http://www.u2u.net/Tools/wincamlquerybuilder/CamlQueryBuilder.aspx

Algunos enlaces adicionales que les pueden servir:

http://sharepointrelated.com/2012/05/03/addedit-list-items-using-powershell-in-sharepoint-2010/

http://davidlozzi.com/2012/02/14/playing-with-sharepoint-data-in-powershell/