1с как конвертировать объект неопределенное типа
Перейти к содержимому

1с как конвертировать объект неопределенное типа

  • автор:

1с как конвертировать объект неопределенное типа

Ситуация такая — имеется неопределенный реквизит в таб части — его нужно првести в каждом конкретном случае к реквизиту того типа который есть в шапке документа на основании которого делается данный документ

тип реквизита документа заранее не известен:

Для Индекс = 1 По Метаданные.Документ(ДокументОснование.Вид()).РеквизитШапки() Цикл
Если (Метаданные.Документ(ДокументОснование.Вид()).РеквизитШапки(Индекс).Идентификатор <> СокрЛП(«ДокОснование»)) Тогда
НоваяСтрока();
ИмяРек = Метаданные.Документ(ДокументОснование.Вид()).РеквизитШапки(Индекс).Идентификатор;
ТЗнч = ТипЗначенияСтр(ДокументОснование.ПолучитьАтрибут(Метаданные.Документ(ДокументОснование.Вид()).РеквизитШапки(Индекс).Идентификатор));
Форма.старый.НазначитьТип(ТЗнч,,);
старый = ДокументОснование.ПолучитьАтрибут(Метаданные.Документ(ДокументОснование.Вид()).РеквизитШапки(Индекс).Идентификатор);
КонецЕсли;
КонецЦикла;

старый — и есть тот самый реквизит
Код не ругается но и не работает. Реквизит может быть каким угодно — число, ссылка на документ, ссылка на справочник что угодно
Как это сделать правильно. Критерий — должно выводиться значение реквизита в таб чась — оно не выводится

Если использовал ТипЗначение — тож не работало — мало того толком не вывоил его даже в строку сообщений — только цифры.
Если ТипЗначениеСтр — выводит с точностью до Документ — какой документ не выводит
Версия 7.7

. Форма.старый.НазначитьТип(ТЗнч,,);
Мне кажется, что Форма. здесь лишние.

возможно что так. Убрал слово форма — ругается
старый.НазначитьТип(ТЗнч,,);
: Значение не представляет агрегатный объект (НазначитьТип)

старый.УстановитьАтрибут(ДокументОснование.ПолучитьАтрибут(Метаданные.Документ(ДокументОснование.Вид()).РеквизитШапки(Индекс).Идентификатор));
тоже не работает. — также ругается
Старый как и ИмяРек — реквизиты таб части текущего документа
Но ИмяРек — строка а старый — неопределенный. В имяРек имя реквизита таб части пишется влет
Что делаю не так?

Преобразование типов в 1С

Разберем основные вопросы преобразования типов в 1С 8.3: из строки в число, из числа в строку, из даты в число и прочие варианты. В этой статье мы рассмотрим функции преобразования значений, и я соберу в едино все варианты преобразования примитивных типов.

Строка в число в 1С

Узнаем, как в 1С 8.3 преобразовать строку в число.

Пусть, у нас есть числа в таком виде.

СтрокаЧ1 = "120"; СтрокаЧ2 = "12.24"; СтрокаЧ3 = "12,24"; СтрокаЧ4 = "0,24"; СтрокаЧ5 = "0000001"; 

Для того, чтобы выполнить преобразование этих строк в число, необходимо воспользоваться методом Число. Этот метод преобразует параметр в число.

Ч1 = Число(СтрокаЧ1); Ч2 = Число(СтрокаЧ2); Ч3 = Число(СтрокаЧ3); Ч4 = Число(СтрокаЧ4); Ч5 = Число(СтрокаЧ5); 

Обратите внимание, что разделять дробную часть можно в строке как при помощи символа точка «.», так и при помощи символа запятая «,». Если перед каким-то числом в строке стоят нули, то они отсекаются. У нас будет следующий результат.

Строка в число в 1С

Число в строку в 1С

Рассмотрим обратную задачу, когда в 1С 8.3 нужно преобразовать число в строку. Самый простой вариант использовать метод Строка, который преобразует собственный параметр в строку.

Ч1 = 120; Ч2 = 12.24; Ч3 = 10000000000; СтрокаЧ1 = Строка(Ч1); СтрокаЧ2 = Строка(Ч2); СтрокаЧ3 = Строка(Ч3); Сообщить(СтрокаЧ1); Сообщить(СтрокаЧ2); Сообщить(СтрокаЧ3); 

И какой результат возвращает этот код:

Число в строку в 1С

У этого способа имеется недостаток: он ставит пробелы между разрядами у длинных чисел. Для того, чтобы в 1С преобразовать число в строку без пробелов нужно воспользоваться функцией Формат. Данная функция имеет два параметра: преобразуемое значение и форматную строку. Если нам нужно указать, что число преобразуется в строку без пробелов в разряде, то необходимо указать в форматной строке, что порядок разделения группировки разрядов числа или равен 0, или пустой.

Ч1 = 10000000000; СтрокаЧ1 = Формат(Ч1,"ЧГ color: red;">); Сообщить(СтрокаЧ1); 

Результат будет без разрядов:

число в строку без пробелов 1C

Строка в дату 1С

Узнаем, как преобразовать в 1С 8.3 строку в дату. Для этого необходимо использовать метод Дата, который преобразует параметр (в том числе строку ) в дату . Причем, замечу, что строка должна быть задана в таком формате «ГГГГММДДЧЧММСС».

Подробнее о форматах дат читайте в этой статье: даты в 1С.

СтрокаД1 = "20120910"; СтрокаД2 = "20120910121559"; СтрокаД3 = "00010101121559"; Дата1 = Дата(СтрокаД1); Дата2 = Дата(СтрокаД2); Дата3 = Дата(СтрокаД3); 

Строка в дату в 1С

Если мы зададим дату в не верном формате, то преобразование не произойдет и возникнет ошибка «Преобразование значения к типу Дата не может быть выполнено».

Например, этот код:

СтрокаД1 = "121559"; Дата1 = Дата(СтрокаД1) 

Приведет к ошибке:

Преобразование значения к типу Дата не может быть выполнено

Дата в строку в 1С

Преобразовать дату в строку можно несколькими способами. Первый способ: воспользоваться уже знакомым нам методом Строка.

Дата1 = Дата(2012,10,12); СтрокаД = Строка(Дата1); Сообщить(СтрокаД); 

В этом случае у нас выйдет строка в обычном «полном» формате даты.

Дата в строку в 1С

А чтобы получить дату в том формате, в каком нам нужно, необходимо воспользоваться методом Формат.

Форматов дат может быть великое множество ,все я разбирать в этой статье не буду, покажу только как можно быстро воспользоваться этой функцией.

Мы изменим предыдущий код, написав вместо метода Строка метод Формат, а в качестве второго параметра у метода Формат напишем просто две кавычки.

Дата1 = Дата(2012,10,12); СтрокаД = Формат(Дата1,""); Сообщить(СтрокаД); 

После нужно между кавычками поставить курсор, вызвать контекстное меню, и применить в нем команду Конструктор форматной строки.

Конструктор форматной строки

В этом конструкторе на закладке Дата вы можете выбрать удобный вам формат даты.

Конструктор форматной строки

И после нажатия кнопки ОК этого конструктора, нужный формат появится в виде строки.

Дата1 = Дата(2012,10,12); СтрокаД = Формат(Дата1,"ДФ=dd/MM/yy"); Сообщить(СтрокаД); 

В результате метода Формат, дата будет преобразована в строку в том виде, в каком нам необходимо.

Дата в строку в 1С

Строка в булево в 1С

При помощи метода Булево мы можем некоторые строковые представления (Да, Нет, Истина, Ложь) преобразовывать в значения Истина или Ложь.

Например, следующие переменные:

стр_Да = Булево("Да"); стр_Нет = Булево("Нет"); стр_Истина = Булево("Истина"); стр_Ложь = Булево("Ложь"); 

Будут иметь такие значения:

Строка в булево

Булево в строку в 1С

Разберем, как в 1С можно выразить тип булево строкой. Булево значение можно преобразовать в строку несколькими способами. Во-первых, можно просто воспользоваться методом Строка.

Например, как здесь:

б_Истина = Истина; б_Ложь = Ложь; СтрИстина = Строка(б_Истина); СтрЛожь = Строка(б_Ложь); Сообщить(СтрИстина); Сообщить(СтрЛожь); 

У нас будет выходить следующий результат:

Булево в строку

В этом случае, булево в строку преобразовалось согласно региональным установкам информационной базы.

Если мы, как-то по-другому хотим преобразовать булево в строку, то можно воспользоваться уже знакомым нам методом Формат.

Переделаем, предыдущий код:

б_Истина = Истина; б_Ложь = Ложь; СтрИстина = Формат(б_Истина,""); СтрЛожь = Формат(б_Ложь,""); 

Знакомым способом вызовем конструктор форматной строки, где на закладке Булево введем преставление значений Истина и Ложь.

Конструктор форматной строки Булево

После нажатия кнопки ОК конструктора, второй параметр метода Формат заполнится:

б_Истина = Истина; б_Ложь = Ложь; СтрИстина = Формат(б_Истина,"БЛ='Ни как нет'; БИ=Конечно"); СтрЛожь = Формат(б_Ложь,"БЛ='Ни как нет'; БИ=Конечно"); Сообщить(СтрИстина); Сообщить(СтрЛожь); 

И будет следующий результат:

Булево в строку

Число в булево в 1С

В 1С 8.3. мы можем преобразовать любое число в булево по следующему правилу: 0 будет преобразован в Ложь, все остальные значения в Истина.

б_Ложь = Булево(0); б_Истина = Булево(100000); 

Будет следующий результат:

Число в булево в 1С

Булево в число в 1С

Можно сделать и обратное преобразование. Булево значение в число.

Для этого нужно воспользоваться методом Число, где в качестве параметра указать булево значение. Тогда Истина будет преобразована в 1С, а Ложь – в 0.

Например, как в этом коде:

б_Истина = Истина; б_Ложь = Ложь; ч_Истина = Число(б_Истина); ч_Ложь = Число(б_Ложь); 

С таким результатом:

Булево в число

Статьи о примитивных типах в 1С:

Более подробно и основательно начальные вопросы программирования в 1С есть вы можете изучить в
Книга «Программировать в 1С за 11 шагов»

Изучайте программирование в 1С в месте с моей книгой «Программировать в 1С за 11 шагов»

Программировать в 1С за 11 шагов

Книга написана понятным и простым языком — для новичка.

  1. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  2. Научитесь понимать архитектуру 1С;
  3. Станете писать код на языке 1С;
  4. Освоите основные приемы программирования;
  5. Закрепите полученные знания при помощи задачника.

О том как разрабатывать под управляемым приложением 1С, читайте в книге Книга «Основы разработки в 1С: Такси»

Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.

Основы разработки в 1С такси

  1. Очень доступный и понятный язык изложения
  2. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  3. Поймете идеологию управляемого приложения 1С
  4. Узнаете, как разрабатывать управляемое приложение;
  5. Научитесь разрабатывать управляемые формы 1С;
  6. Сможете работать с основными и нужными элементами управляемых форм
  7. Программирование под управляемым приложением станет понятным

Промо-код на скидку в 15% — 48PVXHeYu

Эти книги, плюс книга по программированию оперативного учета имеются в едином комплекте: комплект книг по разработке в 1С.
Только для читателей моего блога,
промо-код на скидку в 300 рублей на весь комплект: blog


Если Вам понравился этот урок, был полезен или помог решить какую-нибудь проблему, то Вы можете поддержать мой проект, перечислив любую сумму
.

можно оплатить вручную:

Яндекс.Деньги — 410012882996301
Web Money — R955262494655

Вступайте в мои группы:

Зачем надо отказываться от модальности

1С:Предприятие использует модальные окна в тех ситуациях, когда от пользователя требуется ввод информации, без которой невозможно дальнейшее выполнение алгоритма. При этом полностью блокируется весь остальной интерфейс программы, а исполнение программного кода останавливается до тех пор, пока пользователь не закроет модальное окно. С появлением веб-клиента и с переходом 1С:Предприятия на мобильные платформы, модальные окна оказались источником большого количества неудобств и проблем, зачастую неразрешимых.

Как правило «десктопные» браузеры лучше или хуже, но поддерживают модальные окна и открывают их в новом окне браузера как «всплывающее окно». Но из-за того, что технология всплывающих окон массово используется в Интернете для размещения рекламы, практически во всех браузерах стандартно отключен показ всплывающих окон. В подавляющем большинстве случаев без изменения этой настройки браузера работа веб-клиента становится невозможной.

Другая проблема заключается в том, что мобильные браузеры вообще не поддерживают модальные окна.

В такой ситуации вариант работы интерфейса 1С:Предприятия без использования модальных окон снимает все перечисленные выше проблемы. При этом не происходит отказа от функциональности, которая обеспечивалась ранее модальными окнами. Но эта функциональность реализуется другими технологиями, которые не препятствуют работе 1С:Предприятия в браузерах. В новом режиме работы интерфейса окно, которое раньше было бы модальным, рисуется в пределах родительского окна, и точно так же блокирует весь остальной интерфейс веб-клиента. В результате:

  • Не происходит открытия новых окон браузера, что повышает производительность и стабильность веб-клиента;
  • Во многих случаях дополнительная настройка браузера становится ненужной, так как 1С:Предприятие больше не использует всплывающие окна;
  • Любая конфигурация, используя веб-клиент, может работать на iPad.

Когда надо отказываться от модальности

Не нужно «бросать всё» и начинать отказываться от модальности. Есть несколько случаев, когда можно продолжать работать в модальном режиме.

Во-первых, не любая версия технологической платформы поддерживает режим работы интерфейса без использования модальности. Этот режим работы существует, начиная с версии 8.3.3.721 (06.09.2013). Поэтому, если вы работаете на младших версиях платформы, можете пока не озадачиваться отказом от модальности.

Во-вторых, не все прикладные решения в обязательном порядке должны использовать этот режим. Критичными являются приложения, работа с которыми будет вестись:

  • На iPad;
  • В режиме сервиса (например, они будут размещаться на 1cfresh.com);
  • С помощью веб-клиента.

Если ваше прикладное решение заведомо не будет использоваться в этих режимах, вы можете пока не отказываться от модальности.

Однако все типовые решения 1С разрабатывает исходя из того, что они могут использоваться любым из доступных способов. Поэтому в них основным режимом работы интерфейса является режим без использования модальности. В этом режиме будут работать новые прикладные решения. На этот режим будут переводиться старые прикладные решения. А значит, этот режим работы вам лучше начать осваивать уже сейчас. Даже если ваше приложение пока может его не использовать, мы рекомендуем, по возможности, начать перевод уже сейчас. Потому что в будущем этот режим работы будет единственным.

Сравнение модального и немодального режимов работы

Следует сказать, что отказ от модальности — это вещь не простая. Она является существенным поворотом в сторону асинхронной модели работы клиентского приложения. Не все сценарии, использующие на данный момент модальные окна, могут быть легко переведены на использование блокирующих окон.

Существенное количество сценариев работы может потребовать не просто замены одних методов встроенного языка другими, а изменения самого подхода к проектированию юзабилити интерфейса прикладного решения. Проще говоря, прежде чем пытаться переделать модальный диалог, стоит подумать, а можно ли здесь вообще обойтись без него?

Подробнее об этом мы поговорим позже, а для начала разберемся, в чём же заключаются принципиальные отличия этих двух режимов работы интерфейса. Понять разницу модального и немодального режимов работы проще всего на небольшом примере. Старая процедура, открывавшая модальное окно и обрабатывавшая полученные им данные, могла выглядеть так:

Метод Вопрос() открывает модальное окно. В момент исполнения этого метода дальнейшее исполнение программного кода останавливается, модальное окно блокирует весь интерфейс и ожидает реакции пользователя.

После того, как пользователь нажимает одну из кнопок, например «Да» , исполнение кода продолжается, а модальное окно исчезает и пользователю снова становится доступен весь интерфейс:

В этом примере выводятся два тестовых сообщения и на картинке видно, что оба сообщения появляются на экране только после того, как модальное окно исчезнет.

Таким образом можно сказать, что старый режим работы обеспечивает модальность как для разработчика (останавливается исполнение кода), так и для пользователя (блокируется интерфейс, доступно только модальное окно).

Новый режим работы интерфейса обеспечивает модальность лишь для пользователя. Для разработчика, в момент отображения блокирующего окна, исполнение программного кода не останавливается. Чтобы увидеть это рассмотрим не совсем корректный пример:

Метод ПоказатьВопрос() открывает блокирующее окно. В момент исполнения этого метода блокирующее окно заблокирует интерфейс, и он будет ожидать реакции пользователя. Однако исполнение программного кода на этом не остановится, и будут выполнены все операторы, следующие за методом ПоказатьВопрос() . В данном случае будет выведено сообщение.

После того, как пользователь нажмёт одну из кнопок, например «Да» , начнётся исполнение другой процедуры. Той, которая была назначена в качестве обработчика оповещения при вызове метода ПоказатьВопрос() :

В этом примере мы специально допустили ошибку. Но благодаря ей мы можем увидеть обе важные особенности.

Во-первых, алгоритм, который раньше являлся одним целым, теперь нужно разделять на две части. Одна часть открывает блокирующее окно. Вторая часть обрабатывает реакцию пользователя в блокирующем окне. Чтобы система знала, с какого места продолжать исполнение программного кода, блокирующему окну передаётся имя процедуры, которая должна быть выполнена тогда, когда пользователь закроет это окно.

Во-вторых, после оператора, открывающего блокирующее окно, не должно содержаться исполняемого кода. Иначе этот код будет выполнен, не дожидаясь реакции пользователя.

Поэтому правильным решением является перенос всего кода в процедуру, исполняемую после закрытия блокирующего окна:

Тут нужно оговориться, и мы это видели на примере, что нет запрета на то, чтобы после оператора, открывающего блокирующее окно, содержался какой-либо исполняемый код. Но вы должны понимать, что платформа выполнит этот код без остановки. Независимо от того, что введёт пользователь в блокирующем окне, или когда он это окно закроет. Если такое поведение не противоречит логике вашего прикладного решения, то пожалуйста, можно использовать этот вариант.

Механизмы платформы для отказа от модальности

Этот раздел носит, скорее, «энциклопедический» характер. Он будет полезен тем, кто хочет в полной мере познакомиться со всеми механизмами платформы, которые появились для обеспечения немодального режима работы.

Если же вам не терпится приступить к «активным действиям», то вы можете перейти сразу к одному из следующих разделов:

  • Как писать новые конфигурации — для тех, кто сразу хочет создавать конфигурацию, работающую в режиме без использования модальности;
  • Как переделывать старые конфигурации — для тех, кто хочет перевести имеющуюся конфигурацию в режим работы без использования модальности.

Итак, возвращаясь к механизмам платформы нужно сказать, что по большому счёту они делятся на две большие группы. Механизмы, которые обеспечивают работу в немодальном режиме и механизмы, помогающие перейти в этот режим. Основная часть этих механизмов появилась в платформе начиная с версии 8.3.3.721 (06.09.2013), а в версии 8.3.5 в неё были добавлены инструменты рефакторинга, облегчающие преобразование имеющихся конфигураций. Перечислим все эти механизмы по-порядку.

Новый режим интерфейса

У конфигурации появилось новое свойство — » Режим использования модальности» . Именно оно и определяет, в каком режиме работает конфигурация:

  • «Не использовать» — это новый, немодальный режим работы. Для новых конфигураций это стандартный режим;
  • «Использовать с предупреждением» — этот режим предназначен для разработчика. Он не препятствует использованию модальных окон, но каждый раз, когда открывается модальное окно, выдаёт предупреждающее сообщение. Пример использования этого режима есть в разделе Поиск модальных методов — В режиме 1С:Предприятие;
  • » Использовать» — режим, обеспечивающий совместимость новой версии платформы со старыми конфигурациями, работающими в модальном режиме.

Новый режим открытия окна формы

У свойства формы РежимОткрытияОкна появилось новое значение — БлокироватьВесьИнтерфейс . Именно это значение теперь следует использовать для того, чтобы из всего интерфейса пользователю была бы доступна только одна открытая форма. Пример использования этого свойства есть в разделе Как открыть произвольную форму в блокирующем режиме.

Немодальные аналоги модальных методов

Некоторые методы встроенного языка открывают модальные окна. Для этих методов в платформе были созданы «методы-дублёры», которые обладают той же функциональностью, но используют блокирующие окна. Например, старый метод Вопрос() и новый «метод-дублёр» ПоказатьВопрос() . Полный список этих методов можно посмотреть в документации Руководство разработчика, Приложение 13. Соответствие синхронных методов асинхронным аналогам.

Кроме документации метод-дублёр можно посмотреть и в синтакс-помощнике. Для каждого старого метода они указаны.

Пример использования этих методов есть, например, в разделе Вопрос в модуле команды, формы или в общем модуле.

Новый синтаксис метода ОткрытьФорму()

Для того чтобы открывать форму в блокирующем режиме, метод-дублёр создавать не стали. Потому что уже и так существовало два метода: ОткрытьФормуМодально() и ОткрытьФорму() . Поэтому в привычный метод ОткрытьФорму() добавили несколько новых параметров: ОписаниеОповещенияОЗакрытии и РежимОткрытияОкна .

Они позволяют сразу передать форме нужное описание оповещения и указать новый режим открытия окна. Пример можно посмотреть в разделе Как поступить, если форму нужно открывать то в обычном, то в блокирующем режиме.

Объект встроенного языка ОписаниеОповещения

Назначение этого объекта — указать точку конфигурации, с которой должно быть продолжено исполнение кода после того, как пользователь закроет блокирующее окно. Этот объект содержит имя экспортируемой процедуры, которая начнёт выполняться, а также указание на модуль, в котором находится эта процедура.

Если процедура находится в том же модуле, в котором создаётся описание оповещения, то для указания на этот модуль используется значение ЭтотОбъект . Это новое свойство, реализованное для управляемой формы, команды командного интерфейса и общего модуля. Именно в этих модулях может находиться процедура обработки оповещения. Пример есть в разделе Вопрос в модуле команды, формы или в общем модуле.

Иногда возникает необходимость разместить обработчик оповещения не в том модуле, в котором создаётся описание оповещения, а в другом, например, в общем модуле. В таком случае вместо ЭтотОбъект можно указать имя общего модуля. Пример можно посмотреть в разделе Вопрос в модуле управляемого приложения.

Кроме этих параметров описание оповещения может содержать структуру с произвольными данными. Передача этих данных в обработчик оповещения может понадобиться для того, чтобы алгоритм, выполняемый после реакции пользователя, мог использовать значения, вычисленные перед открытием блокирующего окна. Такой пример можно посмотреть в разделе Как передать дополнительную информацию в форму, открываемую в блокирующем режиме.

Свойство формы ОписаниеОповещенияОЗакрытии

У формы появилось новое свойство — ОписаниеОповещенияОЗакрытии . В него передаётся то описание оповещения, которое мы указываем в методе ОткрытьФорму() . После закрытия формы исполнение кода продолжается с процедуры, указанной в этом описании оповещения.

Метод ВыполнитьОбработкуОповещения()

Этот метод используется для того, чтобы выполнить процедуру обработчика оповещения. Чтобы указать на этот обработчик, в метод передаётся описание оповещения.

Этот метод требуется в сложных «многоуровневых» алгоритмах асинхронных вызовов, т.к. описание оповещения может быть сконструировано в начале алгоритма, а реальное использование этого обработчика может понадобиться через несколько вложенных процедур. Такой пример можно посмотреть в разделе Вопрос во вложенной процедуре, после которой есть код.

Поиск модальных методов в режиме расширенной проверки конфигурации

В механизме проверки конфигурации реализован новый режим расширенной проверки «Поиск использования модальности» . Он позволяет найти те фрагменты кода, которые приводят к открытию модальных окон. Пример можно посмотреть в разделе Проверка конфигурации в режиме Конфигуратор.

Из командной строки эта проверка выполняется с помощью параметра -CheckUseModality ключа командной строки запуска ExtendedModulesCheck .

Инструменты для полуавтоматического перевода конфигураций в режим без использования модальности

Эти инструменты реализованы в платформе начиная с версии 8.3.5. Они собраны в меню «Конфигурация — Рефакторинг» и » Текст — Рефакторинг — Модальные вызовы» . С помощью этих инструментов можно частично автоматически, а частично с применением «ручного труда» перевести существующую конфигурацию в немодальный режим работы. Примеры использования этих инструментов можно посмотреть в разделах Автоматическое преобразование модальных методов и Ручное преобразование конструкций, которые невозможно преобразовать автоматически.

Как писать новые конфигурации

Общие замечания

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

Во-первых, о свойствах самой конфигурации беспокоиться не надо. Режим без использования модальности является стандартным для новых конфигураций. Поэтому после создания новой информационной базы с пустой конфигурацией её свойство «Режим использования модальности» будет установлено в значение «Не использовать» .

Во-вторых, прежде чем использовать блокирующие окна, или методы, открывающие диалоги в блокирующем режиме, следует подумать, есть ли в них необходимость. Если логика работы позволяет обойтись без блокирующего диалога — лучше не использовать его. Более того, в целом ряде случаев ради этого полезно изменить алгоритм или какие-то интерфейсные решения. Потому что это может быть проще, понятнее и надёжнее, чем пытаться реализовать «именно такой» сценарий работы в асинхронной модели работы интерфейса.

Как мы уже говорили ранее, не все сценарии работы могут быть легко и просто переведены на использование блокирующих диалогов. Если нельзя отказаться от использования блокирующих диалогов, то в новых конфигурациях имеет смысл заранее продумывать разделение кода, требующего действий пользователя, и кода, реализующего прикладную логику. И стараться их не смешивать. Например, сначала выполнить все интерактивные действия, «пообщаться» с пользователем, а после этого выполнить прикладной алгоритм «без вопросов».

В-третьих, если вы всё же решили использовать блокирующие диалоги, то вместо старых, модальных методов, следует использовать их новые немодальные аналоги. Обычно (но не всегда) немодальные аналоги начинаются со слова «Показать». В синтакс-помощнике для каждого старого модального метода указан его блокирующий аналог. А полный список соответствия всех методов можно посмотреть в документации.

В-четвёртых, чтобы открыть форму в блокирующем режиме вместо метода ОткрытьФормуМодально() нужно использовать метод ОткрытьФорму() , но с новым синтаксисом. Новый синтаксис позволяет указать ОписаниеОповещения и режим открытия окна.

В-пятых, если форма всегда будет открываться только в блокирующем режиме, в конфигураторе нужно установить её свойство РежимОткрытияОкна в значение «Блокировать весь интерфейс «.

Здесь надо сделать следующее замечание. Используя » Блокировать весь интерфейс » мы полностью моделируем для пользователя старое, модальное поведение. Но дело в том, что модальные окна, являясь элементами синхронной (блокирующей) модели, не очень хорошо сочетаются с природой веб-приложений, которые в большинстве своём построены на асинхронной модели. То есть веб-приложения не блокируют действия пользователя, если на это нет совсем крайней необходимости.

Поэтому если мы хотим, а мы хотим, двигаться в сторону веб-приложений, то вместо «Блокировать весь интерфейс» лучше использовать » Блокировать окно владельца» . Тогда окно владельца будет заблокировано, но остальной интерфейс прикладного решения для пользователя будет доступен.

В некоторых сценариях это может быть полезно. Например для того, чтобы выполнить действия, препятствующие дальнейшей работе длительной обработки. Через 30 минут её работы выяснилось, что не все нужные документы проведены. Тогда пользователь может провести документы, а потом вернуться к прерванной обработке. Не запуская её с самого начала.

В некоторых ситуациях это может быть вредно. Потому что пользователь может «потерять фокус», начать «гулять» по интерфейсу, зайти далеко и потом долго искать ту форму, на которой был задан вопрос.

Однозначно хорошего совета тут дать нельзя. Но все же, прежде чем использовать » Блокировать весь интерфейс» в каждом конкретном случае желательно проанализировать возможность использования значения «Блокировать окно владельца» . Потому что оно больше подходит к формату веб-приложений.

В-шестых, так как указывать ОписаниеОповещения нужно во всех методах, использующих блокирующие окна, в конфигураторе есть возможность автоматизировать эту работу (начиная с версии 8.3.5). Достаточно написать имя метода и открывающую скобку. А после этого из контекстного меню вызвать команду «Рефакторинг — Создать обработку оповещения» :

В результате платформа создаст конструктор и процедуру, обрабатывающую оповещение:

Типичные примеры

Далее мы разберём несколько типичных примеров использования немодальных вызовов. Эти примеры помогут вам разобраться в новых подходах к написанию кода и построению алгоритмов.

Вопрос в модуле команды, формы или в общем модуле

Суть этого примера заключается в том, что мы используем немодальный метод-дублёр, в который передаём описание оповещения. А всю логику, которая должна обрабатывать ответ пользователя, помещаем в отдельную экспортируемую процедуру в этом же модуле. Именно на эту процедуру и указывает описание оповещения.

Вопрос в модуле управляемого приложения

Особенность этого примера заключается в том, что нет возможности сослаться на модуль приложения с помощью свойства ЭтотОбъект . Поэтому процедуру, обрабатывающую оповещение, нужно располагать, например, в неглобальном клиентском общем модуле. В конструкторе описания оповещения на такой модуль можно сослаться, просто указав его имя:

Этот же приём нужно использовать, если вы находитесь в глобальном общем модуле.

По поводу модуля управляемого приложения нужно сделать ещё одно замечание. Возможно, вы захотите организовать немодальный диалог с пользователем в обработчике ПередНачаломРаботыСистемы . Так, чтобы до момента ответа пользователя не открывалось главное окно приложения. К сожалению, на момент написания статьи, такой возможности нет. И в этом случае вам придётся выбрать другую логику работы прикладного решения.

Другой сценарий, который является крайне нежелательным — это немодальный диалог в обработчике ПередЗавершениемРаботыСистемы . Во-первых потому, что в условиях веб-клиента браузеры очень негативно относятся к показу каких-либо сообщений при закрытии приложений и блокируют их. Во-вторых потому, что наличие такого диалога не позволит реализовать некоторые сценарии работы.

Например, в конфигурации есть форма, перед закрытием которой также задаётся вопрос пользователю в немодальном диалоге. Допустим, пользователь модифицировал данные в этой форме и, не сохраняя их, пытается закрыть всё приложение. В результате он ответит что-то в диалоге перед закрытием формы, форма закроется, но приложение останется открытым. Так происходит потому, что в немодальном диалоге перед закрытием формы сначала отменяется стандартная последовательность действий системы (см. пример). А это, в том числе, отменяет и закрытие самого приложения.

Как открыть произвольную форму в блокирующем режиме

Если у вас есть форма, которую вы всегда хотите открывать только в блокирующем режиме, можно сразу, в конфигураторе, установить её свойство РежимОткрытияОкна в значение «Блокировать весь интерфейс» . А затем открывать её прежним методом ОткрытьФорму() , передавая в него описание оповещения:

Как поступить, если форму нужно открывать то в обычном, то в блокирующем режиме

В этом случае в конфигураторе свойство формы РежимОткрытияОкна лучше оставить в стандартном значении «Независимый» . А при открытии формы в явном виде указывать нужный режим открытия окна прямо в методе ОткрытьФорму() :

Как передать дополнительную информацию в форму, открываемую в блокирующем режиме

Может так случиться, что до вызова блокирующего окна у вас накопились какие-то значения, которые должны быть использованы после того, как пользователь ответит на вопрос или закроет блокирующую форму. Как передать их в процедуру, обрабатывающую оповещение?

Для этого у объекта ОписаниеОповещения существует третий параметр в конструкторе, в который можно передать структуру, содержащую значения, необходимые в дальнейшем:

Вопрос во вложенной процедуре, после которой нет кода

Рассмотрим ситуацию, когда блокирующий вызов хочется написать во вложенной процедуре. Например, так:

В этом случае достаточно будет вместо одной вложенной процедуры написать две процедуры, использующие блокирующий метод ПоказатьВопрос() :

Вопрос во вложенной процедуре, после которой есть код

Рассмотрим более сложный случай, когда после вызова вложенной функции выполнятся некоторый код. Например, так:

Казалось бы, следуя рекомендациям, надо просто заменить вложенную процедуру двумя процедурами:

Однако в этом случае алгоритм, следующий за вызовом вложенной процедуры, будет выполнен ещё до того, как пользователь ответит на вопрос. Ведь, как мы знаем, исполнение кода не останавливается после выполнения блокирующего метода (Сравнение модального и немодального режимов работы):

Поэтому в такой ситуации нужно не только использовать блокирующий метод с вызовом оповещения, но ещё и выполнять асинхронный вызов самой вложенной процедуры, также используя оповещение:

Здесь во вложенную процедуру мы сразу передаём описание оповещения, в котором содержится тот код, который должен быть выполнен после вложенной процедуры (последняя процедура). Вызывая блокирующий метод, мы передаём ему «его» описание оповещения ( ВложеннаяПроцедураЗавершение ), а также, через дополнительные параметры, то описание оповещения, которое нужно будет выполнить после того, как будут обработаны интерактивные действия пользователя ( ОбработкаКомандыЗавершение ).

Если сразу осознать такую конструкцию сложно, можно писать «по старому», а затем использовать функции рефакторинга. Они доступны начиная с версии 8.3.5. Как это делается можно посмотреть в примере Необходимо преобразование в асинхронную процедуру.

Вопрос в обработчике формы ПередЗакрытием

Особенность диалога с пользователем в этом (и многих других) обработчиках заключается в том, что в зависимости от реакции пользователя принимается решение: продолжать дальнейшие действия, или отказаться от них. Для этого используется параметр процедуры Отказ . При одном ответе пользователя мы отказываемся от продолжения ( Отказ = Истина ). При другом ответе пользователя — продолжаем дальнейшие действия.

В данном случае сложность заключается в том, что ответ пользователя мы узнаем уже после того, как выйдем из контекста этого обработчика. В процедуре, обрабатывающей оповещение. А параметр Отказ нужно установить именно в этом обработчике.

Поэтому мы действуем в два приёма:

  • В первый раз безусловно отменяем дальнейшие действия ( Отказ = Истина ) и выводим вопрос пользователю;
  • В обработчике оповещения, в зависимости от реакции пользователя, либо снова программно закрываем форму, либо ничего не делаем.

Проблема заключается в том, что обработчик ПередЗакрытием будет выполнен два раза. И чтобы отличить первое его выполнение от второго (когда ответ пользователя уже известен) мы используем клиентскую переменную ВыполняетсяЗакрытие в качестве флага.

В первый проход её значение равно Ложь , и это значит, что нужно отказаться от закрытия и задать вопрос. Во второй проход её значение равно Истина , и это значит, что вопрос задавать не надо:

Вопрос в обработчике формы ПередЗаписью

В обработчике события формы ПередЗаписью также может возникнуть потребность задать вопрос. Как и в предыдущем примере. Однако здесь вопрос так просто не решается. Отличие заключается в следующем.

В предыдущем примере, оказываясь в обработчике ПередЗакрытием , мы однозначно знали действие, которое должно быть выполнено. Это закрытие формы. Поэтому в обработке оповещения мы смело писали Закрыть() .

Но в обработчике ПередЗаписью мы такой однозначной информации не имеем. В этом обработчике мы можем оказаться по двум причинам: если пользователь нажал Записать , или если он нажал Записать и закрыть . То есть дальнейший сценарий действий нам неизвестен. Определить его стандартными способами, находясь внутри этого обработчика, мы не можем.

Поэтому тут можно предложить три варианта, но все они, к сожалению, обладают недостатками:

  • Изменить логику прикладного решения так, чтобы не было диалога с пользователем в этом обработчике. Это не всегда возможно;
  • В обработке оповещения с помощью собственной блокирующей формы задавать пользователю развернутый вопрос, предполагающий точное описание дальнейших действий: Отказаться?, Только записать? , Записать и закрыть? Это может выглядеть не очень красиво, ведь пользователь уже нажал «Записать и закрыть» , а его опять об этом спрашивают;
  • Не использовать стандартные команды формы Записать , » Записать и закрыть» . Вместо них создать собственные команды, в которых и выполнять необходимые алгоритмы. Создание собственных команд потребует дополнительных трудозатрат.

Как переделывать старые конфигурации

Общие замечания

Переделка имеющихся конфигураций для работы в режиме без использования модальности сводится к трём этапам:

  • Первый этап — это поиск модальных вызовов и оценка возможности их преобразования;
  • Второй этап — автоматическое преобразование модальных вызовов;
  • Третий этап — полуавтоматическое преобразование тех модальных вызовов, которые невозможно преобразовать автоматически. Либо изменение алгоритма с целью вообще отказаться от использования таких вызовов (если преобразование оказывается слишком сложным и трудоёмким).

Далее мы рассмотрим все три этапа по-порядку. Какие инструменты можно использовать, какие рекомендации можно дать.

Поиск модальных методов

Существует несколько инструментов, которые позволяют найти модальные вызовы конфигурации. Некоторые из этих инструментов позволяют также оценить возможность автоматического преобразования этих вызовов.

В режиме 1С:Предприятие

Для того чтобы прямо в пользовательском режиме увидеть модальные вызовы конфигурации можно использовать свойство конфигурации «Режим использования модальности» . Его нужно установить в значение » Использовать с предупреждением» . Тогда в процессе работы прикладного решения будут выводиться сообщения каждый раз, как выполняется модальный метод. Но работе приложения это препятствовать не будет:

Проверка конфигурации в режиме Конфигуратор

Можно найти все методы, открывающие модальные диалоговые окна. Для этого нужно выполнить проверку конфигурации с установленным флажком «Поиск использования модальности» .

Проверка конфигурации — Расширенная проверка — Поиск использования модальности :

Результат проверки будет выдан в окно служебных сообщений, из которого можно сразу же перейти в модуль, в котором находится данный метод:

Нужно отметить, что эта проверка обнаруживает не все возможные модальные вызовы, а только те, которые можно определить «наверняка». То есть это модальные методы глобального контекста и модальные методы тех объектов, тип которых однозначно определён в анализируемом контексте.

Поэтому, например, в приведённом примере проверка не обнаруживает модальное открытие диалога выбора цвета во вложенной процедуре. В контексте этой процедуры тип переменной «Диалог» неизвестен.

Проверка одного модуля

Можно найти все модальные вызовы в каком-либо одном модуле (начиная с версии 8.3.5). Для этого нужно открыть этот модуль и выполнить команду контекстного меню «Рефакторинг — Модальные вызовы — Найти модальные вызовы модуля» (эти же команды доступны из меню «Текст» ):

В этом случае будут найдены все строки кода, которые приводят или могут привести к открытию модальных окон. В том числе и те строки, где открытие модального окна возможно, если объект имеет определённый тип:

Например, во вложенной процедуре в данном примере действительно будет открыто модальное окно для выбора цвета.

Если бы во вложенную процедуру в переменной » Диалог » передавалась бы выборка справочника, то, естественно, никакого модального вызова не было бы. Однако проверка всё равно отметила бы эту строку как «потенциально опасную».

Поэтому окончательное решение в таких случаях нужно принимать на основе визуального анализа алгоритма и типов используемых объектов.

Поиск с анализом возможности автоматического преобразования

Можно не только найти все модальные вызовы, но и оценить возможность их автоматического преобразования (начиная с версии 8.3.5). Оговоримся, что автоматическое преобразование выполняется не во всех случаях, подробнее об этом можно прочитать в разделе Автоматическое преобразование модальных методов.

Анализ модальных вызовов выполняется для всей конфигурации командой » Конфигурация — Рефакторинг — Анализ модальных вызовов конфигурации «:

Перед выполнением анализа можно задать параметры. Они позволяют уточнить анализ и одновременно с анализом выполнить преобразование:

Со стандартными значениями (если ничего не менять) буду найдены только те вызовы модальных методов, которые удалось определить однозначно:

Если установить флажок «Отображать методы объектов неопределенного типа» , то тогда будут показаны и те методы объектов, которые потенциально могут привести к открытию модальных окон. Это могут быть действительно модальные вызовы, а может быть и нет. Всё зависит от типа объекта, который нужно определять визуально, анализируя код программы:

В любом случае (с теми или иными параметрами анализа) результат будет содержать подробную информацию по каждому вызову с комментарием:

Вызовы, имеющие отметку «Может быть преобразован» , поддаются автоматическому преобразованию, которое выполняется этой же командой (нужно установить соответствующий флажок). Подробнее можно прочитать в разделе Автоматическое преобразование модальных методов.

С теми вызовами, про которые сказано, что они » Требуют дополнительных изменений» , нужно разбираться вручную. Тут сложно описать все возможные ситуации, но по некоторым типичным сообщениям можно дать примеры.

  • «Принадлежность не определена» — суть проблемы описана в разделе Проверка одного модуля. Вы должны самостоятельно определить тип объекта и на основании этого понять, приводит ли его метод к модальному вызову, или нет.
  • Необходимо преобразование в асинхронную процедуру ;
  • «Не поддерживается для процедур и функций глобального контекста» — суть проблемы описана в разделе Вопрос в модуле управляемого приложения. Нужно вручную определить модуль, в котором будет располагаться обработчик оповещения.
  • Присвоение ссылочного параметра: СтандартнаяОбработка ;
  • Присвоение ссылочного параметра: Отказ ;
  • Невозможно выделить фрагмент-окончание: фрагмент содержит незавершенный блок условия…

Автоматическое преобразование модальных методов

Автоматическое преобразование можно выполнить для всей конфигурации командой «Конфигурация — Рефакторинг — Анализ модальных вызовов конфигурации — Производить преобразование найденных вызовов» .

Можно выполнить аналогичное преобразование только для одного модуля. Для этого можно использовать команду контекстного меню «Рефакторинг — Модальные вызовы — Преобразовать модальные вызовы модуля» , или аналогичную команду из меню » Текст» .

Эти инструменты доступны начиная с версии 8.3.5.

Автоматически преобразуются только тривиальные вызовы. Это такие вызовы, преобразование которых затрагивает одну процедуру и не требует операций помимо выделения объекта.

Остальные вызовы требуют вашего вмешательства. Часть из них можно также преобразовать автоматически, но с помощью последовательного выполнения других команд рефакторинга. Другая часть потребует предварительного изменения алгоритма программы. Некоторые такие типичные ситуации рассматриваются в примерах следующего раздела.

Ручное преобразование конструкций, которые невозможно преобразовать автоматически

В этом разделе мы разберём некоторые типичные случаи, когда автоматическое преобразование невозможно и требуется вмешательство разработчика.

Как мы уже неоднократно говорили, далеко не во всех сценариях работы нужно стремиться «во что бы то ни стало» преобразовать модальный код в блокирующий. Как поступить в каждом конкретном случае — это вопрос творческий. Дать готовые рекомендации вроде «если у вас то-то, то поступить надо так-то» довольно затруднительно.

Мы рекомендуем отталкиваться от того соображения, что асинхронная модель работы, по сути, требует другого подхода к проектированию юзабилити интерфейса. То есть, «по хорошему», «по большому счёту» вопрос не в том, чтобы заменить одни операторы встроенного языка другими. Вопрос в том, чтобы изменить сценарий работы прикладного решения таким образом, когда использование блокирующего диалога станет ненужным.

Поэтому если преобразование существующего модального кода кажется сложным, затратным или вовсе невозможным — не стоит ломать голову. Не стоит придумывать сложные способы преобразования его в блокирующий код. Лучше подумать о том, чтобы в этом месте совсем отказаться от использования модальности.

Необходимо преобразование в асинхронную процедуру

При анализе модулей могут встретиться конструкции, автоматическое преобразование которых затруднительно. Например, на модальный вызов во вложенной процедуре система отреагирует следующим образом:

Это не значит, что автоматическое преобразование невозможно. Это значит, что его результат может оказаться непростым. И по этой причине желательно, чтобы разработчик выполнил его отдельно и самостоятельно.

Чтобы в подобном случае выполнить преобразование, можно установить курсор на модальный метод и из контекстного меню выполнить команду » Рефакторинг — Модальные вызовы — Преобразовать модальный вызов» :

Перед выполнением платформа известит вас, что кроме самого модального вызова необходимо преобразовать вызов процедуры к асинхронному виду:

И после этого будут выполнены оба преобразования:

Присвоение cсылочного параметра: СтандартнаяОбработка

Это простой, но типичный пример. Такое сообщение, например, будет выдано при анализе следующего модуля:

Здесь проблема заключается в том, что присвоение значения переменной СтандартнаяОбработка происходит уже после выполнения модального метода, а значит должно выполняться в процедуре обработчика оповещения. Но там это выполнить невозможно.

На самом деле видно, что в этом фрагменте строку СтандартнаяОбработка = Ложь; можно разместить и до вызова модального метода. От этого логика работы не меняется:

И если мы поступим таким образом, то сразу же облегчим задачу преобразования. Теперь оно может быть выполнено автоматически:

Присвоение cсылочного параметра: Отказ

Этот пример по своему «диагностическому сообщению» очень похож на предыдущий, но решение его уже не такое простое. Например, исходный код выглядит так:

Суть проблемы здесь та же, что и в предыдущем примере. После выполнения модального метода нужно присвоить значение переменной «Отказ» . Но сделать это в контексте обработчика оповещения невозможно.

Дополнительная сложность заключается в том, что просто переставить местами строки кода, как в предыдущем примере, тоже нельзя. Отказ выполняется только при одном из условий.

Поэтому тут нужно применять решение, которое описано в разделе Вопрос в обработчике формы ПередЗакрытием. Выполнять закрытие формы «в два прохода». Первый раз безусловно отказываться от действия и только задавать вопрос. А второй раз уже закрывать форму. А чтобы не зациклиться, использовать переменную модуля для того, чтобы отличить первый проход от второго.

Невозможно выделить фрагмент-окончание: фрагмент содержит незавершенный блок условия. Пример 1

Подобные сообщения свидетельствуют о том, что код довольно сложен и алгоритм автоматического преобразования не может его обработать. В таких случаях можно попытаться изменить или упростить алгоритм для того, чтобы автоматическое преобразование стало возможным. Условия, при которых возможно автоматическое преобразование, подробно описаны в документации.

Безусловно, ситуации могут быть самыми разными и в общем случае они требуют творческого подхода. Здесь мы покажем пару типичных приёмов. Это избавление от цикла и выделение фрагментов в отдельную процедуру.

Итак, к сообщению, вынесенному в заголовок, может привести, например, следующий фрагмент:

Проблема этого фрагмента в том, что модальный вызов выполняется внутри цикла. Для того чтобы появилась возможность преобразовать этот фрагмент в немодальный, нужно изменить логику алгоритма. Вместо того чтобы задавать вопрос каждый раз, как попадается «подозрительная» строка таблицы, нужно сначала найти все подозрительные строки, а затем один раз задать вопрос по поводу этих строк:

После такого изменения становится доступным автоматическое преобразование:

Невозможно выделить фрагмент-окончание: фрагмент содержит незавершенный блок условия. Пример 2

Другой фрагмент, который может привести к такому сообщению, может выглядеть так:

Проблема этого фрагмента заключается в строках, отмеченных стрелками. Каждая из этих строк может быть выполнена как в результате прохода по ветке с модальным вызовом, так и в результате прохода по «безмодальным» веткам алгоритма. Если бы в коде присутствовала только одна из этих строк, автоматическое преобразование было бы возможно. Но так, как их две, ситуация становится довольно сложной.

Что можно сделать? Путём выделения фрагмента кода в отдельную процедуру можно попытаться уменьшить «вариативность» алгоритма.

Посмотрим на первую «проблемную» строку. Перейти к ней мы можем из двух веток алгоритма:

Причём эти переходы должны будут принципиально отличаться, ведь из «немодальной» ветки мы можем перейти в эту же процедуру, а из «модальной» мы должны будем перейти в обработчик оповещения.

Можно упростить эту ситуацию, выделив весь оператор » Если» в отдельную процедуру:

Тогда уже будет неважно, по какой ветке шло выполнение алгоритма. К выполнению «проблемной» строки мы придём из одной и той же точки — после возврата из выделенной процедуры.

Поскольку выделяемый фрагмент содержит «Возврат» , выделим его в асинхронную процедуру. Получится четыре процедуры:

А теперь уже можно преобразовать вызов ОткрытьФормуМодально() . Вместо одной процедуры АктВыполненныхРаботПоЗаказамПриИзмененииФрагмент() получится три процедуры:

Функция ВыгрузитьПоПравилу — мощный инструмент расширения возможностей ваших правил конвертации. Конвертация данных 2.1

  • ДипломИзВходящихДанных.PNG
  • ВыгрузитьОбъект.PNG
  • ПослеВыгрузкиДанных.PNG

Казалось бы, всего лишь одна функция из арсенала разработчика правил обмена на Конвертации данных 2.1, но понимание этой функции расширяет ваши возможности при написании качественных правил обмена в несколько раз. Да, что там писать эти правила? Сопоставил реквизиты, сопоставил табличные части, да еще помощник автоматически создаст необходимые ПКО, ПКС, ПВД. А как быть, когда нужно передать Регистр сведений в регистр сведений, да не просто передать, а привязать это действие к выгрузке определенных элементов, например, элементов справочника Физические лица? Или как передать табличную часть справочника в документы, да так, чтобы одна строка табличной части создавала ровно один документ на стороне приемника? А как быть, если невозможно сделать соответствия между объектами и данные для приемника необходимо собирать из разных источников? Именно для подобных задач вам может понадобиться функция ВыгрузитьПоПравилу.

Здесь, я расскажу вам о тех ситуациях, в которых мне понадобилась эта функция, и как она меня не раз выручила. Все свое повествование я сопровожу реальными примерами, которые реализовывались мной в одном из проектов.

Описание функции ВыгрузитьПоПравилу().

Функция ВыгрузитьПоПравилу() используется для выгрузки объекта в xml-узел и возвращает узел ссылки на этот объект.

В процессе выгрузки эта функция вызывается из :

ПВД, когда объект из выборки получен и необходимо произвести его конвертацию.

ПКО, когда необходимо выгрузить связанную с выгружаемым объектом информацию.

ПКС, когда свойство имеет ссылочный тип и необходимо выгрузить по ссылке из этого свойства объект.

Из функции ВыгрузитьПоПравилу() могут быть вызваны другие функции, выгружающие субконто, свойства и т.д. этого объекта, а из этих функций – рекурсивно может быть вызвана функция ВыгрузитьПоПравилу(). После того, как объект со всеми необходимыми свойствами выгружен, управление возвращается в то место кода, откуда функция была вызвана . Таким образом, вызов этой функции из обработчиков событий какого-либо правила (ПВД, ПКО, ПКС), не изменяет процесса выгрузки объекта по этому правилу.

Функция ВыгрузитьПоПравилу() имеет ряд параметров

ВыгрузитьПоПравилу(Источник,
Приемник,
ВходящиеДанные,
ИсходящиеДанные,
ИмяПКО,
УзелСсылки,
ТолькоПолучитьУзелСсылки,
ПКО,
ЭтоПравилоСГлобальнойВыгрузкойОбъектов,
ВыборкаДляВыгрузкиДанных)

Все эти параметры в функции имеют значения по умолчанию, и, как правило, передавать имеет смысл только параметр ИмяПКО, а также параметры Источник и/или ВходящиеДанные – в зависимости от того, как настроено ПКО.

ИмяПКО – строка, название ПКО, в которое передаем управление.
Источник – ссылка на элемент объекта-источника, который передаем для конвертации.
ВходящиеДанные – структура. Элементы в ней должны быть названы аналогично ПКС, у которых стоит флаг «Получить из входящих данных». Если таких ПКС нет, передавать этот параметр не нужно. Если в ПКО у всех ПКС стоит флаг «Получить из входящих данных», то, наоборот, необходимо передать структуру ВходящиеДанные, а Источник тогда передавать не нужно.

Выгрузка произвольной выборки данных через стандартную выборку с регистрацией объекта источника.

Необходимость в такой задаче может возникнуть, когда объект «источника» и объект «приемника» имеют различную смысловую или функциональную структуру .

Например, документ «источника» позволяет вводить информацию по нескольким подразделениям предприятия, документ «приемника» позволяет вводить информацию только об одном подразделении предприятия.

Данная задача отлично решается при помощи произвольного алгоритма выборки в ПВД, но данное решение имеет два недостатка:

  1. Мы лишаемся механизма регистрации изменений;
  2. Алгоритм произвольной выборки отказывается работать в БСП.

БСП — библиотека стандартных подсистем. В частности, имеет своем составе подсистему «Обмен данными», данная подсистема реализует механизмы автоматической синхронизации данных между конфигурациями, по правилам написанным в Конвертации данных.

  1. Создаем ПВД со Стандартным алгоритмом выборки;
  2. Указываем объект выборки;
  3. Пишем обработчик «Перед выгрузкой»(хочу подчеркнуть, что нужно использовать именно этот обработчик). Например, следующего содержания:

//Начинаем отбор данных для выгрузки Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ | ПриемНаРаботуВОрганизациюРаботникиОрганизации.Сотрудник, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.ПодразделениеОрганизации КАК Подразделение, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.Должность, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.ЗанимаемыхСтавок КАК Ставка, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.ДатаПриема, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.Сотрудник.ВидЗанятости КАК ВидЗанятости, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.Ссылка.Дата, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.Ссылка.Номер, | ПриемНаРаботуВОрганизациюРаботникиОрганизации.Ссылка.Проведен, | ВЫБОР | КОГДА ПриемНаРаботуВОрганизациюОсновныеНачисления.ВидРасчета = ЗНАЧЕНИЕ(ПланВидовРасчета.ОсновныеНачисленияОрганизаций.ОкладПоЧасам) | ТОГДА ИСТИНА | ИНАЧЕ ЛОЖЬ | КОНЕЦ КАК СдельнаяОплатаТруда, | ПриемНаРаботуВОрганизациюОсновныеНачисления.ВидРасчета КАК ВидРасчета |ИЗ | Документ.ПриемНаРаботуВОрганизацию.РаботникиОрганизации КАК ПриемНаРаботуВОрганизациюРаботникиОрганизации | ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПриемНаРаботуВОрганизацию.ОсновныеНачисления КАК ПриемНаРаботуВОрганизациюОсновныеНачисления | ПО ПриемНаРаботуВОрганизациюРаботникиОрганизации.Ссылка = ПриемНаРаботуВОрганизациюОсновныеНачисления.Ссылка | И ПриемНаРаботуВОрганизациюРаботникиОрганизации.Сотрудник = ПриемНаРаботуВОрганизациюОсновныеНачисления.Сотрудник |ГДЕ | ВЫБОР | КОГДА &ИспользоватьОтборПоПодразделениям ТОГДА | ПриемНаРаботуВОрганизациюРаботникиОрганизации.ПодразделениеОрганизации В ИЕРАРХИИ (&Подразделения) | ИНАЧЕ | ИСТИНА | КОНЕЦ | И ВЫБОР | КОГДА &ИспользоватьОтборПоВидамРасчета ТОГДА | ПриемНаРаботуВОрганизациюОсновныеНачисления.ВидРасчета В ИЕРАРХИИ (&ВидРасчета) | ИНАЧЕ | ИСТИНА | КОНЕЦ | И ПриемНаРаботуВОрганизациюРаботникиОрганизации.Ссылка = &Ссылка"; Выполнить(Алгоритмы.ЗаполнитьПараметрыОтбораПоВидамРасчета); Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка); Выполнить(Алгоритмы.ЗаполнитьПараметрыОтбораПоПодразделениям); ВыбранныеДанные = Неопределено; ПустаяТабличнаяЧасть = Неопределено; Выполнить(Алгоритмы.ПолучитьСтруктуруВыгрузкиКадровыхДокументов); РезультатЗапроса = Запрос.Выполнить().Выгрузить(); Сотрудники = ПустаяТабличнаяЧасть.Скопировать(); СтрокаДокумента = Неопределено; Для Каждого СтрокаРезультата Из РезультатЗапроса Цикл ДанныеИзВнешнихСистем = "Выгружено из ЗиКБУ, документ ""Прием на работу в организацию"" №" + СтрокаРезультата.Номер + " от " + Формат(СтрокаРезультата.Дата, "ДФ=dd.MM.yyyy") + ", " + СтрокаРезультата.Подразделение.Наименование; СтрокаДокумента = ВыбранныеДанные.Найти(ДанныеИзВнешнихСистем); Если СтрокаДокумента = Неопределено Тогда СтрокаДокумента = ВыбранныеДанные.Добавить(); СтрокаДокумента.Дата = СтрокаРезультата.ДатаПриема; СтрокаДокумента.Кафедра = СтрокаРезультата.Подразделение; СтрокаДокумента.Проведен = СтрокаРезультата.Проведен; СтрокаДокумента.ДокументСАктивнымиДолжностями = Истина; СтрокаДокумента.ДанныеИзВнешнихСистем = ДанныеИзВнешнихСистем; СтрокаДокумента.АктивныеДолжности = ПустаяТабличнаяЧасть.Скопировать(); СтрокаДокумента.НеактивныеДолжности = ПустаяТабличнаяЧасть.Скопировать(); КонецЕсли; СтрокаРаботников = СтрокаДокумента.АктивныеДолжности.Добавить(); СтрокаРаботников.Должность = СтрокаРезультата.Должность; СтрокаРаботников.Сотрудник = СтрокаРезультата.Сотрудник.Физлицо; СтрокаРаботников.Ставка = СтрокаРезультата.Ставка * 100; СтрокаРаботников.ВидНачисления = СтрокаРезультата.ВидРасчета; СтрокаРаботников.ВидЗанятости = СтрокаРезультата.ВидЗанятости; КонецЦикла; //Переводим отобранные данные из Таблицы значений в Массив структур для дальнейшей передачи в ПКО ДокументыЗакреплениеЗаКафедрой = Неопределено; Выполнить(Алгоритмы.ПереводТаблицыЗначенийВМассивЗакреплениеЗаКафедрой); //Обходим отобранные данные и выгружаем с помощью функции ВыгрузитьПоПравилу Для каждого Документ Из ДокументыЗакреплениеЗаКафедрой Цикл ВыгрузитьПоПравилу(,,Документ,,"ЗакреплениеЗаКафедройИзВходящихДанных"); КонецЦикла; //Отменяем стандартную выгрузку объекта Отказ = Истина;

Большую часть этого обработчика, как вы можете видеть, занимает отбор данных необходимых для выгрузки. Тут и множество фильтров: по подразделениям, по видам расчетов и механизм разбиения одного документа «источника» на несколько документов «приемника». Если коротко, то в данном примере табличная часть одного документа «источника» разносится по табличным частям нескольких документов «приемника», а значением разбиения данных является значение Подразделения.

Для удобства работы при отборе данных мы использовали Таблицу значений, наш алгоритм подразумевает ПКО с получением данных из «входящих данных», которые будут переданы в функцию ВыгрузитьПоПравилу, поэтому в соответсвующем алгоритме мы производим перевод Таблицы значений в Массив структур.

На следующем шаге мы обходим отобранные данные и вот уже в этом месте мы используем нашу функцию ВыгрузитьПоПравилу. Параметр Документ, здесь является структурой, которую мы передаем как входящие данные, а второй передаваемый нами параметр, это название ПКО, которому мы передаем наши данные.

В самом конце мы отменяем выполнение стандартной выгрузки, так как все необходимые данные связанные с объектом выборки мы уже выгрузили.

Тем самым мы сохраняем функциональность регистрации изменений — документ изменился, зарегистрировался для выгрузки, данные выгрузили. И в то же время делаем произвольный отбор необходимых нам данных.

В ПКО в этом случае для свойств необходимо указать, что они получаются из «Входящих данных».

Выгрузка Регистр сведений -> Регистр сведений с зависимостью от переноса другого объекта.

Типичным примером такой задачи является перенос контактной информации физического лица. Простейший способ решения задачи — это перенос всех «Физических лиц» и всего регистра сведений «Контактная информация» физических лиц. Что делать если нам необходимо переносить не всех физических лиц? Например, только тех физических лиц, которые упоминаются в каком-либо переносимом нами документе. В таком случае, как известно, ПКС документа вызывает ПКО справочника «Физические лица» и тем самым обеспечивается перенос физических лиц упоминаемых в документе.

В переносе «Контактной информации» физических лиц в данной ситуации может помочь функция ВыгрузитьРегистр, очень похожая на функцию ВыгрузитьПоПравилу.

Хочу отметить, что потребность в использовании функции ВыгрузитьРегистр у меня появилась, когда я начал адаптировать правила под БСП уже отлаженные на обработке Универсальный обмен XML. Регистры через обработку спокойно выгружались с использованием функции ВыгрузитьПоПравилу, но БСП ни как не хотело правильно понимать такую выгрузку, в результате чего пришлось переписывать код через ВыгрузитьРегистр.

В обработчике»После выгрузки в файл» ПКО «Физические лица», пишем код следующего вида:

////////////////////////////////////////////////////// //Выгрузим контактную информацию типа Адрес Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | КонтактнаяИнформация.Представление, | КонтактнаяИнформация.Вид, | КонтактнаяИнформация.Тип, | КонтактнаяИнформация.Объект |ИЗ | РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация |ГДЕ | КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес) | И КонтактнаяИнформация.Вид В (ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресФизЛица), ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ФактАдресФизЛица)) | И КонтактнаяИнформация.Объект = &Объект"; Запрос.УстановитьПараметр("Объект", Источник); Выборка = Запрос.Выполнить ().Выбрать (); Пока Выборка.Следующий () Цикл Отбор = Новый ТаблицаЗначений; Отбор.Колонки.Добавить ("Имя"); Отбор.Колонки.Добавить ("Значение"); Отбор.Колонки.Добавить ("Использование"); СтрокаОтбора = Отбор.Добавить (); СтрокаОтбора.Имя = "Объект"; СтрокаОтбора.Значение = Выборка.Объект; СтрокаОтбора.Использование = Истина; Строки = Новый ТаблицаЗначений; Строки.Колонки.Добавить("Представление"); Строки.Колонки.Добавить("Вид"); Строки.Колонки.Добавить("Тип"); Строки.Колонки.Добавить("Объект"); Строка = Строки.Добавить(); Строка.Представление = Выборка.Представление; Строка.Вид = Выборка.Вид; Строка.Тип = Выборка.Тип; Строка.Объект = Выборка.Объект; НаборЗаписей = Новый Структура("Отбор, Строки"); НаборЗаписей.Отбор = Отбор; НаборЗаписей.Строки = Строки; ВыгрузитьРегистр(НаборЗаписей. "КонтактнаяИнформация"); КонецЦикла;

Как видно, в коде отбираются все записи регистра сведений, относящиеся к текущему выгружаемому Физическому лицу, а полученная выборка обходится в цикле.

Для того, чтобы выгрузить записи регистра сведений через функцию ВыгрузитьРегистр, необходимо подготовить структуру НаборЗаписей, которая имеет два поля: Отбор и Строки.

ПКО «КонтактнаяИнформация» имеет следующий вид:

Выгрузка Табличная часть -> Регистр сведений.

По своему решению задача аналогична предыдущей. С той лишь разницей, что информацию для регистра сведений «приемника» брать придется из других объектов «источника», а точнее табличной части того объекта, который на данный момент выгружается. Если бы на стороне «приемника» была так же табличная часть, то задача легко решалась бы в виде ПГКС. Поэтому снова воспользуемся функцией ВыгрузитьРегистр.

Рассмотрим пример переноса информации по ученым степеням Физического лица. Опять создаем код в обработчике «После выгрузки в файл» ПКО «Физические лица». Так как задача аналогичная предыдущей привожу только, код отбора и выгрузки данных из обработчика:

/////////////////////////////////////////////////////// //Выгрузим информацию по ученым степеням Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ФизическиеЛицаУченыеСтепени.Ссылка, | ФизическиеЛицаУченыеСтепени.УченаяСтепень, | ФизическиеЛицаУченыеСтепени.ОтрасльНауки, | ФизическиеЛицаУченыеСтепени.ДипломСерияНомер, | ФизическиеЛицаУченыеСтепени.ДатаПрисужденияУченойСтепени |ИЗ | Справочник.ФизическиеЛица.УченыеСтепени КАК ФизическиеЛицаУченыеСтепени |ГДЕ | ФизическиеЛицаУченыеСтепени.Ссылка = &ФизЛицо"; Запрос.УстановитьПараметр("ФизЛицо", Источник); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл Отбор = Новый ТаблицаЗначений; Отбор.Колонки.Добавить ("Имя"); Отбор.Колонки.Добавить ("Значение"); Отбор.Колонки.Добавить ("Использование"); СтрокаОтбора = Отбор.Добавить (); СтрокаОтбора.Имя = "ФизическоеЛицо"; СтрокаОтбора.Значение = Выборка.Ссылка; СтрокаОтбора.Использование = Истина; Строки = Новый ТаблицаЗначений; Строки.Колонки.Добавить("Ссылка"); Строки.Колонки.Добавить("ФизическоеЛицо"); Строки.Колонки.Добавить("УченаяСтепень"); Строки.Колонки.Добавить("Специальность"); Строки.Колонки.Добавить("НомерДиплома"); Строки.Колонки.Добавить("Период"); Строка = Строки.Добавить(); Строка.ФизическоеЛицо = Выборка.Ссылка; Строка.УченаяСтепень = Выборка.УченаяСтепень; Строка.Специальность = Выборка.ОтрасльНауки; Строка.НомерДиплома = Выборка.ДипломСерияНомер; Строка.Период = Выборка.ДатаПрисужденияУченойСтепени; НаборЗаписей = Новый Структура("Отбор, Строки"); НаборЗаписей.Отбор = Отбор; НаборЗаписей.Строки = Строки; ВыгрузитьРегистр(НаборЗаписей. Истина,"УченыеСтепениФизическихЛиц"); КонецЦикла;

Выгрузка Табличная часть -> Документ.

Предположим, в «источнике» информация для переноса хранится в менее детализированном виде, чем в приемнике, но достаточном для переноса. Например, мной решалась задача по переносу информации об образовании физических лиц из ЗиКБУ в Университет. Понятно, что на стороне кадровой программы нужна минимальная информация об образовании физических лиц, главное что сотрудник обладает необходимой квалификацией и хватит. А вот на стороне университета, информация об образовании, а точнее о дипломах хранится куда более подробно, в связи со спецификой учереждения.

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

Вот пример выгрузки Дипломов физических лиц. Все тот же обработчик «После выгрузки в файл» ПКО «Физические лица», пишем следующий код:

/////////////////////////////////////////////////////// //Выгрузим образование Физического лица Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ФизическиеЛицаОбразование.Ссылка КАК Студент, | ФизическиеЛицаОбразование.ВидОбразования, | ФизическиеЛицаОбразование.УчебноеЗаведение, | ФизическиеЛицаОбразование.Специальность.Наименование КАК Специальность, | ФизическиеЛицаОбразование.Диплом, | ФизическиеЛицаОбразование.ГодОкончания, | ФизическиеЛицаОбразование.Квалификация |ИЗ | Справочник.ФизическиеЛица.Образование КАК ФизическиеЛицаОбразование |ГДЕ | ФизическиеЛицаОбразование.Ссылка = &ФизЛицо"; Запрос.УстановитьПараметр("ФизЛицо", Источник); РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл ВходящиеДанные = Новый Структура; ВходящиеДанные.Вставить("Студент", ВыборкаДетальныеЗаписи.Студент); ВходящиеДанные.Вставить("ВидОбразования", ВыборкаДетальныеЗаписи.ВидОбразования); ВходящиеДанные.Вставить("ОбразовательноеУчреждениеПриОкончании", ВыборкаДетальныеЗаписи.УчебноеЗаведение); ВходящиеДанные.Вставить("Специальность", ВыборкаДетальныеЗаписи.Специальность); СерияНомерДиплома = ВыборкаДетальныеЗаписи.Диплом; СерияДиплома = ""; НомерДиплома = ""; Выполнить(Алгоритмы.ПолучитьСериюИНомер); ВходящиеДанные.Вставить("СерияДиплома", СерияДиплома); ВходящиеДанные.Вставить("НомерДиплома", НомерДиплома); Если НЕ ВыборкаДетальныеЗаписи.ГодОкончания = 0 Тогда ВходящиеДанные.Вставить("ГодЗавершения", Дата(ВыборкаДетальныеЗаписи.ГодОкончания, 1, 1)); ВходящиеДанные.Вставить("ДатаВыдачи", Дата(ВыборкаДетальныеЗаписи.ГодОкончания, 1, 1)); Иначе ВходящиеДанные.Вставить("ГодЗавершения", Дата("00010101")); ВходящиеДанные.Вставить("ДатаВыдачи", Дата("00010101")); КонецЕсли; ВходящиеДанные.Вставить("Квалификация", ВыборкаДетальныеЗаписи.Квалификация); ВыгрузитьПоПравилу(,,ВходящиеДанные,,"ДипломИзВходящихДанных"); КонецЦикла;

Тут мы отбираем данные из табличной части и формируем входящие данные для документа на стороне «приемника», после чего при помощи функции ВыгрузитьПоПравилу, передаем входящие данные ПКО ДипломИзВходящихДанных, которое имеет следующий вид:

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

Замечания по перегрузке.

1. У меня возникли сложности при использовании правил в БСП, в части выгрузки объектов по ссылкам, проблема решилась принудительной установкой параметра ВыгрузитьОбъект в значение Истина, для каждого ПКС ссылочного типа:

2. Надо помнить, что при выгрузке через указанные функции, зачастую отсутствует УникальныйИдентификатор объекта, например, когда объект для выгрузки собирается по частям в виде структуры ВходящихДанных, поэтому поиск по уникальному идентификатору придется отключить.

Подводим итоги. Когда использовать эти функции?

  1. Вам необходимо перегрузить объекты с сильно различной структурой или на стороне «источника» необходимо собирать объекты для выгрузки из разных объектов.
  2. Вам необходимо перегружать объекты с привязкой к выгрузке других объектов.

UPDATE от 11.11.2015

А что если оптимизировать выше написанное?

Пишу дополнение к статье, после оставленного пользователем TarasovAV комментария. Данный пользователь заметил, что можно оптимизировать выгрузку связанной информации, путем накопления списка тех объектов, информацию о которых надо будет отдельно выгружать, а потом через один запрос отобрать сразу всю информацию.

Описываю алгоритм предложенный вышеуказанным пользователем:

1. В правиле конвертации «После загрузки правил обмена», создается параметр типа ТаблицаЗначений, в который будет накапливаться список объектов, для которых в последующем будет выгружаться информация:

Параметры.Вставить("СписокФизическихЛиц", Новый ТаблицаЗначений()); Параметры.СписокФизическихЛиц.Колонки.Добавить("ФизическоеЛицо");

2. В в обработчике «После выгрузки» ПКО «Физические лица» (именно для них в примерах мы выгружаем контактные данные, образование и т.п.), мы пополняем нашу таблицу значений новым физическим лицом, проверяя перед этим, а не добавлено ли уже это физическое лицо в таблицу:

НайденнаяСтрока = Параметры.СписокФизическихЛиц.Найти(Источник); Если НайденнаяСтрока = Неопределено Тогда НоваяСтрока = Параметры.СписокФизическихЛиц.Добавить(); НоваяСтрока.ФизическоеЛицо = Источник; КонецЕсли;

3. И финальным действием, будет непосредственная выгрузка информации, только уже с отбором по все физическим лицам сразу. Для этого все обработчики, что были приведены выше начиная, необходимо перенести в правило конвертации «После выгрузки данных», запросы же необходимо изменить, чтобы в них проверялось не равенство одному элементу, а вхождение значения реквизита в массив элементов:

Обратите внимание, как изменилась установка параметра запроса и проверка условия в запросе:

//. "| И КонтактнаяИнформация.Объект В &СписокФизЛицо"; Запрос.УстановитьПараметр("СписокФизЛицо", Параметры.СписокФизическихЛиц.ВыгрузитьКолонку("ФизическоеЛицо")); //.

Привожу полный код, исправленных ранее приведенных примеров:

////////////////////////////////////////////////////// //Выгрузим контактную информацию типа Адрес Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | КонтактнаяИнформация.Представление, | КонтактнаяИнформация.Вид, | КонтактнаяИнформация.Тип, | КонтактнаяИнформация.Объект |ИЗ | РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация |ГДЕ | КонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес) | И КонтактнаяИнформация.Вид В (ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресФизЛица), ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ФактАдресФизЛица)) | И КонтактнаяИнформация.Объект В &СписокФизЛицо"; Запрос.УстановитьПараметр("СписокФизЛицо", Параметры.СписокФизическихЛиц.ВыгрузитьКолонку("ФизическоеЛицо")); Выборка = Запрос.Выполнить ().Выбрать (); Пока Выборка.Следующий () Цикл Отбор = Новый ТаблицаЗначений; Отбор.Колонки.Добавить ("Имя"); Отбор.Колонки.Добавить ("Значение"); Отбор.Колонки.Добавить ("Использование"); СтрокаОтбора = Отбор.Добавить (); СтрокаОтбора.Имя = "Объект"; СтрокаОтбора.Значение = Выборка.Объект; СтрокаОтбора.Использование = Истина; Строки = Новый ТаблицаЗначений; Строки.Колонки.Добавить("Представление"); Строки.Колонки.Добавить("Вид"); Строки.Колонки.Добавить("Тип"); Строки.Колонки.Добавить("Объект"); Строка = Строки.Добавить(); Строка.Представление = Выборка.Представление; Строка.Вид = Выборка.Вид; Строка.Тип = Выборка.Тип; Строка.Объект = Выборка.Объект; НаборЗаписей = Новый Структура("Отбор, Строки"); НаборЗаписей.Отбор = Отбор; НаборЗаписей.Строки = Строки; ВыгрузитьРегистр(НаборЗаписей. "КонтактнаяИнформация"); КонецЦикла; /////////////////////////////////////////////////////// //Выгрузим образование Физического лица Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ФизическиеЛицаОбразование.Ссылка КАК Студент, | ФизическиеЛицаОбразование.ВидОбразования, | ФизическиеЛицаОбразование.УчебноеЗаведение, | ФизическиеЛицаОбразование.Специальность.Наименование КАК Специальность, | ФизическиеЛицаОбразование.Диплом, | ФизическиеЛицаОбразование.ГодОкончания, | ФизическиеЛицаОбразование.Квалификация |ИЗ | Справочник.ФизическиеЛица.Образование КАК ФизическиеЛицаОбразование |ГДЕ | ФизическиеЛицаОбразование.Ссылка В &СписокФизЛицо"; Запрос.УстановитьПараметр("СписокФизЛицо", Параметры.СписокФизическихЛиц.ВыгрузитьКолонку("ФизическоеЛицо")); РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл ВходящиеДанные = Новый Структура; ВходящиеДанные.Вставить("Студент", ВыборкаДетальныеЗаписи.Студент); ВходящиеДанные.Вставить("ВидОбразования", ВыборкаДетальныеЗаписи.ВидОбразования); ВходящиеДанные.Вставить("ОбразовательноеУчреждениеПриОкончании", ВыборкаДетальныеЗаписи.УчебноеЗаведение); ВходящиеДанные.Вставить("Специальность", ВыборкаДетальныеЗаписи.Специальность); СерияНомерДиплома = ВыборкаДетальныеЗаписи.Диплом; СерияДиплома = ""; НомерДиплома = ""; Выполнить(Алгоритмы.ПолучитьСериюИНомер); ВходящиеДанные.Вставить("СерияДиплома", СерияДиплома); ВходящиеДанные.Вставить("НомерДиплома", НомерДиплома); Если НЕ ВыборкаДетальныеЗаписи.ГодОкончания = 0 Тогда ВходящиеДанные.Вставить("ГодЗавершения", Дата(ВыборкаДетальныеЗаписи.ГодОкончания, 1, 1)); ВходящиеДанные.Вставить("ДатаВыдачи", Дата(ВыборкаДетальныеЗаписи.ГодОкончания, 1, 1)); Иначе ВходящиеДанные.Вставить("ГодЗавершения", Дата("00010101")); ВходящиеДанные.Вставить("ДатаВыдачи", Дата("00010101")); КонецЕсли; ВходящиеДанные.Вставить("Квалификация", ВыборкаДетальныеЗаписи.Квалификация); ВыгрузитьПоПравилу(,,ВходящиеДанные,,"ДипломИзВходящихДанных"); КонецЦикла; /////////////////////////////////////////////////////// //Выгрузим информацию по ученым степеням Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ФизическиеЛицаУченыеСтепени.Ссылка, | ФизическиеЛицаУченыеСтепени.УченаяСтепень, | ФизическиеЛицаУченыеСтепени.ОтрасльНауки, | ФизическиеЛицаУченыеСтепени.ДипломСерияНомер, | ФизическиеЛицаУченыеСтепени.ДатаПрисужденияУченойСтепени |ИЗ | Справочник.ФизическиеЛица.УченыеСтепени КАК ФизическиеЛицаУченыеСтепени |ГДЕ | ФизическиеЛицаУченыеСтепени.Ссылка В &СписокФизЛицо"; Запрос.УстановитьПараметр("СписокФизЛицо", Параметры.СписокФизическихЛиц.ВыгрузитьКолонку("ФизическоеЛицо")); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл Отбор = Новый ТаблицаЗначений; Отбор.Колонки.Добавить ("Имя"); Отбор.Колонки.Добавить ("Значение"); Отбор.Колонки.Добавить ("Использование"); СтрокаОтбора = Отбор.Добавить (); СтрокаОтбора.Имя = "ФизическоеЛицо"; СтрокаОтбора.Значение = Выборка.Ссылка; СтрокаОтбора.Использование = Истина; Строки = Новый ТаблицаЗначений; Строки.Колонки.Добавить("Ссылка"); Строки.Колонки.Добавить("ФизическоеЛицо"); Строки.Колонки.Добавить("УченаяСтепень"); Строки.Колонки.Добавить("Специальность"); Строки.Колонки.Добавить("НомерДиплома"); Строки.Колонки.Добавить("Период"); Строка = Строки.Добавить(); Строка.ФизическоеЛицо = Выборка.Ссылка; Строка.УченаяСтепень = Выборка.УченаяСтепень; Строка.Специальность = Выборка.ОтрасльНауки; Строка.НомерДиплома = Выборка.ДипломСерияНомер; Строка.Период = Выборка.ДатаПрисужденияУченойСтепени; НаборЗаписей = Новый Структура("Отбор, Строки"); НаборЗаписей.Отбор = Отбор; НаборЗаписей.Строки = Строки; ВыгрузитьРегистр(НаборЗаписей. Истина,"УченыеСтепениФизическихЛиц"); КонецЦикла;

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *