Опубликован: 06.12.2011 | Уровень: для всех | Доступ: платный
Лекция 5:

Справочники

< Лекция 4 || Лекция 5: 12345 || Лекция 6 >

Автозаполнение реквизитов

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

Перейдем в модуль объекта (кнопка Модуль объекта на закладке Прочие окна редактирования объекта), из списка процедур и выберем ОбработкаЗаполнения, рис. 4.3.

Процедура обработки заполнения справочника

Рис. 4.3. Процедура обработки заполнения справочника

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

В режиме 1С:Предприятие откроем справочник Номенклатура, создадим две группы – Товары – флаг Услуги в этой группе не устанавливаем, и Услуги – флаг установлен, рис. 4.4.

Две группы в справочнике Номенклатура

увеличить изображение
Рис. 4.4. Две группы в справочнике Номенклатура

Исследуем процедуру обработки заполнения, прежде чем продолжать работу над ней. Для этого вставим в нее какую-нибудь команду, например: ТестоваяПеременная = 0; и установим на строку с данной командой точку останова. Для этого либо выполним двойной щелчок левой кнопкой мыши на сером поле слева от команды, либо, установив курсор в строку с командой, выполним команду Отладка > Точка останова, либо – установив курсор в нужную строку, нажмем F9. Для установки точки останова нужно, чтобы строка, на которую мы пытаемся ее установить, присутствовала в конфигурации базы данных, то есть – написав код, нужно нажать на кнопку Обновить конфигурацию базы данных. В итоге у нас должно получиться следующее, рис. 4.5.

Точка останова в процедуре

Рис. 4.5. Точка останова в процедуре

Запустим конфигурацию в режиме отладки (кнопка Начать отладку, команда меню Отладка > Начать отладку, или клавиша F5 на клавиатуре). Перейдем в группу Услуги и создадим в ней новый элемент. Когда управление будет передано в Конфигуратор, установим курсор на имя параметра ДанныеЗаполнения, вызовем контекстное меню и выберем команду Вычислить выражение. Появится окно Выражение, из которого можно понять, что переменная ДанныеЗаполнения – это структура, в которой присутствуют сведения о родителе создаваемого элемента – то есть – о группе Услуги, рис. 4.6.

Структура ДанныеЗаполнения

Рис. 4.6. Структура ДанныеЗаполнения

Структура – это таблица, которая содержит пары вида КлючЗначение.

В нашем случае, если процедура ОбработкаЗаполнения отработает – она заполнит лишь поле Родитель для создаваемого элемента. А нам хотелось бы установить и флаг Услуга в соответствии с данными родителя.

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

Родитель – здесь хранится родитель элемента – в нашем случае – группа Услуги типа СправочникСсылка.Номенклатура. То есть, при заполнения поля Родитель создаваемого элемента, окажется, что он будет хранить ссылку на другой элемент (в нашем случае – группу), входящий в справочник Номенклатура.

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

ЕдиницаИзмерения имеет значение Null. При настройке состава реквизитов справочника Номенклатура, мы указали, что ЕдиницаИзмерения может задаваться только для элемента. Но в структуре справочника в информационной базе подобное поле присутствует и у группы. Однако значения оно содержать не может – поэтому в качестве типа значения мы видим Null. Типы значений Неопределено и Null кажутся похожими, но это – разные вещи. Значение с типом Неопределено может быть задано, а значение Null не может быть задано в принципе.

Свойство Услуга установлено в значение Истина – этот флаг мы устанавливали при создании группы Услуги.

Свойство ЭтоГруппа так же истинно – оно устанавливается в истинность для групп.

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

Услуга = ДанныеЗаполнения.Родитель.Услуга.

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

ДанныеЗаполнения.Вставить("Услуга", ДанныеЗаполнения.Родитель.Услуга);

В итоге у нас получается такой код, рис. 4.7.

Заполнение реквизита Услуга на основании параметров элемента родителя

Рис. 4.7. Заполнение реквизита Услуга на основании параметров элемента родителя

Здесь мы установили точку останова для того, чтобы посмотреть, как изменится структура при выполнении данной процедуры. Опробуем решение в пользовательском режиме, можно заметить, что, во-первых, структура ДанныеЗаполнения действительно теперь содержит ключ Услуга со значением Истина, а так же то, что элементы, создаваемые в группе с установленным флагом Услуга, имеют данный реквизит в установленном положении, рис. 4.8.

Результат заполнения реквизита Услуга на основании параметров элемента родителя

Рис. 4.8. Результат заполнения реквизита Услуга на основании параметров элемента родителя

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

Ошибка при попытке создать элемент, у которого нет родителя

Рис. 4.9. Ошибка при попытке создать элемент, у которого нет родителя

Нажав на кнопку Подробно, видим, что ошибка произошла при попытке добавить в структуру новую запись, рис. 4.10.

Более подробное описание ошибки

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

Нажав на кнопку Конфигуратор, мы попадаем в Конфигуратор. Прежде чем обращаться к элементу структуры Родитель, нужно убедиться в том, что Родитель в структуре присутствует. Если Родителя нет – в структуру не нужно ничего добавлять, если есть – можно добавить. Попробуем такой код:

  Если ДанныеЗаполнения.Свойство("Родитель") Тогда
   ДанныеЗаполнения.Вставить("Услуга", ДанныеЗаполнения.Родитель.Услуга);
 КонецЕсли;

Как кажется, все должно работать правильно – если в структуре обнаружилось поле Родитель – мы можем обращаться к свойству Услуга. Но попытка выполнить эту процедуру снова приводит к ошибке

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

Параметр ДанныеЗаполнения при создании элемента или группы на верхнем уровне справочника

увеличить изображение
Рис. 4.11. Параметр ДанныеЗаполнения при создании элемента или группы на верхнем уровне справочника

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

Вышеприведенные рассуждения приводят нас к следующему коду:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
Если ДанныеЗаполнения<>Неопределено Тогда  
 Если ДанныеЗаполнения.Свойство("Родитель") Тогда
   ДанныеЗаполнения.Вставить("Услуга", ДанныеЗаполнения.Родитель.Услуга);
 КонецЕсли;
КонецЕсли;
КонецПроцедуры

В данной редакции обработчика события ОбработкаЗаполнения все работает верно.

Чисто теоретически (предположим, при изменении кем-либо нашего кода) возможна ситуация, когда ДанныеЗаполнения будут являться структурой и в этой структуре, в то же время, не будет свойства Родитель. Поэтому наряду с проверкой на неопределенность значения мы оставляем и проверку на наличие свойства Родитель.

Мы обсудили и проиллюстрировали родительские отношения в справочнике, рассмотрим теперь пример работы с подчиненными справочниками.

< Лекция 4 || Лекция 5: 12345 || Лекция 6 >
Лариса Дятчина
Лариса Дятчина

Код 

&НаКлиенте

Процедура ОсновноеКонтактноеЛицоПриИзменении(Элемент)

Если НЕ ПроверитьЗаполнениеРеквизита() Тогда

 Сообщить("Выбранное контактное лицо, "+Объект.ОсновноеКонтактноеЛицо+",не работает у контрагента.");

КонецЕсли;

КонецПроцедуры

 

&НаСервере

Функция ПроверитьЗаполнениеРеквизита()

 Возврат (Объект.ОсновноеКонтактноеЛицо.ПредставительРаботает);  

КонецФункции

&НаСервере

Процедура УстановитьНомерПредставителя()

 

 Объект.ТелефонКонтактногоЛица=Объект.ОсновноеКонтактноеЛицо.КонтактныеСведения;

КонецПроцедуры

При проверке выдает ошибку:

{Справочник.Контрагенты.Форма.ФормаСписка.Форма(12,11)}: Переменная не определена (Объект)
 Возврат (<<?>>Объект.ОсновноеКонтактноеЛицо.ПредставительРаботает);   (Проверка: Сервер)
{Справочник.Контрагенты.Форма.ФормаСписка.Форма(17,2)}: Переменная не определена (Объект)
 <<?>>Объект.ТелефонКонтактногоЛица=Объект.ОсновноеКонтактноеЛицо.КонтактныеСведения; (Проверка: Сервер)
{Справочник.Контрагенты.Форма.ФормаСписка.Форма(17,32)}: Переменная не определена (Объект)
 Объект.ТелефонКонтактногоЛица=<<?>>Объект.ОсновноеКонтактноеЛицо.КонтактныеСведения; (Проверка: Сервер)
{Справочник.Контрагенты.Форма.ФормаСписка.Форма(6,41)}: Переменная не определена (Объект)
 Сообщить("Выбранное контактное лицо, "+<<?>>Объект.ОсновноеКонтактноеЛицо+",не работает у контрагента."); (Проверка: Тонкий клиент)

 

работаю на версии 1С:Предприятие 8.3 (8.3.10.2650)

максим матасов
максим матасов
Леонид Альбрехт
Леонид Альбрехт
Россия, Екатеринбург, 10, 2004
Оксана Максимова
Оксана Максимова
Россия, Екатеринбург, Уральский государственный университет им. А. М. Горького, 2013