domingo, 12 de diciembre de 2010

Aumentar el número de registros por página

Por defecto Dync CRM permite visualizar un máximo de 250 registros por página en cada vista, para poder aumentar dicha cantidad ejecutar la siguiente sentencia sql:
update UserSettingsBase set PagingLimit=500

Aumentar el número de registros para exportación a excel

Por defecto en Dync CRM 4 se puede exportar a excel como máximo 10000 registros. Para aumentar dicha cantidad se deberá ejecutar la siguiente sentencia SQL en la BD Organizacional:
update OrganizationBase set maxrecordsforexporttoexcel=65535
Nota: el número 65535 sólo es referencial
Luego, en el servidor de CRM deberemos realizar iisreset para aplicar los cambios realizados.

sábado, 11 de diciembre de 2010

Reordenar NavBar de entidad

Es conocido que para ordenar ítems del navBar existe una opción llamada “Orden de visualización”

No obstante, esta opción sólo está habilitada para las relaciones personalizadas y no para las que son OOTB o para los ítems que creamos por el ISV.

Para estos casos se puede hacer uso de un JScript en el OnLoad y utilizar la función "insertBefore". Este script requiere de los ID de los ítems del NavBar de la entidad (este ID lo podremos obtener utilizando herramientas como IEDevTollbar o simplemente buscando en el código fuente del formulario). En este ejemplo trabajaremos con los ítems Actividades e Historial de la entidad Contactos. En el OnLoad copiar lo siguiente:
var _ActivitiesNavItem = document.getElementById("navActivities").parentNode;
var _ActHistoryNavItem = document.getElementById("navActivityHistory").parentNode;
_ActHistoryNavItem.insertBefore(_ActivitiesNavItem);
Y Esto sería el antes y el después.

CrmForm Jscript con intellisense generator

En ciertas ocasiones hemos deseado o necesitado un editor que cuente con intellisense para desarrollar nuestros JS. Aquí les muestro de un tool que les servirá de mucha ayuda, MS CRM Javascript Intellisense Generator que lo puedes descargar de aquí.

Una vez descargado y ejecutado, nos parecerá una pantalla de conexión.

Una vez conectado, en la parte inferior nos mostrará el nombre de la organización y al lado derecho se mostrará el listado de entidades. (Si seleccionamos una serie de características asociadas a la entidad).
Hacemos clic en el botón “Save” para generar una carpeta con el contenido de características de todas las entidades existentes.

Colocamos la carpeta generada dentro de una solución de Visual Studio y procederemos a abrir el archivo relacionado a la entidad en la cual queramos generas nuestro JScript.

En la parte inferior del archivo abierto ya podremos comenzar a desarrollar nuestros JS con intellisense.

 

viernes, 10 de diciembre de 2010

Obtener sentencia SQL desde Vista o Búsqueda Avanzada

Muchas veces (especialmente cuando empezamos con Dync CRM) y nos solicitan hacer reportes desde Visual Studio, desconocemos el nombre de las tablas, de los atributos, o simplemente no tenemos experiencia haciendo consultas a BD. En un post anterior mostré como obtener el FetchXML de vistas y búsquedas avanzadas, ahora les mostraré la manera de obtener la sentencia SQL.

Primero haremos una búsqueda avanzada (o seleccionaremos una vista) y la exportaremos a Excel seleccionando la opción “Hoja de cálculo dinámica” (Dynamic worksheet).
Cuando tengamos el Excel abierto con el resultado de la exportación, procederemos a seleccionar la opción “Datos” del ribbon y luego seleccionaremos la opción “Conexiones”.

Luego se abrirá una ventana en la cual haremos clic en el botón “Propiedades…”,
En la siguiente ventana, seleccionaremos la pestaña “Definición”, donde en la sección “Texto del comando” se muestra la sentencia SQL

domingo, 19 de septiembre de 2010

Limitar el número de registros asociados a una entidad

Partamos del siguiente ejemplo:
Se tiene la entidad personalizada jlc_documento la cual está asociada a las entidades contact y account. Siendo contact y account las entidades que tengan la vista asociada y jlc_documento los lookups. (El lookup creado de la relación contact-jlc_documento es jlc_documentocontactid y el lookup creado de la relación account-jlc_documento es jlc_documentoaccountid)
Se desea poder registrar como máximo 10 jlc_documentos por cada registro de contact y account.
La solución a este problema podría ser la siguiente:

var clienteId;
var nroRegistros;
var authenticationHeader;
var xml;
if (crmForm.FormType == 1) {
    if (crmForm.all.jlc_documentoaccountid.DataValue[0].id != null || crmForm.all.jlc_documentocontactid.DataValue[0].id != null) {
        if (crmForm.all.jlc_documentoaccountid.DataValue[0].id != null) {
            clienteId = crmForm.all.jlc_documentoaccountid.DataValue[0].id;
        }
        else {
            clienteId = crmForm.all.jlc_documentocontactid.DataValue[0].id;
        }

        authenticationHeader = GenerateAuthenticationHeader();
        //Prepare the SOAP message.
        xml = "<?xml version='1.0' encoding='utf-8'?>" +
        "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +
        " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
        " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
        authenticationHeader +
        "<soap:Body>" +
        "<Fetch xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
        "<fetchXml>&lt;fetch mapping='logical'&gt;" +
        "&lt;entity name='jlc_documento'&gt;" +
        "&lt;filter type='or'&gt;" +
        "&lt;condition attribute='jlc_documentoaccountid' operator='eq' value='" + clienteId + "'/&gt;" +
        "&lt;condition attribute='jlc_documentocontactid' operator='eq' value='" + clienteId + "'/&gt;" +
        "&lt;/filter&gt;" +
        "&lt;/entity&gt;" +
        "&lt;/fetch&gt;</fetchXml>" +
        "</Fetch>" +
        "</soap:Body>" +
        "</soap:Envelope>";

        //Prepare the xmlHttpObject and send the request.
        var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
        xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
        xHReq.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Fetch");
        xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        xHReq.setRequestHeader("Content-Length", xml.length);
        xHReq.send(xml);
        //Capture the result
        var resultXml = xHReq.responseXML;
        //Check for errors.
        var errorCount = resultXml.selectNodes('//error').length;
        if (errorCount != 0) {
            var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
            alert(msg);
        }
        //Process and display the results.
        else {

            //Capture the result and UnEncode it.
            var resultSet = new String();
            resultSet = resultXml.text;
            resultSet.replace('&lt;', '<');
            resultSet.replace('&gt;', '>');

            // Create an XML document that you can parse.
            var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            oXmlDoc.async = false;
            // Load the XML document that has the UnEncoded results.
            oXmlDoc.loadXML(resultSet);
            //Display the results.
            var results = oXmlDoc.getElementsByTagName('result');
            nroRegistros = results.length;
            if (nroRegistros == 10) {
                alert("Se han registrado el número máximo de asociaciones");
                window.close();
            }
        }
    }
}


miércoles, 8 de septiembre de 2010

Ejecutar OnChange sin perder el foco

El evento OnChange de los campos de un formulario de Dync CRM tienen una peculariedad ... el evento se ejecuta cuando se pierde el foco. Este detalle podría crearnos ciertas dificultades para lo cual tendríamos que forzar a que dicho evento se ejecute inmediatamente después de cambiar su valor y no después que se haya perdido el foco del campo. Veamos el siguiente ejemplo:
ESCENARIO
Se tiene el campo checkbox "valor" y un campo de caja de texto "descripcion". El campo "descripcion" deberá estar deshabilitado a menos que se haya seleccionado el campo "valor".

SOLUCION FALLIDA
En el evento OnChange de "valor" colocar:
if(crmForm.all.valor.DataValue==true)
   crmForm.all.descripcion.Disabled=false;
La opción arriba mencionda funciona sí y sólo sí luego de haber colocado un check en el campo "valor" se da un clic en cualquier otra parte del formulario o si se presiona la tecla TAB.

Para lograr nuestro cometido emplearemos "attachEvent" y que se ejecute en el momento que se haga check en "valor"
SOLUCION CORRECTA
En el evento OnLoad del formulario colocaremos lo siguiente 
function MiFuncion(){
   if(crmForm.all.valor.DataValue==true)
      crmForm.all.descripcion.Disabled=false;
}
crmForm.all.valor.attachEvent('onclick',MiFuncion);

viernes, 13 de agosto de 2010

crmForm.que?

Este post está orientado a personas que recién están empezando a realizar códigos de javascripts para los formularios y campos de CRM. Al menos cuando yo empecé en este mundo lo primero que me mandaron hacer fue justamente esto y en muchas ocasiones ignoraba de las propiedades y métodos que permitirían realizar rápidamente mi trabajo... en fin. Para que no les pase como a mí, les voy a dejar un listado de propiedades y métodos:
Variables Globales
SERVER_URL Nos proporciona una cadenta de texto con el nombre del servidor
USER_LANGUAGE_CODE Proporciona el codigo del lenguaje seleccionado por el usuario
ORG_LANGUAGE_CODE Proporciona el codigo del paquete de lenguaje dela organización
ORG_UNIQUE_NAME Proporciona el nombre de la organización

Propiedades crmForm
crmForm.all Nos permite acceder a todos los campos del formulario
crmForm.IsDirty Retorna un booleando. True si el campo ha sido modificado
crmForm.FormType Obtiene un entero según el modo en el que se encuentre el formulario. Como valores
válidos tenemos:

-Undefined Form Type = 0

-Create Form = 1

-Update Form = 2

-Read Only Form = 3

-Disabled Form = 4

-Quick Create Form = 5

-Bulk Edit Form = 6
crmForm.ObjectId Retorna un string que muestra el GUID del registro abierto. En caso que el
formulario sea de tipo"Create Form" el vaslor será null.
crmForm.ObjectTypeCode Obtiene el código de la entidad del formulario abierto.
crmForm.ObjectTypeName Obtiene el nombre de la entidad del formulario abierto.

Lookup Multientity - (como el de cliente)

En ocasiones hemos necesitado de un lookup el cual nos permita manejar tanto Cuentas como Contactos (similar al que hay en el formulario de Casos) o lookups como los "Referente a". Si bien es cierto que es una funcionalidad propia de CRM, en este ejempplo (que tiene como base este post) vamos a emular un lookup multi-entidad el cual nos permita hacer el registro de un contacto o cuenta.
Supongamos que tienen una entidad personalizada llamaba: jl_entidad. Deberán crear relaciones con la entidad account y contact donde éstas son las entidades principales. Agregar los campos de tipo lookup jl_accountid y jl_contactid en el formulario de jl_entidad.
Ahora en el evento OnLoad, copiar el siguiente código:
var accountLookup = crmForm.all.jl_accountid;
var contactLookup = crmForm.all.jl_contactid;
accountLookup.lookuptypes = "1,2";
accountLookup.lookuptypenames = "account:1,contact:2";
accountLookup.lookuptypeIcons = "/_imgs/ico_16_1.gif:/_imgs/ico_16_2.gif";
if (contactLookup.DataValue != null) {
   accountLookup.DefaultValue = contactLookup.DataValue;
   accountLookup.DataValue = contactLookup.DataValue;
   if (typeof (accountLookup.DataValue[0].data) != "undefined") {
      accountLookup.DefaultValue[0].data = accountLookup.DataValue[0].data;
   }
}
En el evento OnSave copiar lo siguiente:
var accountLookup = crmForm.all.jl_accountid;
var contactLookup = crmForm.all.jl_contactid;
if (accountLookup.DataValue == null) {
   contactLookup.DataValue = null;
}
else {
   var customer = accountLookup.DataValue[0];
   if (customer.type == "1") {
      contactLookup.DataValue = null;
   }
   else {
      contactLookup.DataValue = accountLookup.DataValue;
      accountLookup.DataValue = null;
   }
}

miércoles, 11 de agosto de 2010

Personalizando FULLNAME

Como ya sabemos podemos personalizar el FULLNAME mediante la Configuración del sistema, pero este medio es un poco limitante ya solo nos da la oportunidad de elegir uno de los siguientes formatos:
  • Apellidos, Nombre
  • Nombre Apellidos
  • Apellidos, Nombres Iniciales
  • Nombres Iniciales Apellidos
  • Apellidos, Nombre Segundo nombre
  • Nombre Segundo nombre Apellidos
  • Apellidos Nombre
  • ApellidosNombre
Pero qué pasaría si tenemos el apellido paterno y el apellido materno por separado y queremos que éste forme parte del FULLNAME
Para ello crearemos 2 nuevos campos: jc_apellidopaterno y jc_apellidomaterno.
No utilizamos el atributo lastname ya que lo emplearemos para la concatenación de los atributos que creamos. Por último implementaremos la siguiente porción de JScript:
En el evento OnLoad
//Ocultar el campo lastname que viene por defecto
crmForm.all.lastname.style.visibility='hidden';
crmForm.all.lastname_c.style.visibility='hidden';
En el evento OnSave:
//Concatenación de campos
crmForm.all.lastname.DataValue=crmForm.all.jc_apellidopaterno.DataValue+' '
+ crmForm.all.jc_apellidomaterno.DataValue;
Con esto el campo FULLNAME mostrará el nombre, el apellido paterno y el apellido materno.

No se puede validar la instalación de servidor de informes SQL Server Reporting Services

Tal vez cuando has intentado instalar el CRM Data Connector en un servidor que cuenta con SQL Server 2008 RS te has encontrado con este inconveniente.

Según información oficial este problema se soluciona con las actualizaciones más recientes que se descargan de internet durante la instalación, pero que pasa cuando nuestro servidor de reportes (por motivos de seguridad) no cuenta con salida a la red de redes. Bajo estas circunstancias se vuelve un poco tedioso poder realizar la instalación pero no se vuelve imposible.

Para poder conseguir nuestro objetivo deberemos realiar los siguientes pasos:

1. Copiar la carpeta SRSDataConnector, que viene en el CD de instalación, en una de las particiones del servidor (esto para una mayor facilidad de trabajo). Ejemplo: E:\SrsDataConnector
2. Dentro de la nueva carpeta creada (E:\SrsDataConnector) copiaremos la carpeta VCRedist que también se encuentra en el CD de instalación (Redist\amd64\ VCRedist ó Redist\i386\ VCRedist).
3. Abrir un comand prompt y ejecutar la siguiente instrucción:
Path:>msiexec /i E:\SrsDataConnector\SrsDataConnector.msi PATCH=E:\SrsDataConnector\SrsDataConnector_amd64.msp

4. Aquí se mostrará una ventana de progreso de instalación.
5. Abrir el archivo install-config.xml que se encuentra en E:\SrsDataConnector. La modificación consistirá en agregar la siguiente etiqueta:
<Patch update="true">E:\SrsDataConnector\SrsDataConnector_amd64.msp</Patch>
6. Luego volveremos a abrir un comand promt y ubicarnos en la ruta elegida donde se encuentra el SrsDataConnector(E:\SrsDataConnector). Todo esto se hará vía de comandos
7. Una vez ubicado en E:\SrsDataConnector> ejecutaremos:
SetupSrsDataConnector.exe /config install-config.xml
8. Finalmente se ejecutará el Wizard de instalación y seguiremos hasta culminar la instalación.

Éstos pasos nos permitirán poder instalar satisfactoriamente el Conector de reportes.

Inventario de jscripts crmForm

A quien no le ha pasado que como parte de los entregables de los diferentes proyectos con Dync CRM nos han solicitado realizar un inventario de los scripts desarrollados para los diferentes formularios y atributos de las diferentes entidades :S Bueno esto puede volverse una tarea muy engorrosa (especialmente si uno no ha desarrollado dichos scripts). Felizmente contamos con herramientas que nos pueden facilitar la vida. En esta oportunidad les comento sobre una herramienta que nos va a servir de mucho: FormJavascriptManager que lo puedes descargar haciendo click aquí.
Para utilizar esta herramienta deberemos crear una conexión al servidor de CRM de la siguiente manera:

(Primero hacer click en el botón [...] y luego en [new connection])

En la siguiente ventana le pondremos un nombre a la conexión, escogeremos el tipo de autenticación e ingresaremos información correspondiente al servidor de CRM

Finalmente aparecerá una ventana donde podremos apreciar las entidades personlizables de donde podremos seleccionar aquellas que querramos analizar. Por cada entidad que selecciones nos permitirá visualizar los métodos OnChange, OnSave y OnLoad de los atributos y formularios respectivamente.

domingo, 16 de mayo de 2010

"Reporting Error. The report cannot be displayed"

Microsoft.ReportingServices.ReportProcessing.ReportProcessingException: Cannot create a connection to data source 'CRM'. --->

Es posible que te encuentres con este error luego de una actualización de Base de Datos o de una reasignación de usuarios a los servicios del SQL Server.

Este error se debe ya que la cuenta que el CRM Data Connector usa para la autenticación no tiene los privilegios necesarios sobre las BDs de Dync CRM (es muy probable que la cuenta con la que se ejecuta los servicios NO sea NT AUTHORITY\NETWORK SERVICE). Para solucionar este problema debemos hacer las siguientes configuraciones:

1. En el servidor de RS identificar la cuenta que ejecuta el SQL Server Reporting Services Windows service (esto se identificará desde la pantalla de servicios)
2. Verificar que el usuario identificado en el paso 1 sea miembro de SQLAccessGroup creado con la instalación de DynC CRM. En caso contrario se deberá agregarlo.
3. Abrir el SQL SERVER MANAGEMENT STUDIO.
4. Expandir "Security", luego "Logins", y luego hacer clic derecho en "SQLAccessGroup" y luego hacer clic en "Properties"
5. En la siguiente ventana hacer clic en "[organizacion]_MSCRM" y habilitar las casillas de selección "CRMReaderRole", "public" y "db_owner" ([organizacion]_MSCRM representa la BD Organizacional)
7 Hacer check en la casilla de selección "MSCRM_CONFIG" y habilitar las casillas de selección "CRMReaderRole", "public" y "db_owner" Hacer clic en "Ok"
8. Repetir los pasos 5,6,7 para el usuario identificado en el paso 1.

sábado, 13 de marzo de 2010

Virtualización de 64 bits

Es conocido por muchos q las versiones de Dync CRM "5" y MOSS 2010 han sido liberadas en versiones de 64 bits. Esto ha sido la preocupación de muchos consultores ya que piensan que no podrán generar máquinas virtuales y mostarlas sobre su MS Virtual PC o su Windows Virtual PC. Bueno les comento que encontré una solución ante ello y que me ha servido para montar una imagen con CRM 5, pero esta solución no involucra un producto MS sino una herramienta de SW libre como es Virtual Box.
Antes que nada e ilusionarnos instalando el Virtual Box debemos saber si nuestro equipo soporta una virtualización de este tipo ya que no basta con tener el software sino también el hardware idóneo. Para salir de esta duda podemos descargar Intel Processor Identification Utility o el AMD-V Technology and Microsoft Hyper-V Compatibility Check el cual nos señale si contamos con tecnología de virtualización. En el caso que contemos con estas características deberemos hacer una configuración en la BIOS, esto con el fin de habilitar la función de "Virtualization Technology" que por defecto aparece con un valor de "Disabled". Esta configuración dependerá del equipo con el que contemos. Si quieres ver la correcta configuración de tu equipo haz clic aquí
Una vez realizada estas configuraciones procederemos a descargar la última versión de Virtual Box y a generar nuestra máquina virtual de 64 bits.

sábado, 6 de marzo de 2010

Publicación masiva de reportes - PublishReports

Por disitintos motivos es necesario realizar una publicación masiva de los reportes, esto puede ser debido a que se ha perdido la configuración en el servidor o que se haya formateado(o cualquier otro caso extremo que les haya pasado con el servidor de reportes).
Para ello haremos uso de una herramienta llamada PublishReports.exe
Esta herramienta se encuentra en la carpeta donde se instala dynamics crm que por defecto es: C:\Program Files\Microsoft CRM\Tools\PublishReports.exe
Ahora la pregunta es.... ¿cómo se usa?... bueno la respuesta es:
Abrimos el comand prompt y unos ubicamos en la carpeta Tools:
Drive:\Program Files\Microsoft CRM\Tools>
Luego escribimos: PublishReports [MiOrganizacion]y hacemos enter (no usar los símbolos "[" ni "]" que se encierran el nombre de la organización).
Finalmente quedaría algo así:
Drive:\Program Files\Microsoft CRM\Tools>PublishReports MiOrganizacion

Fetch de búsqueda avanzada

Muchas personas, especialmente aquellas que están aprendiendo a generar fetch, han estado interesadas en saber el fetch que genera una búsqueda avanzada en dync. Para averiguar esto no hay mucho que investigar. Lo único que se debe hacer es construir una Búsqueda Avanzada, luego presionar la tecla F11, en la barra de direcciones escribir: javascript:alert(resultRender.FetchXml.value);
Luego de ello hacer unos cuantos enter y aparecerá una ventana mostrando el fetch construido.

sábado, 27 de febrero de 2010

Integrando Google Maps con CRM 4.0

Muchas veces las empresas que cuentan con CRM 4.0 necesitan visualizar las locaciones de sus clientes para brindar sus servicios de una manera más rápida y eficiente por lo que necesitan de un mapa de referencia dentro de las fichas.
En esta oportunidad mostraremos como conseguir este objetivo. Adicionalmente a esto, crearemos un botón el cual me permita mostrar y ocultar el mapa ya que este ocupa un tamaño considerable.
Primero deberemos crear un IFrame, al cual llamaremos Mapa, dentro de la entidad Account (también puede ser dentro de la entidad contact).




Ahora que ya tenemos la lógica, deberemos crear el botón en el formulario de la entidad account y ahí colocaremos el extracto de Jscript, para esto deberemos modificar el sitemap de la siguiente manera:

<Entity name="account">
<ToolBar ValidForCreate="0" ValidForUpdate="1">
<Button Icon="/_imgs/ico_16_4414.gif" JavaScript="var displ=crmForm.all.IFRAME_Mapa.style.display; if(displ=='none') crmForm.all.IFRAME_Mapa.style.display=''; else crmForm.all.IFRAME_Mapa.style.display='none';" PassParams="1" WinParams="" WinMode="0">
<Titles>
<Title LCID="1033" Text="Mapa" />
</Titles>
</Button>
<ToolBarSpacer />
</ToolBar>
</Entity>
Luego importamos el ISV modificado y verificamos los resultados.
Debemos quitar el check para no Restringir scripting entre marcos .
En el evento Onload del formulario obtendremos los valores que sean referentes al nombre de la calle, distrito, departamento y país y luego lo concatenaremos de la siguiente manera. Cabe resaltar que para el registro de estos campos no he utilizado los que vienen de caja sino que he creado lookups por temas de ubigeo.
var url= "http://maps.google.com/maps?q=" + 
crmForm.all.jc_paisid.DataValue[0].name+ "," + 
crmForm.all.jc_departamentoid.DataValue[0].name + "," + 
crmForm.all.jc_distritoid.DataValue[0].name + "," + 
crmForm.all.jc_calle.DataValue;
crmForm.all.IFRAME_Mapa.src=url;

Ahora que el mapa es se muestra en el formulario, crearemos un botón el cual nos permita ocultarlo y/o visualizarlo según nuestra necesidad. Para lograr esto primero debemos tener en cuenta el jscript que nos permitirá esta fucnionalidad.
var displ=crmForm.all.IFRAME_Mapa.style.display;
if(displ=='none') crmForm.all.IFRAME_Mapa.style.display='';
else crmForm.all.IFRAME_Mapa.style.display='none';
NOTA:El código mostrado arriba nos permite esta funcionalidad. Lo más recomendable es que el IFRAME se encuentre en una sección diferente para ocultar la sección en lugar de ocultar el IFRAME ya que si hacemos esto último se mostrará un espacio vacío.

Empezando a CRMear!!!!!!!

Hola a todos los visitantes de este Blog. Soy consultor de Dynamics CRM desde la versión 3.0 y ahora me encuentro investigando sobre las funcionalidades de la 5.0 Espero realmenete que este medio sirva para poder brindarles apoyo, notas de interés y compartir conocimiento alrededor de MS Dync CRM. Gracias por su atención y bienvenidos a CRMeando.