")); Microsoft Dynamics CRM Blog: CRM to all: 2010

miércoles, 22 de diciembre de 2010

Librerías de javascript compartidas en CRM 2011

Una de las nuevas funcionalidades relacionadas con las inclusiones de Javascript, es la posibilidad de que creación de librearías de Javascript compartidas. De hecho, ahora esta mucho mejor y ordenado, de forma que se pueden incluis librearía de forma dinámica y compartirlas entre entidades.
A continuación, muestro unos pantallazos de como se crearía una librería compartida:

Creación del recurso compartido

Recurso compartido

Funciones compartidas en la librería

Publicando los cambios

Añadir la librería en Cuentas

Selección del recurso compartido

Añadirlo en OnLoad

jueves, 16 de diciembre de 2010

Versión CRM 2011 Release Candidate

Bueno, en el proceso de publicación de una nueva versión de productos de CRM, se ha llegado a uno de los últimos pasos, el Release Candidate.
Esta versión acumula lo ya disponible en la beta, mas comentarios, errores, etc detectados por los usuarios que han estado probando dicha versión.
Es justo la versión anterior a la RTM, que será la definitiva.

Para más información acerca de la version de CRM 2011 Release Candidate, ir al blog del equipo de CRM:
http://blogs.msdn.com/b/crm/archive/2010/12/14/microsoft-dynamics-crm-2011-release-candidate-rc-announcement.aspx

un cordial saludo,

miércoles, 15 de diciembre de 2010

Picklists globales en CRM 2011

Pues sí, en CRM 2011 (por fin) podemos disponer de un picklist que sea compartido entre varias entidades.
De esta forma, podemos por ejemplo crear desplegables para Paises, Provincias, Tipos, Clasificaciones, etc. que se compartirán entre varias entidades. Así, con solo añadir un valor en el picklist, se añadirá en todas las entidades.

Los pasos a seguir para crear un picklist "global" (option sets) son los siguientes en donde muestro un ejemplo de como crear y utilizar un Option set de "Países":

Creación del Option set
















Definir los valores de los Países































Publicar el Option Set















Utilización del Option Set en otras entidades (Cuenta)






Este tipo de Picklist, puede ser definido que no pueda ser modificado


viernes, 3 de diciembre de 2010

Alineaciones de campos numéricos

En su día, publiqué un artículo acerca de como alinear importes en la derecha de las columnas de las vistas utilizando JQuery (http://crmtoall.blogspot.com/2010/03/alineando-importes-la-derecha-en-vistas.html).
Ahora voy a explicar una forma de alineación que se basa en la modificación de las clases propias del CRM, lo cual por supuesto no esta soportado, pero nos permite modificar la forma en que el CRM nos muestra los números.

La forma sería:

Para los grids: modificar el fichero "/_grid/AppGrid.css.aspx" en la clase ‘nobr.num’ y a añadir el texto "text-align: right".

Para los formularios: modificar el fichero “/_forms/controls/controls.css.aspx” la clase 'INPUT.ms-crm-Number' y añadir el valor "text-align: right".

De esta forma, podemos alinear importes hacia la derecha.

un saludo!

jueves, 25 de noviembre de 2010

Flujos de trabajo con de tipo "dialog" en CRM 2011

En CRM 2011 el tema de los antiguos Flujos de trabajo ha sido mejorado de forma importante. Con la nueva versión podremos seguir creando los antiguos flujos de trabajo (que funcionan asíncronamente) y tambien tenemos la posibilidad de ejecutar "Diálogos".
De esta forma, definiendo un flujo de trabajo, se podrán hacer guías paso a paso a los usuarios, ayudas y demas funcionalidades mediante unos flujos que nos permitirán ir pidiendo datos a los usuarios y haciendo acciones de forma interactiva.
En este post, explicaré un pequeño ejemplo de la funcionalidad de estos diálogos. Imaginemos que en vez de crear una Cuenta de la forma tradicional (abriendo el formulario, rellenando los datos, etc) quiero guiar a los usuarios paso a paso para ir rellenando solo ciertos datos, y con mensajes de ayudas.
Para empezar, creamos un nuevo "Proceso" de tipo "Diálogo":
Creación del proceso

















Luego definimos los pasos a seguir (en este caso solo 2 pasos) y publicamos el proceso:
Proceso del díalogo















En este proceso, simplemente en un primer paso se pide el nombre y el numero de la cuenta, y en un segundo paso se solicita una cualificación de la misma. Finalmente se crea la cuenta con esos datos.

Ejecutamos el diálogo:











Rellenamos los datos del primer paso:

















Y del segundo:

















Y finalizamos el proceso:
















Como se ha visto, es muy sencillo hacer procesos guiados para la creación de información en CRM, de forma que se vaya solicitando al usuario la información a rellenar.
Solo hay que hecharle un poco de imaginación para imaginarse para todo lo que puede servirnos esta nueva funcionalidad!

un abrazo

viernes, 19 de noviembre de 2010

Publicado el Rollup 14!

Pues sí, seguimos con los Rollups, ahora ya salió el nuevo Rollup (y van 14).
Para descargarlo ir a este link:
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=0fde5456-05a5-4407-81b3-0eaa928c8cc3&displaylang=en

Para información detallada de la actualización ir a: http://support.microsoft.com/kb/2389019

Como siempre, mucho cuidado con todas las funcionalidades, probar todo bien y ver que tal va todo.

Un saludo,

martes, 9 de noviembre de 2010

Próximas sesiones de CRM 2011 de XRM Virtual User Group


XRM Virtual User Group







El grupo de usuarios "XRM Virtual User Group" (http://www.xrmvirtual.com/) tiene planificadas una serie de sesiones online presentando diferentes funcionalidades de CRM 2011, que recomiendo seguir, ya que suelen estar bien planificadas, y son muy útiles.
La lista de eventos es la siguiente (ver http://www.xrmvirtual.com/events para posibles nuevos eventos):
Un saludo!

lunes, 8 de noviembre de 2010

Nuevas opciones para la gestión de entidades en CRM 2011

En CRM 2011, han añadido ciertas funcionalidades nuevas en lo que respecta a  la personalización de Entidades.
En realidad, lo que se ha añadido es en parte nuevas funcionalidades, y en otra parte, funcionalidades existentes ya en CRM 4.0, hacerla genéricas y administrables desde las personalizaciones.
Esta es una imagen de un formulario de personalización de CRM 2011:
CRM 2011 - Personalización de entidades

Como allí se ve, entre las nuevas posibilidades se destacan:
  • La posibilidad de definir cualquier entidad como una "Actividad".
  • Enviar correos electrónicos
  • Añadir a colas (enrutamiento)
  • Habilitar la posibilidad de añadir conexiones
  • Habilitar la gestión de documentos con Sharepoint
  • Posibilidad de habilitar auditorías
Un saludo,

miércoles, 3 de noviembre de 2010

Han publicado una nueva SDK (4.0.13)

Pues sí, a pesar que Microsoft está centrando los "tiros" en la nueva versión 2011, no se olvidan de la actual y ahn publicado una nueva versión de la SDK (la 4.0.13).
Pueden descargársela de aquí:
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=82E632A7-FAF9-41E0-8EC1-A2662AAE9DFB&displaylang=en

 
En las cosas que hay actualizadas destacan:
  • Actualización de las librerías de la carpeta SDK\bin
  • Actualizados los ejemplos y documentos de SDK\Microsoft.xRM
  • Actualización de ejemplos de LINQ
  • Información sobre como utilizar la Cookie de paginación (Paging Cookie)
  • Etc.
 La verdad no hay cambios muy importantes, pero para los que trabajan con CRM 4.0 es bueno saber que seguimos teniendo "updates".

un saludo

martes, 19 de octubre de 2010

Datos de ejemplo en CRM 2011

Una funcionalidad muy útil que he encontrado para CRM 2011, es el de la creación masiva de datos de ejemplo.
Esto puede ser muy útil a la hora de hacer demos, y poder enseñar las funcionalidades estándar de CRM 2011, sin tener que "perder" tiempo creando datos de ejemplo.
En la SDK, hay un programa de consola, con el código explicando como crear estos datos.
La carpeta es: \SampleCode\CS\GeneralProgramming\Other\ImportOrRemoveSampleData.cs
CRM 2011 tiene simplemente un Mensaje para que se instalen o desinstalen los datos de ejemplo.
El código para realizar esta llamada es muy simple:

// Prompt user to install/uninstall sample data.
Console.WriteLine("Would you like to:");
Console.WriteLine("1) Install sample data for Microsoft Dynamics CRM?");
Console.WriteLine("2) Uninstall sample data for Microsoft Dynamics CRM?");
Console.Write("Press [1] to Install, [2] to Uninstall: ");
String answer = Console.ReadLine();

// Update the sample data based on the user's response.
switch (answer)
{
   case "1":
      Console.WriteLine("Installing sample data...");
      InstallSampleDataRequest request =new InstallSampleDataRequest();
      InstallSampleDataResponse response =(InstallSampleDataResponse)_serviceProxy.Execute(request);
      Console.WriteLine("Sample data successfully installed.");
      break;
   case "2":
      Console.WriteLine("Uninstalling sample data...");
      UninstallSampleDataRequest request2 = new UninstallSampleDataRequest();
      UninstallSampleDataResponse response2 = (UninstallSampleDataResponse)_serviceProxy.Execute(request2);
      Console.WriteLine("Sample data successfully uninstalled.");
      break;
   default:
      Console.WriteLine("Neither option was selected. No changes have been made to your records.");
      break;
   }


Esto crea datos de ejemplo de Cuentas, Contactos, Leads, Oportunidades, etc.

un saludo

viernes, 15 de octubre de 2010

Nuevos Javascripts en formularios de CRM 2011

Siguiendo revisando la SDK, me encontré que la forma de interactuar con los formularios a través de los Javascripts han cambiado un poco. Bueno en realidad, por completo.
Según dice la SDK: "Scripts using crmForm will continue to work in Microsoft Dynamics CRM 2011". Es decir que nuestros Javascripts realizados para 4.0, seguirán funcionando en la nueva versión (siempre y cuando sean soportados, por supuesto).
Obviamente lo que no funcionará serán las nuevas funcionalidades como los múltiples formularios por entidad,la posibilidad de mostrar un atributo mas de una vez en el mismo formulario, o la posibilidad de ocultar elementos del formulario.
Entre los ejemplos, podemos detectar que hay cambios significativos, que además ofrecen una gran variedad de nuevas funcionalidades, dejo algunos ejemplos:
  1. Nuevo objeto Xrm.Page.context:
    • .getUserRoles(): Devuelve un "array" con los roles del usuario
    • .getUserId(): Devuelve el "id" del usuario actual 
  2. Nuevo objeto Xrm.Page.data.entity:
    • .getDataXml(): Devuelve el Xml que se enviará al servidor al guardar
    • .save(): Pasándole algunos de los 3 tipos de guardar como parámetro.
  3. Nuevo objeto Xrm.Page.ui: para acceder a los objetos del formulario
    • .getCurrentControl(): Devuelve el objeto que tiene el foco
    • .refreshRibbon(): Provoca que se refresque el Ribbon según los datos
  4. Nuevo objeto Xrm.Page.ui.control
    • .setVisible(): Por fin! para ocultar atributos 
    • .setLabel(): Para determinar la etiqueta del atributo
    • .refresh(): Para actualizar un "subgrid"
    • .getParent(): Para recoger la sección que contiene el atributo
    • .setDefaultView(viewGuid): Para determinar la vista predeterminada de selección del "lookup".
Uffs, la verdad que hay mucho mucho nuevo, y todo tiene buena pinta...

La verdad que parece que en Microsoft han hecho caso a bastantes de nuestras exigencias como desarrolladores para CRM, facilitándonos las cosas haciendo "soportadas" muchas cosas que a veces teníamos que hacer de forma no soportada.

Un saludo,

viernes, 8 de octubre de 2010

Nuevos tipos de Datos en CRM 2011

He seguido revisando la nueva SDK del CRM 2011, y allí encontré algo que me dió mucha alegría en relación con los tipos de datos del nuevo CRM.
En relación con esto, hay un artículo con el título "Use the New Types" donde hace un mapeo y una comparación de tipos de datos entre CRM 4.0 y CRM 2011.
La sorporesa proviene de que todos los "viejos" tipos de datos como "Crm*" desaparecen, y se comenzarán a utilizar los tipos de datos nativos de .NET (VIVA!).
Agrupando los mismos los cambios mas significativos son:

  • 1) Los campos "Crm*" (CrmDecimal, CrmBoolean, CrmDateTime, CrmFloat, CrmNumber, Key) pasan a ser tipos nativos de .NET (System.Decimal, System.Boolean, System.Boolean, System.Double, System.Integer, System.Guid)

  • 2) Los tipos de referencias (Lookup, Customer, Owner) pasan a ser un nuevo único tipo (EntityReference)


  • Incluyo una imagen con el mapeo de tipos de datos:
    Type Mapping Between Versions

    martes, 5 de octubre de 2010

    Adiós a las "DynamicEntity" en CRM 2011

    Microsoft ha empezado a "soltar" mucha información relacionada con el nuevo CRM 2011.
    Dentro de esta información a publicado una versión "beta" de la futura SDK, que ya deja ciertas ideas de hacia donde apuntan los tiros del xRM.
    La SDK puede descargarse de aquí: http://go.microsoft.com/fwlink/?LinkID=200082&clcid=0x409.
    Intentaré poco a poco ir publicando las novedades y cambios que vaya encontrando en la misma.
    Uno de los puntos mas interesantes viene relacionado con la "muerte" de la clase "DynamicEntity", que solemos utilizar para trabajar con la SDK.
    A partir de ahora, se llamará "Entity", que será la clase que va reemplazar a la citada "DynamicEntity".
    Esto provocará algunas ventajas como que será mucho mas cómodo trabajar con todas las entidades.
    La clase Entity pasa a estar en "Microsoft.Xrm.Sdk".
    Estos son algunos ejemplos de los cambios:
    //CRM 2011
    Entity entity = new Entity(Account.EntityLogicalName);
    entity["accountid"] = Guid.NewGuid();
    
    // CRM 4.0
    DynamicEntity entity = new DynamicEntity();
    entity.Name = EntityName.account.ToString();
    entity["accountid"] = new Key(Guid.NewGuid());
    

    Un saludo,

    martes, 28 de septiembre de 2010

    Formatos de datos en CRM


    Si bien en CRM al hacer consultas a través de la plataforma ya nos devuelve los datos formateados según los datos del usuario que realiza las consultas, muchas veces es necesario recoger esa configuración del usuario para presentar la información según su formato.
    De esta forma podremos hacer que nuestros desarrollos sean totalmente "multiformato" y que este se recoja dinámicamente desde el CRM.
    Para esto existe una función de SQL Server que provee el CRM que se llama de la siguiente forma:
    SELECT * FROM dbo.fn_GetFormatStrings()
    Esta función esta documentada en la SDK y se puede llamar de forma soportada. Para mas información acerca de esta función ir a: http://msdn.microsoft.com/en-us/library/bb955087.aspx
    Esto devuelve una serie de datos relacionados con el usuario que realiza la consulta (con la autenticación de Windows Integrada) que nos servirán para luego formatear cualquier tipo de dato.
    Esto nos devuelve por ejemplo:
    • DateFormat: dd\/MM\/yyyy
    • TimeFormat: hh\:mm tt
    • NumberLanguageCode: en-GB
    • CalendarType: Gregorian
    • NumberFormat_0_Precision: ###,###,###,##0;-###,###,###,##0;0
    • NumberFormat_2_Precision: ###,###,###,##0.00;-###,###,###,##0.00;0.00
    • CurrencyFormat_0_Precision: "£"###,###,###,##0;-"£"###,###,###,##0;"£"0
    • CurrencyFormat_2_Precision: "£"###,###,###,##0.00;-"£"###,###,###,##0.00;"£"0.00
    Entonces estos resultados podemos usarlos en C# para formatear datos, por ejemplo:
    DateTime dtfecha = new DateTime(2010, 1, 1);
    double dblNumero = 587125635.66;
    
    Console.WriteLine(dtfecha.ToString(@"dd\/MM\/yyyy"));
    Console.WriteLine(dblNumero.ToString(@"###,###,###,##0;-###,###,###,##0;0"));
    Console.WriteLine(dblNumero.ToString(@"""£""###,###,###,##0.00;-""£""###,###,###,##0.00;""£""0.00"));
    
    Esto nos devuelve:

    Y listo! de esta simple manera, dejaremos nuestros desarrollos en multiformato recogiéndo los mismos desde el CRM.

    un abrazo 

    viernes, 24 de septiembre de 2010

    Publicado el Rollup 13

    En estos "movidos" días con noticias acerca del CRM 2011, se podría pensar que se esta dejando olvidado al "viejo?" Dynamics CRM 4.0.
    Pues nada mas lejos de la realidad, ayer el equipo de desarrollo de Microsoft ha publicado un nuevo Rollup (y ya van 13!!).
    Como siempre es mejor probar toda nuestra implementación en un servidor de desarrollo antes de instalar los servidores de producción.
    Como nota destacable se recoge la compatibilidad con Internet Explorer 9 Beta (http://www.microsoft.com/ie).

    un Saludo

    miércoles, 15 de septiembre de 2010

    Buenas prácticas con los metadatos

    Casi siempre en nuestros desarrollos necesitamos ir a los metadatos del CRM, para ver determinados atributos, tamaños, personalizaciones, etc.
    Esto nos hará nuestros desarrollos mas dinámicos y adaptables, además de ser mas "inteligentes".
    Para esto hay varias formas de acceder a los metadatos, y es necesario que se haga de una forma que afecte lo menos posible al rendimiento tanto de nuestro desarrollo como del servidor de CRM.
    Es por esto que me pregunté que diferencias de rendimiento podría haber si en vez de recoger un atributo mediante el mensaje "RetrieveAttribute", recojo la entidad completa mediante el mensaje "RetrieveEntity" o incluso recogiendo todas las entidades con el "RetrieveAllEntities".
    Para esto me desarrollé la siguiente aplicación de consola que me muestra las diferencias de tiempos de respuesta:
    CrmAuthenticationToken token = new CrmAuthenticationToken();
                token.OrganizationName = "AdventureWorks";
    
                token.AuthenticationType = 0;
    
                MetadataService metadataService = new MetadataService();
                metadataService.Url = "http://192.168.1.22:5555/MSCRMServices/2007/MetadataService.asmx";
                metadataService.CrmAuthenticationTokenValue = token;
                metadataService.Credentials = new System.Net.NetworkCredential("usuario", "contraseña", "CRM");
                
                RetrieveAllEntitiesRequest allEntitiesRequest = new RetrieveAllEntitiesRequest();
                allEntitiesRequest.RetrieveAsIfPublished = false;
                allEntitiesRequest.MetadataItems = MetadataItems.EntitiesOnly;
    
                DateTime dtinicioall = DateTime.Now;
                RetrieveAllEntitiesResponse allEntitiesResponse = (RetrieveAllEntitiesResponse)metadataService.Execute(allEntitiesRequest);
                TimeSpan dtall = DateTime.Now.Subtract(dtinicioall);
                Console.WriteLine("Tiempo en ejecutar RetrieveAllEntitiesResponse:" dtall.TotalMilliseconds.ToString());
    
                RetrieveEntityRequest entityRequest = new RetrieveEntityRequest();
                entityRequest.RetrieveAsIfPublished = false;
                entityRequest.LogicalName = "contact";
                entityRequest.EntityItems = EntityItems.All;
    
                DateTime dtiniciocontact = DateTime.Now;
                RetrieveEntityResponse entityResponse = (RetrieveEntityResponse)metadataService.Execute(entityRequest);
                TimeSpan dtcontact = DateTime.Now.Subtract(dtiniciocontact);
                Console.WriteLine("Tiempo en ejecutar RetrieveEntityResponse de contact:"   dtcontact.TotalMilliseconds.ToString());
    
    
                DateTime dtinicioaccount = DateTime.Now;
                entityResponse = (RetrieveEntityResponse)metadataService.Execute(entityRequest);
                TimeSpan dtaccount = DateTime.Now.Subtract(dtinicioaccount);
                Console.WriteLine("Tiempo en ejecutar RetrieveEntityResponse de account:"   dtaccount.TotalMilliseconds.ToString());
    
    
                RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest();
                attributeRequest.EntityLogicalName = "contact";
                attributeRequest.LogicalName = "firstname";
                attributeRequest.RetrieveAsIfPublished = false;
    
                DateTime dtiniciofirstname = DateTime.Now;
                RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)metadataService.Execute(attributeRequest);
                TimeSpan dtfirstname = DateTime.Now.Subtract(dtiniciofirstname);
                Console.WriteLine("Tiempo en ejecutar RetrieveAttributeResponse de firstname de contact:"   dtfirstname.TotalMilliseconds.ToString());
    
    
                attributeRequest = new RetrieveAttributeRequest();
                attributeRequest.EntityLogicalName = "account";
                attributeRequest.LogicalName = "name";
                attributeRequest.RetrieveAsIfPublished = false;
    
                DateTime dtinicioname = DateTime.Now;
                attributeResponse = (RetrieveAttributeResponse)metadataService.Execute(attributeRequest);
                TimeSpan dtname = DateTime.Now.Subtract(dtinicioname);
                Console.WriteLine("Tiempo en ejecutar RetrieveAttributeResponse de name de account:"   dtname.TotalMilliseconds.ToString());
    
                Console.ReadLine();
    

    Bien, esto me devuelve como resultado lo siguiente (los tiempos están en milisegundos):


    Lo que se recoge claramente allí es que por ejemplo es mucho mas óptimo el recoger un solo atributo que recoger toda la entidad de "account", pero que pasaría si tenemos que recoger 15 atributos diferentes de "account"?. Allí ya nos convendría recoger la entidad completa...

    Conclusión: es claramente recomendable el ejecutar los mensajes mas "ajustados" a lo que se quiera realizar, pero teniendo en cuenta la escalabilidad de nuestra aplicación, y el funcionamiento que se quiere como resultado.

    Un abrazo,

    jueves, 9 de septiembre de 2010

    La beta del CRM 2011 ya está aquí!

    Pues sí, por fin! ya podemos tocar lo que será el próximo CRM y ver en primera persona todo lo nuevo.
    Se acabaron los foros, comentarios, videos y presentaciones, ahora nos toca a nosotros vivirlo!
    La versión Beta ya está disponible para su descar de http://www.crm2011beta.com/

    Entren a ver que tal, y participen en los foros para enviar posibles cambios, incidencias, etc (tengan en cuenta que es beta,je).

    Por mi parte ya puedo decir que sí:
     "I'm ready for Microsoft Dynamics CRM 2011"



    un saludo

    lunes, 6 de septiembre de 2010

    Como funciona la eliminación de un valor de un Picklist

    En este post intentaré explicar lo que ocurre cuando se elimina un valor de un atributo de tipo "Picklist" (desplegable).
    Es un poco curioso el funcionamiento, incluso un poco incompleto para mi gusto.
    Vamos a ver un ejemplo e iremos revisando como queda la información en el SQL Server.
    Primero vamos a crear un atributo nuevo en la entidad de "Caso" y lo añadimos al formulario. Será un desplegable con el nombre "new_categoria" con los valores "Uno", "Dos", "Tres":
    Atributo picklist

    Creamos un registro de "Caso" con el valor de Categoría en "Dos" y luego hacemos un par de consultas en el SQL Server para ver que nos queda almacenado físicamente en la base de datos y en la FilteredView:

    SELECT * FROM IncidentExtensionBase
    SELECT incidentid,New_Categoria,New_Categorianame FROM FilteredIncident

    Resultados consulta

    Hasta ahora, todo normal, ahora bien, imaginemos que necesitamos eliminar el valor del desplegable "Dos". Al eliminarlo nos aparece el siguiente mensaje:
    "Si algún registro usa el valor que va a eliminar, actualice el registro de modo que use otro valor para poder guardar este cambio. Una vez quitado este valor, no puede usarlo para buscar este registro en la aplicación. ¿Desea continuar?"

    Al leerlo parecería ser que lo que va a hacer será reemplazar los registros con este valor y dejarlo en NULL, pero en realidad no es así.
    Borramos el valor y volvemos a hacer la misma consulta que antes:
    Resultados consulta 2

    Como se ve, en realidad en la base de datos seguimos teniendo el mismo valor, pero lo que ocurre, es que no puede recoger el texto del valor en la FilteredView, cosa que es normal ya que el valor se ha eliminado.

    Imagínense que pasado el tiempo, añadimos un nuevo valor en este desplegable con el mismo valor (2) como índice, pero con otro texto que significa otra cosa:
    Atributo Picklist 2

    Volvemos a hacer la consulta y obtenemos:
    Resultados Consulta 3

    Con esto sacamos como consecuencia, que al eliminar un valor de un desplegable, los registros relacionados con este valor, siguen teniendo el mismo, y no se eliminan, de hecho si hacemos una búsqueda avanzada por ese atributo filtrando por que "Contiene datos", lo encontrará ya que tiene datos, pero es un dato "inexistente". Además hay que tener en cuenta que si creamos nuevos elementos en el desplegable en índices ya existentes, podríamos estar reemplazando y modificando un valor antiguo que ya no nos interesaba.

    La conclusión final y consejo que dejo es que se tenga mucho cuidado con los desplegables y en especial al eliminar los valores, creo que sería una buena práctica no permitir a usuarios finales gestionar este tipo de atributos.

    Un abrazo

    viernes, 3 de septiembre de 2010

    Primera visión interactiva de CRM 2011

    xrmvirtual
    Julie Yack va a hacer una demostración del nuevo CRM 2011 antes de que salga la versión Beta (prevista para este mes).
    La sesión está prevista para el próximo martes 7 de septiembre a las 18:00 hs (hora de España).

    Sin duda es un momento esperado! finalmente se empezará a ver de forma abierta el nuevo CRM!

    Para mas información ver el blog del equipo de CRM:
    http://blogs.msdn.com/b/crm/archive/2010/09/01/your-first-interactive-look-at-crm-2011.aspx

    un saludo

    viernes, 27 de agosto de 2010

    Eliminación de registros en SQL Server

    Normalmente en los proyectos de CRM, hay una parte del mismo que se dedica a realizar cargas iniciales.
    Estas cargas iniciales las vamos realizando primero en servidores de desarrollo para ir probando como van quedando, y luego los eliminamos y para volver a realizar las mismas.
    Para relizar estas eliminaciones masivas, podríamos eliminar los registros directamente en el servidor de SQL Server.
    Obviamente esto esta totalmente no soportado, pero si se hace de forma controlada, puede ayudarnos a ahorrarnos una cuantas horas.
    Por ejemplo, si tenemos una entidad de paises con el nombre "new_pais", la eliminación de todos los registros de esta entidad sería la siguiente:

    DELETE new_paisExtensionBase
    DELETE new_paisBase


    Siempre primero se debe eliminar la "...ExtensionBase" y luego la "...Base".
    Algunas entidades como las actividades ademas necesita que se eliminen mas registros (por ejemplo la tabla ActivityPointer), pero de todos modos, el SQL Server nos irá diciendo que tablas relacionadas se deben eliminar previamente.

    Un saludo

    jueves, 12 de agosto de 2010

    CRM "Twenty-Eleven" video de presentación en WPC 2010

    Después de un pequeño parón de un par de semanas (paternidad incluída) intentaré volver escribir en mi blog.
    He encontrado en el blog de Richard Knudson una entrada comentada con el vídeo de presentación de Microsoft Dynamics CRM 2011 en la conferencia mundial de partners que se celebró en EEUU recientemente.
    El vídeo es el siguiente (ojo, hace falta Silverlight):
    Get Microsoft Silverlight

    Dura una hora, y contiene 2 demos del producto, una relacionada con las nuevas funcionalidades para usuarios (comienza en el minuto 8) y otra demo con nuevas funcionalidades para desarrolladores y personalizadores (comienza en el minuto 29).

    La entrada del blog de Richard Knudson donde comenta todo el contenido del video es:
    http://www.dynamicscrmtrickbag.com/2010/07/25/taking-the-covers-off-crm-2011/

    un saludo

    viernes, 30 de julio de 2010

    Microsoft publica el Rollup 12

    Pues si, ha llegado nuestro cita bimensual con un nuevo Rollup.
    En este caso ya vamos por el 12, y sumando.
    Puede ser descargado de este enlace:
    http://www.microsoft.com/downloads/details.aspx?displaylang=es&FamilyID=a80147f8-130e-492d-93d3-e16e6b2e2fa1
    Así que ya saben, a probarlo todo muy bien y a instalarlo!

    un saludo

    jueves, 29 de julio de 2010

    Listado de Add-ons para el CRM

    Online Directory of Microsoft Dynamics Add-on Products
    El otro día encontré una página web independiente en donde aparecen listados diferentes Add-ons para los productos de Microsoft, incluído por supuesto, el CRM.
    Es muy interesante y útil estar al día de estos diferentes componentes ya que pueden ayudarnos mucho en las implantaciones.
    Les recomiendo darse una vuelta por esta web:
    http://www.microsoftdynamicsaddons.com/
    un saludo!

    lunes, 19 de julio de 2010

    Como personalizar la vista de integrantes de la lista de marketing

    Muchas veces nos ocurre en CRM que necesitamos personalizar alguna vista que no sabemos muy bien donde modificarla.
    Por ejemplo, en el caso de la vista de los integrantes de una Lista de marketing (en el mismo formulario de Lista de marketing) nos podríamos llevar una desilución, ya que si vamos a las personalizaciones, no hay ninguna entidad con el nombre de "Integrantes de la lista".
    Imaginemos que necesitamos añadir en una Lista de marketing de tipo "Contacto" la cuenta relacionada de cada uno de los contactos para uqe quede como lo siguiente:
    Integrantes de la lista de marketing

    Los pasos para hacer esto son:
  • 1) Hacer una búsqueda avanzada de "Vistas" filtrando por las vistas de "Todos los integrantes":
    Búsqueda avanzada de Vistas

  • 2) Abrir la vista y personalizarla como una vista normal.

  • 3) Ir a personalizaciones y publicar todas las personalizaciones.


  • Lo único que no tengo muy claro es como exportar esta personalización sola (imagino que solo se incluye exportando todas las personalizaciones)

    Espero les sirva,

    un saludo

    viernes, 16 de julio de 2010

    Pasar a vivir en la "nube"

    Cloud computing
    Pues si, parece ser que inexorablemente vamos por el camino directo al cielo, o mejor dicho a la "nube".
    El desarrollo y mejora de las comunicaciones está llevando a que se cambie la mentalidad en relación con las soluciones que las empresas de software ofrecen sus soluciones.
    La actual tendencia es ofrecer soluciones en la "nube", es decir en internet, y por lo tanto con un coste de implantación y mantenimiento muchísimo menor para los usuarios. En la actualidad se puede observar como las soluciones de software se ven mas como "servicios" que como cajitas que se venden e instalan.
    El software como servicio (SAS) no es algo nuevo, pero ahora parece que está en un momento de expansión o "explosión". Todo se quiere convertir a esta modalidad, y poco a poco se irá haciendo.
    Microsoft también va por esta línes y lo ha confirmado en la conferencia mundial de partners en Washington - WPC 2010 - (http://www.microsoft.com/presspass/press/2010/jul10/07-12cloudcomputingpr.mspx).
    Actualmente ya existen varias soluciones que Microsoft ofrece en la "nube":
  • Windows Azure

  • Microsoft SQL Azure

  • Exchage

  • Sharepoint

  • Office Live Meeting

  • Microsoft Office Communications Online

  • Microsoft Dynamics CRM Online


  • Imagino que este movimiento a la "nube" crecerá, solo habrá que prepararse para "volar".

    Para mas información: http://www.microsoft.com/cloud/

    un saludo

    jueves, 15 de julio de 2010

    Como borrar el valor de un atributo en un Workflow

    Muchas veces me han preguntado si existe la posibilidad de borrar el valor de un atributo desde un Workflow.
    Esto nos puede servir por ejemplo para hacer validaciones, o en caso de tener 3 campos y queremos que se rellene uno en primer lugar, en caso de rellenar otro, podríamos copiarlo en donde lo deseamos y borrarlo después.
    La forma de borrar un campo en un Workflow es muy sencilla, pero aparece en el CRM un poco "escondido".
    En una acción de "Actualizar registro" debemos seleccionar el atributo y seleccionar el operador "Borrar" como en lo siguiente:
    Workflow: como borrar un campo

    Espero les sirva!

    un saludo

    martes, 13 de julio de 2010

    Microsoft Dynamics CRM 2011 beta!

    Hola a todos, finalmente el nombre del nuevo CRM será "Microsoft Dynamics CRM 2011".
    Se ha anunciado en la Conferencia mundial de partners que la versión beta de la nueva versión estará disponible en septiembre!
    Ya queda cada vez menos, y podremos ver como va quedando el nuevo CRM y las nuevas funcionalidades.
    Recomiendo dar una vuelta por la siguiente página web y registrarse para estar actualizado de las novedades: https://offers.crmchoice.com/betaofferlanding/
    Algunas imágenes que aparecen allí de lo que será en nuevo CRM 2011:
    Dynamics CRM 2011
    Dynamics CRM 2011
    Dynamics CRM 2011

    miércoles, 7 de julio de 2010

    Como saber quién tiene instalado el Cliente de Outlook

    Microsoft Outlook 2010
    A veces necesitamos saber exactamente que usuarios tienen instalado o utilizan el cliente de Outlook para CRM.
    Existe una consulta en la base de datos, que puede devolvernos esta información y además decirnos en que ordenador está instalado.
    La consulta es la siguiente:

    SELECT Subscription.MachineName, SystemUserBase.FullName
    FROM Subscription
    INNER JOIN SystemUserBase
    ON Subscription.SystemUserId = SystemUserBase.SystemUserId


    Un saludo!

    martes, 6 de julio de 2010

    Escalabilidad con xRM

    Microsoft Dynamics CRM
    La semana pasada Microsoft publicó un artículo relacionado con la escalabilidad del CRM y pruebas y consejos de como mejorar el rendimiento de una implantación de CRM (o xRM).
    El artículo puede descargarse de aquí:
    http://blogs.msdn.com/b/crm/archive/2010/06/30/microsoft-dynamics-crm-4-0-xrm-application-scalability-study.aspx
    En el blog del equipo de CRM, aparece una descripción del mismo:
    http://blogs.msdn.com/b/crm/archive/2010/06/30/microsoft-dynamics-crm-4-0-xrm-application-scalability-study.aspx

    Considero que es muy importante estar al día e informado de este tipo de documentos que publica Microsoft, porque también nos da algunas pistas de por donde "tirar" cuando tenemos algunas dudas en una implantación.

    El estudio muestra el rendimiento de los servidores, con 3 escenarios diferentes:
  • 1 aplicación para 20.000 usuarios

  • 4 aplicaciones para 5.000 usuarios cada una

  • 20 aplicaciones para 1.000 usuarios cada una


  • No soy experto en sistemas, pero está claro que el primer "cuello de botella" aparece en los servidores de aplicación, donde está el sitio web con sus web services. Multiplicando estos, se consigue una gran mejora de rendimiento.

    Un saludo

    miércoles, 30 de junio de 2010

    Estados de los Emails

    Al crear actividades de tipo Email, las mismas van cambiando de estados. en este artículo intentaré explicar un poco de como es este cambio de estados.
    El flujo sería mas o menos el siguiente:
    Flujo de estados de emails

    Pongamos por ejemplo que planificamos un envío de un Email, simplemente lo creamos.
    En este momento los valores serían:
    StateCode=0 (Abierto)
    StatusCode=1 (Borrador)

    Ahora bien, supongamos que le damos el botón de "Enviar". Al hacer eso, el CRM simplemente marcará el correo electrónico para reaizar el envío. Los estados ahora serían:
    StateCode=1 (Completado)
    StatusCode=6 (Envío pendiente)

    Luego lo que ocurre es que el servicio asíncrono de CRM (CRMAsyncService) ejecutará el evento "BackgroundSendEmail" que lo que hace es buscar todos los emails en "Envío pendiente" (statuscode=6) para marcarlos para que el Email Router haga efectivo el envío. Despues de ejecutar este evento los estados serían:
    StateCode=1 (Completado)
    StatusCode=7 (Enviando)

    Lo que ocurre ahora es que el Email Router busca todos esos correos electrónico en estado "Enviando" para intentar entregar los mismos al servidor que tenga configurado. En caso de fallar, volverá al estado "Envío pendiente" para intentarlo enviar de nuevo. En caso de ir correctamente el estado quedaría así:
    StateCode=1 (Completado)
    StatusCode=3 (Enviado)

    Espero les sirva, cuando le damos al "Enviar" desde el CRM ocurren muchas cosas por detrás...

    abrazo.

    miércoles, 23 de junio de 2010

    Correos electrónicos enviados varias veces por el Email router

    Existe algunos casos en los cuales el Email Router envia un correo electrónico mas de una vez, y en este post intentaré dar respuesta a la pregunta de por qué este servicio del CRM realiza esta operación de forma tan "inesperada".
    Imaginense que creo un correo electrónico normal de CRM como el siguiente:
    Correo electrónico

    En donde "Prueba 1" y "Prueba 2" son contactos de la empresa y por lo tanto tienen correos electrónicos de dentro del dominio, pero uno de los dos contactos tiene el correo incorrectamente en el CRM (por un error al crear el mismo).

    Al enviar este E-mail, el Email Router intentará entregar este correo electrónico al Exchange, pero este devolverá un error de "User unknown" ya que una de las direcciones del dominio no existe. Esto en realidad no significa que el correo electrónico no haya salido, sino simplemente que no se ha podido entregar a uno de los destinatarios, pero al resto de destinatarios sí que le llegará correctamente.

    Este error devuelto por el Exchange provoca que el E-mail en CRM quede marcado como con error, por lo que intentará realizar el envio de nuevo.

    Es por esto que a los destinatarios de este correo electrónico les podrá llegar este E-mail mas veces.

    Para solucionar esto, se debe introducir correctamente la dirección de correo electrónico o revisar los parámetros del Email Router en relación con las repeticiones ante errores.

    Para la configuración del Email Router, recomiendo la SDK en el artículo "Outbound Provider Configuration Settings":
    http://msdn.microsoft.com/en-us/library/cc906239.aspx

    Un saludo!

    lunes, 21 de junio de 2010

    Consultado los Workflows desde SQL Server

    Los flujos de trabajo se ejecutan con el servicio asíncrono de CRM (AsyncService) y van dejando en el SQL Server registro del estado de los mismos, los pasos y el seguimiento de los mismos.
    Como todos sabemos, no esta soportado el acceso a ciertas tablas del SQL Server directamente, pero el CRM nos ofrece unas "FilteredViews" para poder consultar los Workflows para hacer un seguimiento de la ejecución de los mismos.
    Las vistas se llaman "FilteredAsyncOperation" y "FilteredWorkflowLog"
    La consulta para recoger todas las ejecuciones de workflows es la siguiente:

    select asyncoperationid, name,statecodename,statuscodename, createdon
    from FilteredAsyncOperation
    WHERE messagename='ExecuteWorkflow'
    order by createdon desc

    y para recoger el estado de cada uno de los "Steps" (pasos) del workflow:

    select stepname,activityname,description, completedon,statusname
    from FilteredWorkflowLog
    where asyncoperationid='8C6D813F-0C73-DF11-955A-000C299E8D82' --(aqui poner un "id" recogido de la consulta anterior)

    De esta forma por ejemplo lo que podemos hacer es un monitor de ejecución de flujos de trabajo, de forma muy sencilla con una aplicación de escritorio o web que se vaya actualizando automáticamente.


    un saludo

    sábado, 5 de junio de 2010

    Microsoft publica el Rollup 11

    Como cada 2 meses, Microsoft ha publicado un nuevo Update Rollup 11.
    Puede ser descargado de aquí: http://www.microsoft.com/downloads/details.aspx?displaylang=es&FamilyID=f84f2bfb-393d-4b90-bf1b-300a82ec6083
    Para mas información mirar la descripción de los cambios aquí:
    http://support.microsoft.com/default.aspx?kbid=981328
    y en el blog del equipo de CRM:
    http://blogs.msdn.com/b/crm/archive/2010/06/04/update-rollup-11-for-microsoft-dynamics-crm-4-0.aspx

    Como siempre: mucho cuidado y probar bien la instalación de esto antes de instalar en producción.

    Un saludo

    viernes, 4 de junio de 2010

    Cuidado con los "Otros"


    Se ha publicado un artículo en el blog del equipo de CRM con unos consejos realizados por el MVP Joel Lindstrom, que creo que son interesantes, ya que surgen de la experiencia de diversas implementaciones en muchos clientes.
    El artículo es el siguiente:
    Lost: Beware of the "Others"
    Si bien el título es gracioso y nos hace referencia a la serie finalizada recientemente (tristemente), los consejos son muy útiles.
    Habla de los típicos campos de tipo picklist para categorizar Cuentas o Contactos, en donde después de una seria de valores, se añade el "peligroso" valor de "Otros" para definir el registro.
    El tema es que como a los usuarios les suele ser mas "fácil" poner "Otros" que seleccionar el valor que debería ser, o porque la categorización no recoge el valor que se necesite(no siempre es culpa del usuario), resulta que puede ocurrir que la gran mayoría de los registros terminen teniendo el valor "Otros".
    Esto puede provocar que se dificulte mucho la explotación de esta información, y para evitar esto da algunos consejos:

  • Dentro de lo posible, no incluir el valor "Otros" en los picklists.

  • En su lugar, diseñar un proceso sencillo para que los usuarios puedan solicitar nuevos valores para el picklist.

  • En caso de ser muy necesario el valor "Otros", tener el mismo muy controlado, para que no ocurra lo descrito.

  • En caso de que la categorización pueda ser muy cambiante, analizar la posibilidad de poner un "Lookup" en lugar de un "Picklist", y que sean los mismos usuarios los que puedan gestionar la categorización. (esta recomendación es añadida)


  • un abrazo

    miércoles, 2 de junio de 2010

    Haciendo consultas con LINQ usando Microsoft Xrm

    Siguiendo con el artículo Usando la nueva SDK 4.0.12 (Microsoft xRM) voy a mostrar como seguir aprovechando las nuevas posibilidades que nos permite la nueva SDK (4.0.12).
    En este artículo mostraré un par de ejemplos de como poder hacer consultas en LINQ al CRM.
    En el siguiente cósigo muestro como se podrían hacer consultas en LINQ, para recoger datos de contactos en CRM, filtrando por el email:

    var crm = new Xrm.XrmDataContext("Crm");

    var namedContacts =
    from contact in crm.contacts
    where contact.emailaddress1 == "[email protected]"
    select contact;
    foreach (var c in namedContacts)
    {
    System.Console.WriteLine(c.fullname);
    }

    var contacts4 =
    from contact in crm.GetEntities("contact")
    where contact.GetPropertyValue("emailaddress1") == "[email protected]"
    select contact.GetPropertyValue("fullname");

    foreach (var c in contacts4)
    {
    Console.Write("{0}, ", c);
    }


    Como se ve, hay 2 formas de hacer las consultas, la primera es con los objetos creados por crmsvcutil.exe, y la segunda manera es realizandolo con "Dynamics Entities".

    lunes, 24 de mayo de 2010

    Usando la nueva SDK 4.0.12 (Microsoft xRM)

    En la nueva versión de la SDK, se recogen una serie de herramientas y ejemplos de código, muy útiles para el trabajo con CRM.
    Esto se recoge en el capítulo Advanced Developer Extensions for Microsoft Dynamics CRM 4.0 (Microsoft xRM).
    En este post, intentaré dar una especie de "ayuda" de como empezar a utilizar estas utilidades para sacar provecho de las mismas.
    Haré un pequeño ejemplo paso a paso de como crear un nuevo proyecto, y utilizar el código de xRM para crear un Contacto.

    Paso 1: copiar la herramienta "crmsvcutil.exe" que contiene la SDK en la carpeta "SDK\microsoft.xrm\tools" en el servidor de CRM.

    Paso 2: Ejecutar en una línea de comandos lo siguiente:
    crmsvcutil /server:"http://localhost/DEMO" /namespace:Xrm /dataContextPrefix:Xrm /out:Xrm.cs

    Esto genera un fichero "Xrm.cs" con todas la estructura necesaria para trabajar con "xRM".

    Paso 3: Crear un nuevo proyecto de tipo "Aplicación de consola".

    Paso 4: Añadir las siguientes referencias al proyecto:
  • Microsoft.Crm.Sdk.dll y Microsoft.Crm.SdkTypeProxy.dll (SDK\Bin)
  • Microsoft.Xrm.Client Microsoft.Xrm.Portal Microsoft.Xrm.Portal.Files (SDK\Microsoft.Xrm\Bin)
  • System.Data.Services System.Data.Services.Client (.NET)

    Paso 5: Añadir la clase "Xrm.cs" generada previamente con la herramienta "crmsvcutil.exe"

    Paso 6: Añadir un nuevo fichero de Configuración de la aplicación (app.config) con el siguiente Xml (reemplazar las credenciales del usuario):








    El proyecto quedaría así:


    Paso 7: añadir el código para la creación del Contacto:

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

    namespace TestXrm
    {
    class Program
    {
    static void Main(string[] args)
    {
    CrearContacto();
    }
    static void CrearContacto()
    {
    var crm = new Xrm.XrmDataContext("Crm");

    var contact = crm.CreateEntity("contact");

    contact.SetPropertyValue("firstname", "Demian Adolfo");
    contact.SetPropertyValue("lastname", "Raschkovan");
    contact.SetPropertyValue("emailaddress1", "[email protected]");

    var id = Guid.NewGuid();
    contact.SetPropertyValue("contactid", id);

    crm.AddObject("contact", contact);
    crm.SaveChanges();

    var id2 = contact.GetPropertyValue("contactid");

    }

    }
    }


    Espero les sirva!

    un abrazo
  •