Приемы программирования

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

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

Ниже описываются эти объекты и взаимосвязи между ними:

СправочникиМенеджер

Обеспечивает доступ ко всем справочникам конфигурации. Свойства этого объекта совпадают с именами справочников и содержат объекты типа СправочникМенеджер.

СправочникМенеджер

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

СправочникСсылка

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

СправочникОбъект

Предоставляет доступ к элементу с возможностью записи. Данный объект содержит методы, влияющие на элемент в базе данных, например, методы Записать и Удалить.

СправочникВыборка

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

СправочникСписок

Объект для управления списком элементов в табличном поле. Позволяет управлять колонками, отбором и сортировкой в списке.

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

 

 

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

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

Продемонстрируем на примерах выполнение типичных операций со справочниками.

Обращение к менеджеру справочника

Обращение к менеджеру справочника производится следующим образом:

 

СпрСотр = Справочники.Сотрудники;
СпрТовары = Справочники["Номенклатура"];
 

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

Объект СправочникиМенеджер является коллекцией значений и позволяет обратиться к конкретному элементу коллекции через приведенные выше конструкции. Хотя эти две конструкции функционально эквивалентны, но нужно знать различные варианты их использования:

1. Первый вариант (через точку) применяется, когда имя справочника известно программисту и оно неизменно. Такая конструкция более простая и рекомендуется к применению в большинстве случаев.

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

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

Ниже показываются два варианта обращения к справочнику, первый из которых ошибочный:

 

СпрСотр = Новый Справочники.Сотрудники; // так нельзя!!
СпрСотр = Справочники.Сотрудники; //а вот так правильно
 

Выборка элементов справочника

Перебор элементов справочника производится через объект СправочникВыборка, который возвращается при вызове методов Выбрать и ВыбратьИерархически объекта СправочникМенеджер:

СпрВыборка = Справочники.Номенклатура.Выбрать();
Пока СпрВыборка.Следующий() Цикл
	Сообщить(СпрВыборка.Код + " " + СпрВыборка.Наименование);
	//перебор строк табличной части
	Для Каждого стр Из СпрВыборка.ЕдиницыИзмерения Цикл
		Сообщить(" " + стр.ЕдиницаИзмерения);
	КонецЦикла;
КонецЦикла;

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

Ниже видна разница в работе этих методов (жирным шрифтом выделены группы справочника):

IMG NO

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

Синтаксическая диаграмма метода Выбрать и ВыбратьИерархически такова (на примере метода Выбрать):

 

Выбрать(<Родитель>, <Владелец>, <Отбор>, <Порядок>);
 

Ниже поясняется назначение каждого параметра:

Родитель

Ссылка на родительский элемент или группу. В выборку попадут только элементы, принадлежащие заданному эле-

менту (группе). Параметр имеет смысл только для иерархических справочников.

Владелец

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

Отбор

Структура, которая позволяет отобрать элементы справочника с заданным значением в определенном реквизите. Ключ структуры содержит имя реквизита, а значение структуры задает значение отбора. В структуре могут использоваться только реквизиты Код, Наименование и реквизиты с установленным признаком индексирования. Обратите внимание, что структура может содержать только один элемент. Для отбора элементов по нескольким признакам можно использовать запросы.

Порядок

Строка, задающая условие упорядочивания по реквизиту, например, «Оклад Убыв». Упорядочивание может быть использовано только для индексированных реквизитов (в том числе для кода и наименования).

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

СпрНоменклатура = Справочники.Номенклатура;
ГруппаМониторы = СпрНоменклатура.НайтиПоНаименованию("Мониторы");
СпрВыборка = СпрНоменклатура.Выбрать(ГруппаМониторы,,,"Цена Убыв");
Пока СпрВыборка.Следующий() Цикл
КонецЦикла;

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

 

Отбор = Новый Структура) "ТипРодства");
Отбор.ТипРодства = Перечисления.ТипРодства,Сын;
СпрВыборка = Справочники.Семья.Выбрать(,ВыбСотр,Отбор,);
 

Создание элементов и групп справочника

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

Ниже приведен пример создания группы Прочие справочника Сотрудники и элемента в этой группе:

 

НоваяГруппа = Справочники.Сотрудники.СоздатьГруппу();
НоваяГруппа.Код = 1;
НоваяГруппа.Наименование = "Прочие";
НоваяГруппа.Записать();
 
НовыйСотрудник = Справочники.Сотрудники.СоздатьЭлемент();
НовыйСотрудник.Код = 100;
НовыйСотрудник.Наименование = "Иванов Иван Иванович";
НовыйСотрудник.Родитель = НоваяГруппа.Ссылка;
НовыйСотрудник.Записать();
 

Поиск в справочнике

Поиск элемента или группы производится методами НайтиПоКоду, НайтиПоНаименованию и НайтиПоРеквизиту. Эти методы возвращают ссылку на найденный элемент или пустую ссылку, если элемент не найден. Проверка на пустую ссылку производится методом Пустая, который возвращает значение Истина, если ссылка действительно пустая.

Следующий пример демонстрирует применение этих методов:

 

СотрСсылка = Справочники.Сотрудники.НайтиПоКоду(100);
Если НЕ СотрСсылка.Пустая() Тогда
	Сообщить("Найден сотрудник с кодом 100: " +
	СотрСсылка.Наименование);
КонецЕсли;
	//2-й вариант проверки на пустую ссылку
Если СотрСсылка = Справочники.Сотрудники.ПустаяСсылка() Тогда 
 
КонецЕсли;
 

Удаление элемента или группы справочника

Удаление элемента справочника производится с помощью объекта СправочникОбъект и только так. Другим способом удалить элемент справочника нельзя.

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

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

Следующий пример находит элемент с определенный кодом и демонстрирует два способа пометки на удаление и непосредственное удаление объекта:

 

СотрСсылка = Справочники.Сотрудники.НайтиПоКоду(100);
Если Не СотрСсылка.Пустая () Тогда
	СотрОбъект = Сотр.ПолучитьОбъект();
	
//1-й вариант пометки на удаление
	СотрОбъект.ПометкаУдапения = Истина;
	СотрОбъект.Записать();
 
	//2-й вариант пометки на удаление
	СотрОбъект.УстановитьПометкуУдаления(Истина);
 
	//3-й вариант: непосредственное удаление объекта
	СотрОбъект.Удалить();
КонецЕсли;
 

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

Открытие форм справочника

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

Рассмотрим возможные варианты открытия различных форм справочника:

 

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

 

Работа с табличным частями

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

Ниже показан пример обработки табличной части УтверждаемыеДокументы для справочника Сотрудники:

 

Сообщить("Выбранный сотрудник утверждает следующие документы:");
Для Каждого УтвДок Из ВыбСотр.УтверждаемыеДокументы Цикл
	Сообщить(УтвДок.Документ);
КонецЦикла;
 

Модуль объекта

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

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

В версии 8.0 существуют следующие события, обработчики которых располагаются в модуле справочника:

ПриКопировании

Событие возникает при создании элемента справочника копированием. В обработчике события ПриКопировании можно вмешаться в этот процесс и более интеллектуально заполнить некоторые реквизиты элемента справочника.

ПередЗаписью

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

ПриЗаписи

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

ПередУдалением

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

ПриУстановкеНовогоКода

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

ОбработкаЗаполнения

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

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

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

 

Процедура ПередЗаписью(Отказ)
	Если ЭтоГруппа = Ложь И ЕдиницаИзмерения.Пустая() Тогда
		Сообщить("Не указана основная ед. измерения!");
		Отказ = Истина;
	КонецЕсли;
КонецПроцедуры
 

Обратите внимание, что реквизит ЕдиницаИзмерения определен только для элементов справочника Номенклатура, поэтому сначала проверяется, что записывается именно элемент, а не группа (условие «ЭтоГруппа = Ложь»).

Также заметьте, что вторая часть условия в операторе Если не выполняется, если первое условие не выполнено. Это происходит, потому, что, как уже говорилось в главе «Встроенный язык», в  1С:Предприятии 8.0 применяется сокращенное вычисление условий. Если после вычисления части составного условия уже можно определить результат всего условия, то остальная часть условия не вычисляется. Если бы в нашем примере для группы вычислялась вторая часть условия, то выдавалась бы ошибка, поскольку реквизит ЕдиницаИзмерения для групп не определен. корм для кошек pronature . На станциях, реклама в метро.