Материал подготовлен совместно с Петром Федотовым
Рассмотрим несколько примеров, когда нам необходимо не просто передать значение одного реквизита справочника DIRECTUM в аналогичный реквизит справочника 1С, а выполнить какие-нибудь вычисления с реквизитом и уже результат вычисления передать в 1С. Для этого в карточке «Настройки обмена данными с интегрированными системами» для нужного справочника в табличной части надо создать вычисляемый реквизит и задать для него вычисление.
Пример 1. Необходимо настроить синхронизацию справочника Организации DIRECTUM со справочником Контрагенты 1С. Нужно, чтобы реквизит «Юр. / физ. лицо» справочника Контрагенты 1С заполнялся значением «ЮрЛицо». Аналогичного реквизита в справочнике Организации DIRECTUM нет и проблему решить можно с помощью вычисляемых реквизитов. Вычисление для этого реквизита будет таким:
Result = "ЮрЛицо"
В результате в реквизит «Юр. / физ. лицо» справочника Контрагенты 1С мы постоянно будем передавать константу «ЮрЛицо».
Пример 2. Необходимо настроить синхронизацию справочника Персоны DIRECTUM со справочником Физические лица 1С. Нужно, чтобы заполнялись реквизиты «Фамилия», «Имя» и «Отчество» справочника Персоны DIRECTUM. В справочнике Физические Лица 1С ФИО присутствует в виде одной строки в реквизите «Наименование». В этом случае нам на помощь придут вычисляемые реквизиты:
Вычисление реквизита Фамилия:
FIO = '[Description]'
Result = SubString(FIO;' ';1)
Вычисление реквизита Имя:
FIO = '[Description]'
Result = SubString(FIO;' ';2)
Вычисление реквизита Отчество:
FIO = '[Description]'
Result = SubString(FIO;' ';3)
Пример 3. Необходимо настроить синхронизацию справочника Договоры DIRECTUM со справочником Договоры 1С (оба справочника собственная разработка заказчика). Нужно, чтобы реквизит «Состояние договора» типа признак справочника DIRECTUM синхронизировался с реквизитом «Состояние договора» типа справочник «Состояния договоров» справочника 1С. Можно вместо реквизита «Состояние договора» типа признак в справочнике DIRECTUM завести аналогичный реквизит типа справочник и настроить синхронизацию с ним. Можно обойти проблему с помощью вычисляемых реквизитов, но для этого нам нужно будет узнать UUID записей справочника 1С, которые соответствуют значениям реквизита «Состояние договора» типа признак в DIRECTUM. Т.к. я в программировании 1С не силен, то просто добавил на форму записи справочника 1С кнопку и повесил на неё такой обработчик (потом все вернул обратно, как было):
СправочникСсылка = Справочники.СостоянияДоговоров.НайтиПоКоду(1);
Сообщить("Код = 1; UUID = " + СправочникСсылка.УникальныйИдентификатор());
И повторил этот код для всех записей, благо их было не много. В результате вычисление на реквизите получилось следующее:
DogState = '[РИТСостДоговора]'
Result = "00000000-0000-0000-0000-000000000000"
if Assigned(DogState)
if DogState == "В стадии заключения"
Result = "9fa29428-d942-4ef7-b742-ccf411905e1b"
endif
if DogState == "Действующий"
Result = "f6eecbaa-a0a4-49b3-b853-627f6f59fb0e"
endif
if DogState == "Завершен"
Result = "a9f61c04-1422-4d7c-a246-46fef8f963c4"
endif
if DogState == "Расторгнут"
Result = "ff8b6418-9463-4fba-baff-fa768e4912c2"
endif
endif
Пример 4. Необходимо настроить синхронизацию справочника Договоры DIRECTUM со справочником Договоры 1С (оба справочника собственная разработка заказчика). Нужно, чтобы в реквизит «Куратор филиала» справочника 1С заносилась информация о филиале, в котором работает руководитель подразделения заключившего договор из справочника DIRECTUM. В справочнике DIRECTUM такого реквизита нет, но есть реквизит «Подразделение» в котором содержится информация о подразделении, заключившем договор. Справочнику Наши организации DIRECTUM соответствует справочник Организации 1С. Предположим, что уже настроена синхронизация данных справочников, причем Код записи справочника Организации (1C) хранится в реквизите "ISBIntNumber" справочника Наши организации (DIRECTUM). Более наглядно это видно на скриншотах (у реквизита "ISBIntNumber" заголовок «Код 1С»):
Можно добавить в справочник Договоры (DIRECTUM) реквизит «Филиал», в который записывать «Нашу организацию» руководителя подразделения и настроить синхронизацию этого реквизита с реквизитом «Куратор филиала» справочника 1С. А можно в настройках интеграции создать вычисляемый реквизит и все вычисления произвести в нем. Рассмотрим второй вариант, тогда вычисление для этого реквизита будет таким:
IntegratedSystemCode = '1С81' //код системы 1с из справочника DIRECTUM
Environment = Object.Environment
V8AppIndex = Environment.IndexOfName('V8App') //проверяем наличие переменной окружения, созданной ранее коннектором
if V8AppIndex <> -1
V8App = Environment.Values(V8AppIndex)
else //если не нашли, то создадим
V8App = Connector1C81Get1C80Application(IntegratedSystemCode) //получаем 1С app
Environment.SetVar("V8App";V8App) //установить переменную окр. для использования в следующей итерации
endif
// Определим филиал куратора (руководителя подразделения)
PodrCode = '[Подразделение]'
Podr = References.ПОД.GetObjectByCode(PodrCode)
KuratorCode = Podr.Работник
Kurator = References.РАБ.GetObjectByCode(KuratorCode)
KuratorFilialCode = Kurator.НашаОрг
KuratorFilial = References.НОР.GetObjectByCode(KuratorFilialCode)
OrgCode = KuratorFilial.ISBIntNumber
// Обратимся к объектной модели 1С, чтобы найти запись по коду
Record1C = V8App.Справочники.Организации.НайтиПоКоду(OrgCode)
UUID = Record1C.УникальныйИдентификатор()
Result = V8App.String(UUID)
В результате в реквизит «Куратор филиала» справочника Договоры (1С) будет передано значение UUID записи справочника Организации (1С), которому соответствует «Наша организация» (DIRECTUM) руководителя подразделения заключившего договор.
Пример 5. Необходимо настроить синхронизацию справочника Договоры DIRECTUM со справочником Договоры 1С (оба справочника собственная разработка заказчика). Нужно, чтобы в реквизит «Куратор» справочника 1С заносилась информация о Персоне, которая является руководителем подразделения заключившего договор из справочника DIRECTUM. В справочнике DIRECTUM такого реквизита нет, но есть реквизит «Подразделение» в котором содержится информация о подразделении, заключившем договор. Справочнику Персоны DIRECTUM соответствует справочник Физические лица 1С. Предположим, что уже настроена синхронизация данных справочников, причем Код записи справочника Персоны (DIRECTUM) хранится в реквизите «ВнешнийКлюч» справочника Физические лица (1С). Более наглядно это видно на скриншоте:
Опять же, можно добавить в справочник Договоры (DIRECTUM) реквизит «Куратор», в который записывать «Персону» руководителя подразделения и настроить синхронизацию этого реквизита с реквизитом «Куратор» справочника 1С. А можно в настройках интеграции создать вычисляемый реквизит и все вычисления произвести в нем. Рассмотрим второй вариант, тогда вычисление для этого реквизита будет таким:
IntegratedSystemCode = '1С81' //код системы 1с из справочника DIRECTUM
Environment = Object.Environment
V8AppIndex = Environment.IndexOfName('V8App') //проверяем наличие переменной окружения, созданной ранее коннектором
if V8AppIndex <> -1
V8App = Environment.Values(V8AppIndex)
else //если не нашли, то создадим
V8App = Connector1C81Get1C80Application(IntegratedSystemCode) //получаем 1С app
Environment.SetVar("V8App";V8App) //установить переменную окр. для использования в следующей итерации
endif
// Определим куратора (руководителя подразделения)
PodrCode = '[Подразделение]'
Podr = References.ПОД.GetObjectByCode(PodrCode)
KuratorCode = Podr.Работник
Kurator = References.РАБ.GetObjectByCode(KuratorCode)
KuratorPersCode = Kurator.Персона
// Найдем соответствующую запись, обратившись к объектной модели 1С
// Сформируем запрос к 1С
VQuery = V8App.NewObject("Query")
VQueryText = 'select C.Code from Справочник.ФизическиеЛица as C where C.ВнешнийКлюч = "'&KuratorPersCode&'"'
VQuery.Text = VQueryText
VQueryResult = VQuery.Execute
// Обработаем результат запроса
if not VQueryResult.IsEmpty
VQueryRecords = VQueryResult.Choose
VQueryRecords.Next
VRecordCode = V8App.XMLString(VQueryRecords.Get(0))
// Найдем запись по коду
Record1C = V8App.Справочники.ФизическиеЛица.НайтиПоКоду(VRecordCode)
UUID = Record1C.УникальныйИдентификатор()
Result = V8App.String(UUID)
else
Result = "00000000-0000-0000-0000-000000000000"
endif
В результате в реквизит «Куратор» справочника Договоры (1С) будет передано значение UUID записи справочника Физические лица (1С), которому соответствует «Персона» (DIRECTUM) руководителя подразделения заключившего договор.
Пример 6. Иногда нужно из одной записи DIRECTUM сделать две записи в разных справочниках 1С. При этом если эти записи еще и связаны между собой, т.е. в реквизите одной из записей выбрана вторая, то в этом случае нужно иметь возможность получить UUID ссылку на первую запись, чтобы передать её в справочный реквизит второй записи. Это можно сделать только через конструкцию CHANGE_TO_UUID_IDDIR. Подобную ситуацию разберем в этом примере.
Необходимо настроить синхронизацию справочника Договоры DIRECTUM со справочником Договоры 1С (оба справочника собственная разработка заказчика). Нужно, чтобы в реквизит «Договор» справочника 1С заносилась информация о Договоре из справочника Договоры не газовые 1С, которому соответствует запись справочника Договоры DIRECTUM. Если соответствующего договора в справочнике Договоры не газовые 1С нет, то нужно создать в этом справочнике запись и ссылку на неё поместить в реквизит «Договор» справочника Договоры 1С. Предполагается, что код договора DIRECTUM хранится в реквизите «Внешний ключ» справочника Договоры не газовые 1С. Более наглядно это видно на скриншоте:
Вычисление для реквизита «Договор» будет следующим:
IntegratedSystemCode = '1С81' //код системы 1с из справочника DIRECTUM
Environment = Object.Environment
V8AppIndex = Environment.IndexOfName('V8App') //проверяем наличие переменной окружения, созданной ранее коннектором
if V8AppIndex <> -1
V8App = Environment.Values(V8AppIndex)
else //если не нашли, то создадим
V8App = Connector1C81Get1C80Application(IntegratedSystemCode) //получаем 1С app
Environment.SetVar("V8App";V8App) //установить переменную окр. для использования в следующей итерации
endif
// Определим, есть ли такой договор в 1С
Code = '[Код]'
Dogovor = References.ДГВ.GetObjectByCode(Code)
// Найдем соответствующую запись в 1С
// Сформируем запрос к справочнику 1С
VQuery = V8AppTemp.NewObject("Query")
VQueryText = 'select C.Code from Справочник.ДоговорыНеГазовые as C where C.ВнешнийКлюч = "'&Trim(Dogovor.SYSREQ_CODE)&'"'
VQuery.Text = VQueryText
VQueryResult = VQuery.Execute
// Если такой договор есть, то получим его UUID
if not VQueryResult.IsEmpty
VQueryRecords = VQueryResult.Choose
VQueryRecords.Next
VRecordCode = V8AppTemp.XMLString(VQueryRecords.Get(0))
Record1C = V8AppTemp.Справочники.ДоговорыНеГазовые.НайтиПоКоду(VRecordCode)
UUID = Record1C.УникальныйИдентификатор()
Result = V8AppTemp.String(UUID)
else
// Если такого договора нет, то сформируем новый UUID
Result = "CHANGE_TO_UUID_" & Dogovor.SYSREQ_ID
endif
Вычисление:
Result = "CHANGE_TO_UUID_" & Dogovor.SYSREQ_ID
вернет нам сначала строку вида «CHANGE_TO_UUID_ID», которая затем будет преобразована в реальный UUID номер.
В результате в реквизит «Договор» справочника Договоры (1С) будет передано значение UUID записи справочника Договоры не газовые (1С), которому соответствует «Договор» (DIRECTUM), либо будет сформирован новый UUID, если такого договора еще нет.
В коде вычисляемых реквизитов мы можем также использовать прикладные функции и процедуры 1С, оформленные в модулях объектов. Т.е. вычисления нужных данных можно писать в базе 1С, а в коде вычисляемого реквизита просто вызвать готовую функцию с параметрами и получить результат её работы, например:
ЗначениеФункции = V8App.Справочники.Контрагенты.НашаФункция(Параметр)
Также нужно помнить, что при использовании подключения к 1С через вычисления или создание новой переменной окружения, приведет к использованию еще одной лицензии. Об этом не стоит забывать разрабатывая доработки к коннектору.
Приведенные выше примеры подключения для вытаскивания данных из 1С в вычисляемых реквизитах можно использовать и в обычных прикладных вычислениях DIRECTUM, например, в отчетах, в действиях справочников, в различных агентах и т.п.
Добрый день! Пишу загрузку сотрудников и подразделений из 1С в Директум. Руководствуясь вашей статьей пытаюсь загрузить из регистра 1С подразделение, привязанное к сотруднику. Получаю UUID подразделения (причем подразделение с таким UUID есть в xml), но в протокол пишется ошибка: "Не хватает данных для импорта объекта с ИД ........", где вместо многоточия UUID. Подскажите пожалуйста, в чем проблема?
Доброго времени суток.
В случае если есть вычисление, то в колонке "Заголовок реквизита системы" можно указать любой реквизит? Он уже не будет влиять на результат заполнения реквизита в DIRECTUM, так?
Можно указать любое имя и заголовок реквизита, но я "на всякий пожарный" даю наименования, которые бы не совпадали с именами уже существующих реквизитов в справочнике.
Ещё вопрос.
Делаю загрузку в DIRECTUM. Вставляю в реквизит простейшее вычисление (как в примере №1), нажимаю кнопку "Создать XSL", затем "Редакт. XSL". В открывшемся окне своего вычисления не вижу. Это нормально, он где-то в другом месте хранится?
P.S.
Результатов в справочнике DIRECTUM тоже не вижу :)
Удалось получить результат вычисления при выполнении следующих условий:
- В колонке "Вычисление" отображается значение "Есть";
- при выборе значения в колонке "Заголовок реквизита системы" выбирается тип реквизита - Вычисляемый;
- в открывшемся окне "Параметры реквизита" поле "Заголовок реквизита" может быть любым, а значение в поле "Имя реквизита" должно соответствовать значению в колонке "Заголовок реквизита DIRECTUM". Если в поле "Имя реквизита" указать имя другого реквизита, то оно и запишется. А вычисление реквизита в этом случае игнорируется...
Ещё вопрос по синхронизации справочников "Организации" в 1С и НОР в DIRECTUM. Поле Код не заполняется автоматом даже при установленной автоматической нумерации (ошибка - Одно или несколько обязательных полей не заполнено.). В него нужно обязательно что-то записывать. Выбрал ручную нумерацию. Обычный код из 1С записать нельзя, потому что к нумерации определённые требования.
Пытался сделать вычисление такое:
Но в результате добавляется только буква Д и код получается неуникальным.
Два вопроса:
1. Как правильно прибавить к коду 1С букву "Д" и таким образом получить уникальный код для НОРа?
2. Можно в этих вычислениях как нибудь вытащить значение счётчика (которое при добавлении записывается в поле "Организация")?
Спасибо.
А что мешает поле Код сделать ключевым реквизитом и синхронизировать в него Код 1С? Оно тогда автоматом будет заполняться. Или добавить в справочник НОР еще один реквизит Код1С и синхронизировать в него Код из 1С. Или синхронизировать НОР и Организации по наименованию?
В НОР всегда нормально реквизит Код заполнялся автоматически. По крайней мере у меня таких проблем никогда не было. Скорее всего вы что-то не так настроили.
Дмитрий, извините за глупый вопрос. Сам запутался и всех запутал.
Записи в НОР добавил руками и в новый реквизит проставил коды 1С. Изменения данных из 1С в DIRECTUM передаются исправно.
Ещё вопрос:
При синхронизации справочников события отрабатывают или коннектор их отключает?
Спасибо за развёрнутый ответ.
Теперь у меня проблемы с присвоением НОР в справочнике Подразделения. Пробовал записывать в Result код, ID и запись. В любом случае возвращает ошибку.
Привожу код. Текст ошибок приведён в качестве комментария.
Тип реквизита - вычисляемый. Заголовок и имя - НашаОрг.
Предполагаю, что должно быть так:
В XSL-шаблоне, если у реквизита НашаОрг стоит тип "Reference", то его надо удалить. Например, если было:
то должно стать:
Хех... теги не показывает. Продублирую:
Было:
Стало:
Странно... А если так:
Было:
Стало:
"Врагу не сдается наш гордый варяг!" ©
Было:
Стало:
Видимо бесполезно...
В XSL-шаблоне у вычисляемого реквизита надо удалить: Type="Reference"
Очередной интересный вопрос :)
В 1С структура подразделений в каждом НОРе 2-х уровневая: филиал и подразделения филиала (филиал - это подразделение НОР). Что бы импортировать эту структуру из 1С, сначала надо добавить все филиалы (верхний уровень), и только потом добавлять подразделения филиалов. Вижу следующие решения:
1. В настройки обмена данными два раза добавить справочник подразделений с разными фильтрами (сначала только филиалы, затем - подразделения);
2. Филиалы добавлять через коннектор, а для заполнения подразделений написать отдельный сценарий, который будет запускаться через диспетчер заданий windows;
Прокомментируйте, если не сложно. Может быть есть ещё какие-то варианты?
Спасибо.
Возникла проблема с нахождением филиала (головного подразделения).
Что делал:
Создал 2 записи в настройках обмена данными. Поставил фильтры соответствующие. Для филиалов на закладке "Доп.настройки" поставил "Главная настройка" - Да, для подчинённых поставил Нет.
Фильтры работают корректно - сначала филиалы, потом всё остальное.
За один запуск (по кнопке "Выполнить") добавляются ВСЕ записи, но при вычислении реквизита "Головное подразделение" филиалы не находятся. Когда нажимаешь кнопку 2-ой раз, то находятся филиалы. Изменял значение "Иерархический справочник" Да/Нет для обоих настроек, но не помогло.
Что нужно сделать чтобы добавление записей и присвоение головных подразделений прошло за один проход?
Вот код по присвоению головного подразделения:
Спасибо
Спасибо
При синхронизации с 1С возникла необходимость отключить обработку в некоторых событиях (не во всех) справочника. Попытался сделать через функции, но InteractiveMode() возвращает значение "true". А функция VarIsClear(Object.Form) возвращает "false". Как и при работе пользователя с формой...
Это нормально или я что-то не то делаю?
Спасибо.
Отключить обработку только одного события "СохранениеПосле" при синхронизации с 1С невозможно.
Функции InteractiveMode() возвращает значение "true", а функция VarIsClear(Object.Form) возвращает "false" в следующих случаях:
- сохранение документа из проводника;
- запуск синхронизации по кнопке "Выполнить" из карточки интегрированной системы;
- запуск синхронизации через сценарий "C:\Program Files (x86)\DIRECTUM Company\DIRECTUM 4.9.1\SBLauncher.exe" -SYS=DIRECTUM -CT=Script -F="LaunchIntegrationAction" -R="Action=ExportDataFromIntegratedSystem|AddParams=IntegratedSystemCode=DIR1С;Mode=Batch;DisableEvents=0;HiddenMode=-1"
Каким ещё образом можно отключить обработку события?
Спасибо.
Отключать все события пробовал, с другими справочниками проблемы начинаются :(
Пришла идея создать отдельную интегрированную систему в DIRECTUM (и отдельный план обмена в 1С) только для одного справочника. Он всё равно по логике синхронизации будет грузится в последнюю очередь. Сначала основной сценарий выполнится со всеми справочниками, затем 2-ой только для этого справочника. Технических препятствий пока не вижу. Со стороны DIRECTUM такой вариант никаких осложнений не вызовет?
Имелось ввиду,что для 2-го сценария отключить обработку событий через параметр.
Добрый день!
Синхронизирую справочники "Физические лица"(1С) и Персоны (Директум).
Делаю вычисляемые реквизиты, где для кажого реквизиты указываю вычисление
Для фамилии:
FIO = '[Description]'
Result = SubString(FIO;' ';1)
Настройка реквизита:
Заголовок Реквизита - Фамилия
Значение реквизита - Result
Для имени
FIO = '[Description]'
Result = SubString(FIO;' ';2)
Настройка реквизита:
Заголовок Реквизита - Имя
Значение реквизита - Result
Для отчества
FIO = '[Description]'
Result = SubString(FIO;' ';3)
Настройка реквизита:
Заголовок Реквизита - Отчество
Значение реквизита - Result
Подскажите пжст почему при загрузке справочника в директум, поле Фамилия загружается правильно, а поля Имя и Отчество, содержат значение поля Фамилия.....
Что я не так указываю?
Не совсем понял такую настройку.
Если мне не изменяет память, то для вычисляемых реквизитов в настройках указывается Заголовок реквизита и Имя реквизита. Кроме того, Result - предопределенная переменная и использовать ее в качестве Имени реквизита нельзя (если я правильно понял где вы данное значение указывали). Для решения проблемы в качестве имени реквизита, для каждой из настроек вместо Result, укажите другие значения, например, Фамилия, Имя, Отчество соотвественно. Ну и в заключение, если вы используете такие вычисления, то у вас в Description должно быть ФИО разделенное одним пробелом.
Description Разделено одним пробелом.
Скрин
Тут основная проблема вот в этой настройке:
Я не знаю где вы ее взяли и что имели в виду.
Судя по скрину вы неправильно указываете Имя реквизита. Для простоты, продублируйте в него содержимое поля Заголовок реквизита.
Авторизуйтесь, чтобы написать комментарий