Импорт данных из Outlook - рыба Ключевые слова: Outlook,рыба,интеграция,импорт,обмен данными
Тезисы:
Каждый элемент Outlook имеет уникальный 48-символьный идентификатор EntryID.Каждый элемент имеет текстовое поле MessageClass со значениями: "IPM.Note", "IPM.Task","IPM.Contact", "IPM.Activity", "IPM.Appointment".
Каждый элемент имеет коллекцию стандартных свойст ItemProperties (нумерация с нуля) и пользовательских свойств UserProperties (нумерация с единицы)Обычно нумерация у объектов в коллекциях Outlook идет с единицы
Имя Com-объекта Outlook "Outlook.Application"При доступе к Outlook таким образом при чтении свойств объектов или модификации данных Outlook выскакивает предупреждение защиты объектной модели Outlook, можно разрешить доступ к Outlook, но не более чем на 10 минут. Есть программы, которые автоматически кликают да в таких окошечках.
Пустая дата в Outlook переносится через OLE как дата 1С '45010101'. Такая дата не может быть сохранена в SQL и вылетает ошибка, поэтому нужно заменять такую дату на дату '00010101'
Перем Аутлук, ПространствоИмен;
Функция ТипАутлукВИдентификаторТипа(Тип)
Если Тип=2 Тогда
Возврат "Сообщения";
КонецЕсли;
Если Тип=2 Тогда
Возврат "Сообщения";
КонецЕсли;
Возврат Неопределено;
КонецФункции
Функция ХорошееИмя(С)
Перем Поз;
Рез=С;
Если С="" Тогда
Возврат "";
КонецЕсли;
Пока истина<>0 Цикл
Поз=НайтиНедопустимыеСимволыXML(С);
Если Поз=0 Тогда
Прервать;
КонецЕсли;
Рез=Сред(Рез,1, Поз-1)+Сред(Рез, Поз+1);
КонецЦикла;
Рез=СтрЗаменить(Рез, Символ(13)+Символ(10), Символы.ПС);
Рез=СтрЗаменить(Рез, Символ(182), Символы.ПС);
Возврат Рез;
КонецФункции
Функция Значение1СИзАутлук(Знч)
Перем Рез;
Если ТипЗнч(Знч)=Тип("Строка") Тогда
Возврат ХорошееИмя(Знч);
КонецЕсли;
Если ТипЗнч(Знч)=Тип("Дата") Тогда
Если Знч='45010101' Тогда
Возврат '00010101';
КонецЕсли;
КонецЕсли;
Возврат Знч;
КонецФункции
Функция ЗагрузитьЭлемент(Элемент)
Объект=Неопределено;
Если Найти(Элемент.MessageClass,"IPM.Note")=1 Тогда
Тип="Note";
ИначеЕсли Найти(Элемент.MessageClass,"IPM.Task")=1 Тогда
Тип="Task";
ИначеЕсли Найти(Элемент.MessageClass,"IPM.Contact")=1 Тогда
Тип="Contact";
ИначеЕсли Найти(Элемент.MessageClass,"IPM.Activity")=1 Тогда
Тип="Activity";
ИначеЕсли Найти(Элемент.MessageClass,"IPM.Appointment")=1 Тогда
Тип="Appointment";
Иначе
Возврат Неопределено;
КонецЕсли;
Объект=Неопределено;
Ссылка=Неопределено;
Загружать=ложь;
Идентификатор=СокрЛП(Элемент.EntryID);
Если Идентификатор="" Тогда
Возврат Неопределено;
КонецЕсли;
НачатьТранзакцию();
МЗ=РегистрыСведений.АутлукИдентификаторы.Получить(Новый Структура("ВнешняяБаза,Идентификатор",ВнешняяБаза,Идентификатор));
Если НЕ МЗ.Объект.Пустая() Тогда
Ссылка=МЗ.Объект;
Если Обновлять Тогда
Объект=Ссылка.ПолучитьОбъект();
Загружать=истина;
КонецЕсли;
Регистрировать=ложь;
Иначе
//Создаем новый объект
Регистрировать=истина;
Загружать=истина;
Если Тип="Task" Тогда
Объект=Справочники.Задачи.СоздатьЭлемент();
КонецЕсли;
КонецЕсли;
Если Загружать и Объект<>Неопределено Тогда
//Обновляем значения свойств
Свойства=Новый Соответствие();
Для Инд=1 По Элемент.ItemProperties.Count() Цикл
Свойство=Элемент.ItemProperties.Item(Инд-1);
Если Свойство.Type=0 Тогда
Продолжить;
КонецЕсли;
Свойства.Вставить(Свойство.Name, Значение1СИзАутлук(Свойство.Value));
КонецЦикла;
Для Инд=1 По Элемент.UserProperties.Count() Цикл
Свойство=Элемент.UserProperties.Item(Инд);
Если Свойство.Type=0 Тогда
Продолжить;
КонецЕсли;
Свойства.Вставить(Свойство.Name, Значение1СИзАутлук(Свойство.Value));
КонецЦикла;
//Установка реквизитов
Если Тип="Task" Тогда
Объект.Наименование=Свойства["Subject"];
Объект.Содержание=Свойства["Body"];
КонецЕсли;
//Запись объекта
Объект.ОбменДанными.Загрузка=истина;
Объект.Записать();
Ссылка=Объект.Ссылка;
//Заносим значения свойств
Для Каждого Свойство Из Свойства Цикл
МЗ=РегистрыСведений.АутлукСвойства.СоздатьМенеджерЗаписи();
МЗ.ВнешняяБаза=ВнешняяБаза;
МЗ.ИмяРеквизита=ХорошееИмя(Свойство.Ключ);
МЗ.Объект=Ссылка;
Знч=Свойство.Значение;
МЗ.ЭтоСтрока=ложь;
Если ТипЗнч(Знч)=Тип("Строка") Тогда
МЗ.ЭтоСтрока=истина;
МЗ.ЗначениеСтрока=Знч;
Иначе
МЗ.Значение=Знч;
КонецЕсли;
МЗ.Записать(истина);
КонецЦикла;
КонецЕсли;
Если Регистрировать И Ссылка<>Неопределено Тогда
МЗ=РегистрыСведений.АутлукИдентификаторы.СоздатьМенеджерЗаписи();
МЗ.ВнешняяБаза=ВнешняяБаза;
МЗ.Идентификатор=Идентификатор;
МЗ.Объект=Ссылка;
МЗ.Тип=Тип;
МЗ.Записать(ложь);
КонецЕсли;
ЗафиксироватьТранзакцию();
Возврат Ссылка;
КонецФункции
Функция ЗагрузитьИзАутлук()
Если ВнешняяБаза.Пустая() Тогда
Сообщить("Не выбрана внешняя база ", СтатусСообщения.Внимание);
Возврат ложь;
КонецЕсли;
//Получаем список папок, которые нужно грузить
Строки=ТПапки.Строки.НайтиСтроки(Новый Структура("Пометка",Истина), Истина);
Для Каждого Стр Из Строки Цикл
Сообщить("=== "+Стр.Имя+" ===");
Попытка
Элементы=Стр.Папка.Items;
Исключение
ОписаниеОшибки=ОписаниеОшибки();
Сообщить("Не удается получить список элементов папки "+ОписаниеОшибки, СтатусСообщения.Внимание);
КонецПопытки;
Для Инд=1 По Элементы.Count() Цикл
ОбработкаПрерыванияПользователя();
Если Инд%10 Тогда
Состояние("Загружается папка:"+Стр.Имя+" Обработано:"+Инд);
КонецЕсли;
Элемент=Элементы.Item(Инд);
ЗагрузитьЭлемент(Элемент);
КонецЦикла;
КонецЦикла;
КонецФункции
Процедура КнопкаВыполнитьНажатие(Кнопка)
// Вставить содержимое обработчика.
ЗагрузитьИзАутлук();
КонецПроцедуры
Функция ОбновитьСписокПапок(Родитель, Строки, Уровень)
ОбработкаПрерыванияПользователя();
Состояние("Обновление списка папок, уровень:"+Уровень);
Для Инд=1 ПО Родитель.Folders.Count() Цикл
Папка=Родитель.Folders.Item(Инд);
ИмяПапки=Папка.Name;
Стр=Строки.Найти(ИмяПапки, "Имя");
Если Стр=Неопределено Тогда
Стр=Строки.Добавить();
Стр.Имя=ИмяПапки;
КонецЕсли;
Стр.Папка=Папка;
Стр.Тип=Папка.DefaultMessageClass;
//Сообщить(Папка.Name);
ОбновитьСписокПапок(Папка, Стр.Строки, Уровень+1);
КонецЦикла;
КонецФункции
Процедура КнОбновитьСписокПапокНажатие(Элемент)
// Вставить содержимое обработчика.
ОбновитьСписокПапок(ПространствоИмен, ТПапки.Строки, 1);
//ЭлементыФормы.ТПапки.СоздатьКолонки();
КонецПроцедуры
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
ТПапки.Колонки.Добавить("Папка");
//ТПапки.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
// Вставить содержимое обработчика.
КонецПроцедуры
Процедура ПриОткрытии()
// Вставить содержимое обработчика.
Попытка
Аутлук=Новый COMОбъект("Outlook.Application");
ПространствоИмен = Аутлук.GetNamespace("MAPI");
Исключение
ОписаниеОшибки=ОписаниеОшибки();
Сообщить("Не удается создать объект Outlook, возможно Outlook не установлен на компьютере "+ОписаниеОшибки, СтатусСообщения.Внимание);
КонецПопытки;
КнОбновитьСписокПапокНажатие(ЭлементыФормы.КнОбновитьСписокПапок);
КонецПроцедуры
|