Eficiente obtener y establecer propiedades personalizadas en una carpeta de contactos en Outlook (2010) (traducción automática)

Importante

En este artículo es la máquina que se traduce, vea la renuncia de responsabilidad. Encontrará la versión en inglés de este artículo aquí para su referencia.

Ayuda visual de Office

Resumen:  Obtenga información acerca de cómo obtener y establecer propiedades personalizadas para elementos de contacto en Microsoft Outlook 2010 de forma eficaz. En concreto, en este artículo se describe cómo utilizar los métodos GetProperties y SetProperties del objeto PropertyAccessor para obtener y establecer muchas propiedades al mismo tiempo.

Applies to: Microsoft Outlook 2010 |  Microsoft Visual Studio 2010

Publicado:  Octubre de 2010

Proporcionado por:  Jonathan Fingold, puente de SDK, LLC

Introducción

Los métodos GetProperties y SetProperties del objeto PropertyAccessor permiten obtener y establecer varias propiedades integradas y personalizadas de un elemento de Microsoft Outlook 2010 con una llamada al método de forma eficaz. En este artículo se utiliza un proyecto de complemento de Outlook de C# que muestran cómo utilizar estos dos métodos.

Codifíquelo

El ejemplo proporcionado con este Visual cómo utiliza un proyecto de C# Outlook 2010 complemento escrito en Microsoft Visual Studio 2010. Para utilizar este ejemplo, ya debe estar familiarizado con C# y crear formularios personalizados y complementos para Outlook.

.files

El complemento contiene cuatro clases importantes:

  • ThisAddin: inicializa el complemento, proporciona acceso a la carpeta de contactos de oportunidades y crea la carpeta oportunidades si no existe.

  • OpportunitiesRibbon: cinta de opciones proporciona un complemento que contiene dos botones (Importar datos y Exportar datos) y importa y exporta los datos entre Outlook y los archivos de datos especificado.

  • Constants: se definen las referencias de la propiedad para las propiedades integradas y personalizadas que este complemento, importa y exporta y contiene otras constantes, como, por ejemplo, los pantalla nombres y tipos de datos de las propiedades.

  • ContactItemHelper: controla las operaciones de archivo asociadas a la importación y exportación de los datos de propiedad.

Además de los archivos de proyecto de Visual Studio, el archivo .zip de ejemplo de código también contiene un archivo de Opportunity.oft de ventas. Debe publicar el formulario de oportunidades de ventas en la biblioteca de formularios personales, especificando el nombre "Oportunidad de ventas".

Puesta en marcha y la carpeta oportunidades

La clase ThisAddin define una propiedad de OpportunitiesFolder, para obtener el objeto Folder para la carpeta oportunidades y un método de CreateOpportunitiesFolder, para crear la carpeta si no existe. Al crear la carpeta oportunidades, el complemento utiliza el objeto de UserDefinedProperties para definir los cinco propiedades de usuario de las cinco propiedades personalizadas que corresponden a los campos en el formulario de oportunidades de ventas.

Cuando se inicia Outlook, llama método de inicio del complemento, ThisAddIn_Startup. El complemento de comprueba si existe la carpeta y crea uno si no existe ya, como se muestra en el siguiente código.

private static readonly string opportunitiesFolderName =
    "Opportunities";

/// <summary>Initializes the add-in.</summary>
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    Outlook.Folder opportunitiesFolder = OpportunitiesFolder;

    // Create the contacts folder titled Opportunities,
    // if the folder does not already exist.
    if (opportunitiesFolder == null)
    {
        opportunitiesFolder = CreateOpportunitiesFolder();
    }
}

/// <summary>Gets the root contacts folder.</summary>
private Outlook.Folder RootContactsFolder
{
    get
    {
        // Use the MAPI namespace to get the root contacts folder.
        Outlook.NameSpace outlookNameSpace =
            this.Application.GetNamespace("MAPI");

        return outlookNameSpace.GetDefaultFolder(
            Outlook.OlDefaultFolders.olFolderContacts)
            as Outlook.Folder;
    }
}

/// <summary>Gets the contacts folder titled Opportunities.</summary>
internal Outlook.Folder OpportunitiesFolder
{
    get
    {
        // Get and return the Opportunities contacts folder,
        // if it exists.
        foreach (Outlook.Folder folder in RootContactsFolder.Folders)
        {
            if (folder.Name.Equals(opportunitiesFolderName))
            {
                return folder;
            }
        }

        // Otherwise, return null.
        return null;
    }
}

/// <summary>Creates a contacts folder titled Opportunities.</summary>
private Outlook.Folder CreateOpportunitiesFolder()
{
    try
    {
        // Create the folder.
        Outlook.Folder opportunitiesFolder =
            RootContactsFolder.Folders.Add(opportunitiesFolderName,
            Outlook.OlDefaultFolders.olFolderContacts)
            as Outlook.Folder;

        // Set the default form for this folder to the custom form,
        // so that new contacts in this folder will use this form.

        // Set the custom form message class property on the folder.
        opportunitiesFolder.PropertyAccessor.SetProperty(
            Constants.MessageClassID,
            Constants.MessageClassOpportunities);

        // Set the custom form display name property on the folder.
        opportunitiesFolder.PropertyAccessor.SetProperty(
            Constants.MessageClassDisplayNameID,
            Constants.SalesFormDisplayName);

        DefineUserProperties(opportunitiesFolder);

        // Make the Opportunities folder visible.
        opportunitiesFolder.GetExplorer().NavigationPane.
            CurrentModule.Visible = true;

        return opportunitiesFolder;
    }
    catch (Exception ex)
    {
        // Dump exception information to the debugger.
        Debug.WriteLine("{0}: {1}", ex.GetType().Name, ex.Message);
        return null;
    }
}

/// <summary>Defines the sales user properties for a folder.</summary>
/// <param name="opportunitiesFolder">The folder in which to define the 
/// sales user properties.</param>
private void DefineUserProperties(Outlook.Folder opportunitiesFolder)
{
    opportunitiesFolder.UserDefinedProperties.Add(
        Constants.encounterDateDisplayName,
        Outlook.OlUserPropertyType.olDateTime,
        true, Outlook.OlFormatDateTime.OlFormatDateTimeLongDayDate);

    opportunitiesFolder.UserDefinedProperties.Add(
        Constants.purchaseEstimateDisplayName,
        Outlook.OlUserPropertyType.olCurrency,
        true, Outlook.OlFormatCurrency.olFormatCurrencyDecimal);

    opportunitiesFolder.UserDefinedProperties.Add(
        Constants.salesRepDisplayName, Outlook.OlUserPropertyType.olText);

    opportunitiesFolder.UserDefinedProperties.Add(
        Constants.salesValuedisplayName,
        Outlook.OlUserPropertyType.olInteger,
        true, Outlook.OlFormatInteger.olFormatIntegerPlain);

    opportunitiesFolder.UserDefinedProperties.Add(
        Constants.tradeShowDisplayName,
        Outlook.OlUserPropertyType.olYesNo,
        true, Outlook.OlFormatYesNo.olFormatYesNoTrueFalse);
}

Obtener y establecer valores de propiedad

La clase OpportunitiesRibbon contiene los controladores de eventos para los botones de Importar datos y Exportar datos .

Las rutas de acceso para los archivos de datos de importación y exportación se definen en la parte superior del archivo, como se muestra en el siguiente código. El archivo de datos de importación (ContactData.csv) se incluye en el archivo .zip de ejemplo de código. El archivo de datos de exportación se crea o se sobrescriben cuando el complemento exporta los datos. Actualizar las rutas de acceso, según sea necesario.

private static readonly string dataImportFile =
    @"D:\ImportData\ContactData.csv";
private static readonly string dataExportFile =
    @"D:\ExportedData\UpdatedContactData.csv";

Para importar los datos de contacto, el complemento lee el contenido del archivo de datos y crea objetos auxiliares que almacenarán temporalmente los datos de una lista de elemento de contacto. (En el código de producción, probablemente deseará crear cada elemento de contacto a medida que recibe los datos del origen de datos.)

Para cada contacto, el complemento crea un elemento de contacto de la oportunidad de ventas, utiliza el objeto de PropertyAccessor del nuevo elemento para establecer todos los valores de propiedad al mismo tiempo y, a continuación, guarda el nuevo contacto, tal como se muestra en el siguiente código.

El método DumpErrorsFromSetProperties envía información acerca de los errores encontrados en la salida de depuración.

private static void ImportData()
{
    List<ContactItemHelper> itemData =
        ContactItemHelper.LoadDataFromFile(dataImportFile);
    foreach (ContactItemHelper contactData in itemData)
    {
        // Create a new sales opportunity contact.
        Outlook.ContactItem newContact =
            Globals.ThisAddIn.OpportunitiesFolder.Items.Add(
            Constants.MessageClassOpportunities)
            as Outlook.ContactItem;

        // Set properties for the contact item.
        object[] errors = newContact.PropertyAccessor.SetProperties(
            ContactItemHelper.PropertyReferences,
            contactData.PropertyValues);

        // Check any errors returned by the SetProperties method.
        DumpErrorsFromSetProperties(contactData, errors);

        newContact.Save();
    }
}

El código siguiente muestra cómo el complemento exporta los datos de contactos por recorrer en iteración los elementos de contacto, compilar una lista de los valores de los elementos de contacto para exportar y, a continuación, escribir los datos en un archivo. csv.

Para cada elemento de contacto, el complemento utiliza PropertyAccessor del elemento para obtener todos los valores de propiedad especificada al mismo tiempo.

private static void ExportData()
{
    // Get a list of the values from the items to export.
    List<object[]> exportItems = new List<object[]>();
    foreach (Outlook.ContactItem item in
        Globals.ThisAddIn.OpportunitiesFolder.Items)
    {
        // Ignore items that are not Sales Opportunity contact items.
        if (item.MessageClass != Constants.MessageClassOpportunities)
            continue;

        // Get values for specified properties from the item's
        // PropertyAccessor.
        object[] values = item.PropertyAccessor.GetProperties(
            ContactItemHelper.PropertyReferences);

        try
        {
            // Convert the encounter date value from a UTC time to 
            // a local time.
            values[5] =
                item.PropertyAccessor.UTCToLocalTime(
                (DateTime)values[5]);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Unable to convert encounter date " +
                "from UTC to local time for contact {0}: {1}",
                item.FullName, ex.Message);
        }

        // Add the values to the list of contact item data.
        exportItems.Add(values);
    }

    // Export the items to a data file.
    ContactItemHelper.ExportData(dataExportFile, exportItems);
}

Hacer referencia a propiedades por su espacio de nombres

Propiedades de los métodos GetProperties y SetProperties de referencia por su espacio de nombres. El código siguiente agrega las referencias de la propiedad para las propiedades integradas y personalizadas como campos de sólo lectura en la clase estática Constants.

También se incluyen los nombres para mostrar las propiedades de la clase Constants.

La mayoría de las propiedades integradas utilizan el espacio de nombres MAPI proptag.

// Display names for built-in properties:

public static readonly string lastNameDisplayName = "Last Name";
public static readonly string firstNameDisplayName = "First Name";
public static readonly string companyNameDisplayName = "Company";
public static readonly string customerIDDisplayName = "CustomerID";
public static readonly string primaryEmailDisplayName = "email";

// References to built-in properties by their namespaces:

/// <summary>A reference to the last name property by its namespace.</summary>
public static readonly string lastNamePropRef =
    "https://schemas.microsoft.com/mapi/proptag/0x3A11001F";

/// <summary>A reference to the first name property by its namespace.</summary>
public static readonly string firstNamePropRef =
    "https://schemas.microsoft.com/mapi/proptag/0x3A06001F";

/// <summary>A reference to the company name property by its namespace.</summary>
public static readonly string companyNamePropRef =
    "https://schemas.microsoft.com/mapi/proptag/0x3A16001F";

/// <summary>A reference to the customer ID property by its namespace.</summary>
public static readonly string customerIDProperRef =
    "https://schemas.microsoft.com/mapi/proptag/0x3A4A001F";

/// <summary>A reference to the primary email property by its namespace.</summary>
public static readonly string primaryEmailPropRef = "urn:schemas:contacts:email1";

Las propiedades personalizadas, que se muestra en el siguiente código, utilizan el espacio de nombres MAPI string.

Gg262881.note(es-es,office.14).gifNota:
Para las propiedades personalizadas, los contactos de Office GUID es parte del nombre del esquema. También se incluyen en esta clase son nombres para mostrar las propiedades. Los permisos muestran los nombres de identificar los datos de la importación y exportación de archivos.

// Display names for custom properties:

public static readonly string encounterDateDisplayName =
    "Encounter Date";
public static readonly string purchaseEstimateDisplayName =
    "Purchase Estimate";
public static readonly string salesRepDisplayName = "Sales Rep";
public static readonly string salesValuedisplayName = "Sales Value";
public static readonly string tradeShowDisplayName = "Trade Show";

// References to custom properties by their namespaces:

private static readonly string baseUri =
    "https://schemas.microsoft.com/mapi/string";
private static readonly string contactItemsGuid =
    "{00020329-0000-0000-C000-000000000046}";

/// <summary>A reference to the encounter date property by its namespace.
/// </summary>
public static readonly string encounterDatePropRef =
    string.Format("{0}/{1}/{2}", baseUri, contactItemsGuid,
    encounterDateDisplayName);

/// <summary>A reference to the purchase estimate property by its namespace.
/// </summary>
public static readonly string purchaseEstimatePropRef =
    string.Format("{0}/{1}/{2}", baseUri, contactItemsGuid,
    purchaseEstimateDisplayName);

/// <summary>A reference to the sales rep property by its namespace.</summary>
public static readonly string salesRepPropRef =
    string.Format("{0}/{1}/{2}", baseUri, contactItemsGuid, salesRepDisplayName);

/// <summary>A reference to the sales value property by its namespace.</summary>
public static readonly string salesValuePropRef =
    string.Format("{0}/{1}/{2}", baseUri, contactItemsGuid, salesValuedisplayName);

/// <summary>A reference to the trade show property by its namespace.</summary>
public static readonly string tradeShowPropRef =
    string.Format("{0}/{1}/{2}", baseUri, contactItemsGuid, tradeShowDisplayName);

Las propiedades personalizadas abarcan algunos de los tipos de datos posibles, que se muestra en el siguiente código, y esta clase proporciona un método GetDataType que devuelve la información de tipo para cada propiedad.

private static readonly Dictionary<string, Type> dataTypes;

static Constants()
{
    dataTypes = new Dictionary<string, Type>();
    dataTypes[lastNameDisplayName] = typeof(string);
    dataTypes[firstNameDisplayName] = typeof(string);
    dataTypes[companyNameDisplayName] = typeof(string);
    dataTypes[primaryEmailDisplayName] = typeof(string);
    dataTypes[customerIDDisplayName] = typeof(string);
    dataTypes[customerIDProperRef] = typeof(string);
    dataTypes[encounterDateDisplayName] = typeof(DateTime);
    dataTypes[purchaseEstimateDisplayName] = typeof(double);
    dataTypes[salesRepDisplayName] = typeof(string);
    dataTypes[salesValuedisplayName] = typeof(int);
    dataTypes[tradeShowDisplayName] = typeof(bool);
}

/// <summary>Returns the managed data type for a given property.
/// </summary>
/// <param name="fieldName">The property name.</param>
/// <returns>The data type of the property, or typeof(string) if the
/// property name is not recognized.</returns>
internal static Type GetDataType(string fieldName)
{
    if (dataTypes.ContainsKey(fieldName))
    {
        return dataTypes[fieldName];
    }
    else
    {
        return typeof(string);
    }
}

Léalo

Cuando se inicia Outlook, el complemento busca una carpeta de contactos de oportunidades y crea uno si no existe. El complemento permite cargar datos desde un archivo de datos para rellenar los elementos de contacto en la carpeta oportunidades. Esta carpeta contendrá los contactos que incluyen información de ventas personalizado, que puede tener acceso a través de un formulario personalizado de la oportunidad de venta. El complemento utiliza el método SetProperties del objeto PropertyAccessor para agregar la información de contacto para cada contacto nuevo y, a continuación, este método permite establecer integrados y las propiedades personalizadas al mismo tiempo.

El PropertyAccessor es bueno para este escenario. Uso del objeto PropertyAccessor conlleva cierta sobrecarga, sino que reduce el tráfico de red. Los métodos GetProperties y SetProperties realizan más rápido que con el objeto de UserProperties cuando tiene que obtener o establecer varias propiedades personalizadas en el nivel de elemento, o el objeto UserDefinedProperties para obtener o establecer varias propiedades personalizadas en el nivel de carpeta. Además, una llamada al método GetProperties o SetProperties es mucho más rápida en establecer varias propiedades que llamar al método GetProperty o SetProperty varias veces.

En este artículo, se publica el formulario de oportunidades de ventas en la biblioteca de formularios personales. La clase de mensaje para el formulario predeterminado de la carpeta oportunidades se establece en IPM.Oportunidad de Contact.Sales. Además, cuando se crean nuevos contactos de los datos importados, se crean como un IPM.Tipo de la oportunidad de Contact.Sales y el formulario de oportunidades de ventas se establece como el predeterminado que se muestra para estos elementos.

Tipos de propiedades

Las propiedades personalizadas en este ejemplo abarcan algunos de los tipos de datos posibles:

  • Fecha encontró contiene un valor de fecha, que es DateTime en C#.

  • Estimación de la compra contiene un valor de moneda, que es double en C#.

  • El representante de ventas contiene un valor de cadena.

  • Valor de ventas contiene un valor entero de 32 bits con signo y representa el rango del contacto.

  • Feria comercial contiene un valor booleano, que es bool en C#.

Establecer las propiedades

El método SetProperties toma dos parámetros:

  • El parámetro SchemaNames contiene una matriz de referencias de propiedad para cada propiedad que desee establecer.

  • El parámetro Values contiene una matriz de los valores para establecer en todas las propiedades en el parámetro SchemaNames.

Si el método SetProperties encuentra un error al asignar un valor a una propiedad, su valor devuelto contiene una matriz que contiene un valor HRESULT que corresponde a cada propiedad que ha generado un error. Si SetProperties se encuentra ningún error, su valor devuelto es una matriz vacía.

Obtener acceso a propiedades

El método GetProperties toma un parámetro, SchemaNames, que contiene una matriz de nombres de esquema para cada propiedad que desee obtener.

El valor devuelto contiene una matriz de los valores de cada propiedad en el parámetro SchemaNames.

Si el método GetProperties encuentra un error al leer un valor de una propiedad, su valor devuelto contiene un valor HRESULT en lugar del valor de esa propiedad en particular.

Consideraciones

Hay varias cosas a considerar cuando se utilizan los métodos GetProperties y SetProperties:

  • Outlook almacena los valores de hora en formato UTC. El objeto de PropertyAccessor proporciona métodos para la conversión entre la hora UTC y la hora local.

  • Outlook almacena los valores binarios como una matriz de bytes. El PropertyAccessor proporciona métodos para la conversión entre cadenas y matrices binarias.

  • El PropertyAccessor no admite algunos tipos de propiedades MAPI, como, por ejemplo, el tipo de propiedad del objeto.

Para obtener más información, consulte la sección explórelo.

Consultar

Ver el vídeo

Ver el vídeo

Duración del vídeo: 09: 57 | Tamaño del archivo: 29,4 MB | Tipo de archivo: Archivo WMV

Hacer clic para obtener el código

Tomar el código

Explórelo

Nota

Declinación de responsabilidades de traducción automática: Este artículo se ha traducido con un sistema informático sin intervención humana. Microsoft ofrece estas traducciones automáticas para que los hablantes de otros idiomas distintos del inglés puedan disfrutar del contenido sobre los productos, los servicios y las tecnologías de Microsoft. Puesto que este artículo se ha traducido con traducción automática, es posible que contenga errores de vocabulario, sintaxis o gramática.