четверг, 30 октября 2008 г.

WMI,1C,Синхронизация часть вторая

Первую задачу синхронизации работников. Я решил и успокоился, что все хватит с меня WMI. Оказалось не все так легко и просто. Встала вторая часть этой задачи, надо стало синхронизировать WMI и список подразделений.

В дереве AD подразделения были сделаны как элементы OU. И немного поштудировав MSDN я нашел, что AD для любой записи представляет интересный реквизит objectGuid. Значение которого для каждого обьекта в дереве уникально.
Из этих двух положений и станцевался кусочек кода.

P.S. Надо учитывать, что objectGuid на выходе предоставляет собой массив байт.

  1. Домен=ПолучитьCOMОбъект("LDAP://OU=YYYY,DC=ХХХ,DC=loc")
  2. // Проверка по подразделениям
  3. Для каждого объекта из Домен Цикл
  4. Для каждого класса из объекта.ObjectClass Цикл
  5.         Если НРег(класса)<>"organizationalunit" Тогда
  6.                 Продолжить;
  7.         КонецЕсли;     
  8.                
  9. НаименованиеДепартамента = СтрЗаменить(объекта.Name,"OU=","");
  10.                        
  11.         // Получим ГУИД
  12.         _ГуидДепартамента         = объекта.objectGuid;
  13.         // Теперь переведем массив байт в более понятный текстовый вид
  14.         _Гуид  = "";
  15.         _Длина = _ГуидДепартамента.GetLength(0);
  16.         Для Счетчик = 1 по _Длина-1 Цикл
  17.                 _Гуид = _Гуид + "_"+Строка(_ГуидДепартамента.GetValue(Счетчик-1)));
  18.         КонецЦикла;     
  19. // Ну а дальше уже имея на руках название подразделения и его уникальный
  20. // текстовый код, проблем быть не должно.
  21. КонецЦикла;

Примерчик работы с WMI через ADO

Встала у меня задачка надо синхронизировать содежимое ActiveDirectory и справочников 1С.

Ниже кратенький и вполне достойный пример, опроса WMI на предмет активных аккаунтов (сиречь пользователей).

P.S. А после дело синхронизации становиться легким и простым как два байта переслать. :)

  1. objConnection = ПолучитьCOMОбъект("","ADODB.Connection");
  2. objConnection.Open("Provider=ADsDSOObject");
  3. objCommand = ПолучитьCOMОбъект("","ADODB.Command");
  4. objCommand.ActiveConnection = objConnection;
  5. objCommand.CommandText =
  6. "<GC://OU=XXX,dc=YYY,dc=loc>;objectCategory=User);displayName,sAMAccountName,
  7. telephoneNumber,userAccountControl,objectGuid,distinguishedName,mail;subtree";
  8. objRecordSet = objCommand.Execute();
  9. Пока НЕ(objRecordset.EOF) Цикл
  10.  Логин = objRecordset.Fields("sAMAccountName").Value;
  11.  Почта = objRecordset.Fields("mail").Value;
  12.  Имя   = objRecordset.Fields("displayName").Value;
  13.  
  14.  Если ПустаяСтрока(Имя) Тогда
  15.   objRecordset.MoveNext();
  16.   Продолжить;   
  17.  КонецЕсли;

четверг, 16 октября 2008 г.

1C: Комплект универсальных отчетов

КонсольАнализаЖурналаРегистрации81
КонсольЗаданий
КонсольЗапросов
КонсольКластераСерверов
НастройкаТехнологическогоЖурнала

вторник, 14 октября 2008 г.

1C 8.1: Регламентные задания, маленькие хитрости

При некоторой заскорузлости описания в учебнике 1С. Документация мне так и не дала мне ответа, почему я сделал все как написано, но задание так и не запускается. Моя проблема оказалась в том, что регламентное задание запускается как внешнее соединение и в этом режиме все обращения к визуальным элементам считаются "ошибка выполнения" при этом консоль сервера не дает ответа, что случилось с запускаемым заданием. Ответ на этот вопрос дала универсальная обработка с диска ИТС "КонсольСервера", с помошью которой можно не только просматривать статистику работы запущенных задач (имхо по крайней мере, сообщение о том, что выполнение задачи было прервано на строке Х и произошла ошибка Ч, было для меня большущим подспорьем). Кроме того, ошибка может быть даже и не в процедуре регламентного задания, а в какой либо другой и увидеть это без обработки крайне сложно.

В общем подитожу:

1. Модули помеченные галочкой внешние соединение, должны содержать только те процедуры и функции которые необходимы для функционирования регламентной процедуры.

2. Обязательно иметь под руками обработку "Консоль сервера", чтобы иметь возможность контролировать ход выполнения заданий.

3. Помнить, что в случае клиент-сервера, планировщиком выступит сервер приложений, а для случая файл-сервера должен функционировать отдельное приложение, которое должно заниматься опросом:

Процедура ОбработкаЗаданий() 
    ВыполнитьОбработкуЗаданий();
КонецПроцедуры

ПодключитьОбработчикОжидания("ОбработкаЗаданий", 3);

* This source code was highlighted with Source Code Highlighter.

 

После запуска данной обработки, при открытии ее формы, выполняется подключение в качестве обработчика ожидания процедуры "ОбработкаЗаданий", которая будет вызываться каждые 3 секунды и, в свою очередь, вызывать метод "ВыполнитьОбработкуЗаданий()". Данный метод проверяет, пришло ли время выполнять задания согласно их расписанию. Если да - то он запускает эти задания на выполнение. Открытие созданной обработки по запуску регламентных заданий не рекомендуется осуществлять в том же соединении, где выполняется основная работа с информационной базой. Для подобной задачи лучше использовать отдельное соединение с той же базой. Более подробно данный вопрос освещен, например, в книге М.Радченко "1С:Предприятие 8.1. Практическое пособие разработчика. Примеры и типовые приемы", глава 12, стр.288.