Сама идея программной работы с предопределенными элемементами, на мой взгляд, очень правильная. Просто есть нюансы, которые нужно учитывать при работе.
Для начала необходимо четко осознать для себя, что есть предопределенные элементы в конфигурации и есть предопределенные элементы в информационной базе (ИБ). Технически предопределенные элементы ИБ это самые обычные элементы справочников, у которых в реквизите "ИмяПредопределенныхДанных" указано, какому предопределенному элементу конфигурации они соответствуют. Ничем больше они от обычных элементов не отличаются. Соответственно, любой обычный элемент ИБ можно сделать предопределенным, любой предопределенный обычным. Для этого достаточно вписать нужное значение в реквизит "ИмяПредопределенныхДанных".
Периодически в этом свойстве оказывается не то значение, которое предусмотрел разработчик. В результате возникают ошибки в работе 1С. От критичных, при которых работа в принципе невозможна, до некритичных, при которых нарушается логика работы алгоритмов.
Условно можно выделить три типа ошибок:
1. "Предопределенный элемент отсутствует в данных";
2. "Предопределенный элемент не уникален";
3. Неверное указание предопределенного элемента;
1. "Предопределенный элемент отсутствует в данных" - отсутствие описанного в конфигурации предопределённого элемента в данных ИБ.
Это наиболее простой в отладке и исправлении тип ошибки. Его простота в том, что платформа достаточно корректно сообщает об этой ситуации "Предопределенный элемент отсутствует в данных" и вполне понятно, как её исправить.
При обращении к отсутствующему элементу в коде "Справочники.ВидыКонтактнойИнформации.EmailКонтактногоЛица" выдается сообщение
При обращении к элементу в запросе "ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.EmailКонтактногоЛица)" выдается сообщение:
Такая ошибка возникает в случае, если элемент в конфигурации описан, но в базе ему элемент не сопоставлен.
Для начала уточним, что такая ситуация не всегда является ошибочной. Вполне возможным является использование предопределённых данных в какой-то программной логике, которая для большинства пользователей может не использоваться. В этом случае, чтобы не захломлять справочник у всех пользователей конфигурации, логично определить предопределенные элементы в конфигурации, но не создавать их во всех ИБ, а лишь для тех ИБ, в которых нужная логика конфигурации используется. В этом случае программист может указать для справочника свойство "Не обновлять предопределенные данные" и создать элементы програмно при обращении к функционалу модуля. Либо дать возможность пользователю самостоятельно привязать предопределенные элементы модуля к имеющимся у него обычным элементам.
Также не используется автоматическое создание предопределенных элементов при работе в режиме РИБ. Так как новые элементы должны передаваться из центральной базы, а не создаваться в узлах с отличающимися УИДами.
Т.е. иногда ошибкой является обращение в несопоставленному элементу, а не само наличие такого элемента.
Необходимо проанализировать, почему элемент не создан. Возможно, он должен создаться при выполнении какого-либо режима программы. Например, после выполнения обмена в РИБ. А возможно, его просто случайно удалили.
Если логикой предусмотрено заполнение предопределенных элементов не автоматически, а отдельным режимом, то перед использование обращения по имени "Справочники.ВидыКонтактнойИнформации.EmailКонтактногоЛица" для предотвращения исключительной ситуации желательно проверить, что элемент уже есть в базе. Если элемент отсутствует, то сообщить пользователю об этом и объяснить, какой режим ему нужно выполнить для заполнения элемента. Для такой проверки можно выполнить запрос к данным.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВидыКонтактнойИнформации.Ссылка
|ИЗ
| Справочник.ВидыКонтактнойИнформации КАК ВидыКонтактнойИнформации
|ГДЕ
| ВидыКонтактнойИнформации.ИмяПредопределенныхДанных = ""EmailКонтактногоЛица""";
ЭлементОтсутсвуетВДанных = Запрос.Выполнить().Пустой();
Если это все-таки ошибка в данных базы, то необходимо выполнить привязку к предопределенному элементу элемента ИБ. Т.е. необходимо объяснить системе, к какому элементу ИБ должен обратиться программный код по данному имени. Технически привязка это просто указание имени предопределенного элемента в свойстве "ИмяПредопределенныхДанных" элемента ИБ. Для ее установки достаточно выполнить код:
ОбновляемыйОбъект = СсылкаНаОбъект.ПолучитьОбъект();
ОбновляемыйОбъект.ИмяПредопределенныхДанных = "НашеИмяПредопределенногоЭлемента";
ОбновляемыйОбъект.ОбменДанными.Загрузка = Истина;
ОбновляемыйОбъект.Записать();
2. "Предопределенный элемент не уникален" - задвоенные предопределенные элементы:
Эта ситуация заключается в том, что к одному предопределенному элементу привязано несколько элементов ИБ. В этом случае при обращении к предопределенному имени элемент будет выбираться случайным образом. Такая ситуация всегда ошибочна. Ее сложность в том, что платформа никак о ней не сообщает. Просто алгоритмы начинают работать неверно.
Платформа сообщит об ошибке "Предопределенный элемент не уникален" лишь при попытке редактирования задублированного элемента.
До тех пор, пока никому не понадобится редактировать элемент, об ошибке никто не узнает.
Такие дубли могут создаться, например, если для справочника используеися РИБ и в свойствах для предопределенных данных указан режим "Обновлять автоматически". В этом случае при выполнении обмена один экземпляр предопределенных данных создастся при обновлении конфигурации. Второй экземпляр предопределенных элементов с тем же именем передастся из центральной базы при обмене.
Также эти дубли возникнут при использовании обработок обмена между конфигурациями в случае, если в разных базах предопределенным элементам соответствеют разные элементы ИБ. В этом случае один экземпляр предопределенных данных в базе уже есть, второй придет при выполнении загрузки данных с другим УИДом. Если вы выполняете переносы данных, необходимо решить, элементы какой базы считаются основными и использовать их же в подчиненной базе. В подчиненной базе необходимо заменить использование старых элементов на элементы основной базы.
Такие ошибки в базе данных можно выявить запросом вида:
ВЫБРАТЬ
ВидыКонтактнойИнформации.ИмяПредопределенныхДанных,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВидыКонтактнойИнформации.Ссылка) КАК КоличествоПредопределенных
ИЗ
Справочник.ВидыКонтактнойИнформации КАК ВидыКонтактнойИнформации
СГРУППИРОВАТЬ ПО
ВидыКонтактнойИнформации.ИмяПредопределенныхДанных
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВидыКонтактнойИнформации.Ссылка) > 1
Этот запрос вернет перечень предопределенных элементов, с которым связано более одного элемента ИБ.
При наличии таких элементов необходимо убрать для одного из них связь с предопределенным. Т.е. необходимо однозначно определить для системы, к какому элементу ИБ должен обратиться программный код при использовании данного имени. Для этого достаточно выполнить код.
ОбновляемыйОбъект = СсылкаНаЭлемент.ПолучитьОбъект();
ОбновляемыйОбъект.ИмяПредопределенныхДанных = "";
ОбновляемыйОбъект.ОбменДанными.Загрузка = Истина;
ОбновляемыйОбъект.Записать();
3. Неверное указание предопределенного элемента.
Ошибка заключается в том, что предопределенному элементу соответствует не тот элемент, который предусмотрен логикой программы. Такие ошибки наиболее сложны в диагностике. В отличие от первых двух типов, на наличие этих ошибок автоматически проверить конфигурацию нельзя. Их можно выявить только анализируя логику работы. При возникновении сомнений можно проверить, нужный ли элемент используется.
Для этого достаточно выполнить одну из команд.
//Определение элемента ИБ, который привязан к нужному предопределенному
Сообщить(Справочники.ВидыКонтактнойИнформации.EmailКонтактногоЛица)
//Определяем предопределенный элемент, к которому привязан выбранный
Сообщить(СсылкаНаЭлемент.ИмяПредопределенныхДанных)
При выявлении таких ошибок необходимо убрать некорректную связь со старым элементом и добавить связь с новым элементом. Код операций аналогичен коду исправления первых двух типов ошибок.
Ну и кратко об ошибках при программной работе или в режиме конфигуратора:
"Предопределенный элемент не принадлежит <Имя справочника>" - ошибка возникает при попытке записать предопределенный элемент с именем, не совпадающим с именем в коонфигураторе.
"Не предопределенные объекты не могут иметь предопределенные записи видов субконто" - ошибка возникает при попытке сделать элемент предопределенный плана счетов непредопределенным. Для устранения ошибок необходимо у каждой строки субконта элемента снять признак "Предопределенное".
"Не предопределенные объекты не могут иметь предопределенные записи ведущих видов расчетов" - ошибка возникает при попытке сделать предопределенный элемент плана видов расчета непредопределенным. Для устранения ошибок необходимо у каждой строки ведущего вида расчета элемента снять признак "Предопределенное".
"Предопределенные элементы не уникальны" - ошибка выдается в конфигураторе при обновлении информационной базы на релиз конфигурации без режима совместимости с 8.3.4. Необходимо до обновления проверить дубли и устранить их.
"Имя предопределенного элемента не уникально" - ошибка возникает при наличии в конфигурации нескольких одноименных предопределенных элементов при обновлении на платформу 8.3.6.2332 и выше. Необходимо устранить дубли в конфигурации.
Для работы с предопределенными данными рекоммендую обработку "Установка предопределенных элементов: просмотр, исправление и поиск ошибок (задвоенных и отсутствующих)". Она умеет выполнять любые действия с предопределенными данными, а также может проверить конфигурацию вцелом на наличие во всех объектах ИБ (справочниках, планах счетов, ПВХ, ПВР) ошибок первых двух типов (задвоенных и отсутствующих элементов).