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

Программная работа со справочниками, обработки, простые отчеты

Теперь займемся кодом. Нам, в дополнение к клиентской процедуре команды СоздатьЭлементСправочника, понадобится серверная процедура или функция, которая и занимается созданием элемента. Обратиться к объекту СправочникМенеджер для конкретного справочника можно различными способами. Предположим, мы заранее знаем, с каким справочником нам нужно работать (например, это – справочник Номенклатура). Для того, чтобы вызвать метод этого справочника СоздатьЭлемент, нам понадобится такая конструкция:

НовыйЭлемент=Справочники.Номенклатура.СоздатьЭлемент();

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

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

НовыйЭлемент = Справочники[ИмяСправочника].СоздатьЭлемент();

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

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

&НаКлиенте
Процедура СоздатьЭлементСправочника(Команда)
  КодНовогоЭлемента=СоздатьЭлементСправочникаНаСервере();  
  Сообщить("В справочнике "+ИмяСправочника+" создан элемент 
   "+НаименованиеЭлемента + " с автоматически присвоенным кодом: 
     "+КодНовогоЭлемента);
КонецПроцедуры

Функция СоздатьЭлементСправочникаНаСервере()
  НовыйЭлемент = Справочники[ИмяСправочника].СоздатьЭлемент();
  НовыйЭлемент.Наименование=НаименованиеЭлемента;
  НовыйЭлемент.Записать();
  Возврат (НовыйЭлемент.Код);
КонецФункции

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

Вот, каковы результаты работы этого кода, рис. 5.10.

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

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

Функция СоздатьЭлементСправочникаНаСервере создает новый элемент, заполняет его свойство Наименование, после чего записывает его и возвращает код нового элемента. Код формируется системой автоматически. Если заглянуть в справочник ЕдиницыИзмерения – там, действительно, будет создан новый элемент с заданным нами наименованием.

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

&НаКлиенте
Процедура ПометитьНаУдалениеВсеЭлементыСправочника(Команда)
  ПометитьНаУдаление();
КонецПроцедуры

Процедура ПометитьНаУдаление()
  СчетчикПомеченных = 0;
  Выборка = Справочники[ИмяСправочника].Выбрать();
  Пока Выборка.Следующий() Цикл
    Элемент=Выборка.ПолучитьОбъект();
    Если НЕ Элемент.ЭтоГруппа Тогда
      Элемент.УстановитьПометкуУдаления(Истина);
      СчетчикПомеченных=СчетчикПомеченных+1;
    КонецЕсли;
  КонецЦикла;
  Сообщить("В справочнике "+ИмяСправочника+" помечено на удаление"+СчетчикПомеченных+" элементов");
КонецПроцедуры

В процедуре ПометитьНаУдаление() мы сначала присваиваем 0 переменной СчетчикПомеченых – с ее помощью мы будем подсчитывать количество помеченных на удаление элементов справочника. В качестве имени справочника мы используем уже знакомый по прошлой процедуре реквизит ИмяСправочника. Конструкция Справочники[ИмяСправочника] позволяет нам обратиться к объекту типа СправочникМенеджер для заданного справочника. Этот объект имеет метод Выбрать(). Метод Выбрать() позволяет сформировать выборку элементов справочника по заданным условиям. Мы, в данном случае, условий не задаем, то есть в выборку попадают все элементы и группы справочника – метод возвращает значение типа СправочникВыборка. СправочникВыборка не содержит элементов справочника, объект этого типа можно считать способом доступа к элементам, способом их перебора. При обращении к выборке обход элементов осуществляется динамически, данные считываются из базы порциями, что позволяет эффективно использовать данный механизм даже для работы с большими справочниками, так как все элементы, входящие в выборку (соответствующие условиям выборки) в память не загружаются.

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

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

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

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

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

Переработанная форма

увеличить изображение
Рис. 5.11. Переработанная форма

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

&НаКлиенте
Процедура НайтиЗаданныйЭлемент(Команда)
  НайтиЗаданныйЭлементНаСервере();
КонецПроцедуры

Процедура НайтиЗаданныйЭлементНаСервере()
  СсылкаНаЭлемент=Справочники[ИмяСправочника].НайтиПоНаименованию(НаименованиеЭлемента);
  Если СсылкаНаЭлемент=Справочники[ИмяСправочника].ПустаяСсылка() Тогда
    Сообщить ("В справочнике "+ИмяСправочника+" нет элемента "+НаименованиеЭлемента);
  Иначе
    Элемент=СсылкаНаЭлемент.ПолучитьОбъект();
    СтароеНаименование=Элемент.Наименование;
    Элемент.Наименование=ВРег(Элемент.Наименование);
    Элемент.Записать();
    Сообщить("Элемент справочника "+ИмяСправочника+" 
      с кодом "+Элемент.Код+" найден, наименование изменено 
        с "+СтароеНаименование+" на "+Элемент.Наименование);
  КонецЕсли;
КонецПроцедуры

В процедуре НайтиЗаданныйЭлементНаСервере() мы обращаемся к методу НайтиПоНаименованию() объекта СправочникМенеджер, полученному посредством конструкции Справочники[ИмяСправочника]. Этот метод, среди прочих, принимает обязательный параметр, который должен содержать строку с наименованием искомого объекта. Мы передаем ему реквизит с искомой строкой. Если метод нашел элемент, наименование которого соответствует этой строке, он вернет ссылку на элемент с типом СправочникСсылка.ИмяСправочника. Если нет – будет возвращена пустая ссылка. Сравнивая возвращенную ссылку с пустой ссылкой на элемент справочника, который мы обрабатываем, мы принимаем решение о том, сообщить ли пользователю об отсутствии искомого элемента, или, если элемент все же найден, переходим от ссылки на него к объекту (метод ПолучитьОбъект() объекта СправочникСсылка), выполняем с ним необходимые действия и выводим соответствующее сообщение пользователю. Вот как выглядит работа этого кода, рис. 5.12.

Результат работы кода по поиску и редактированию элемента справочника

Рис. 5.12. Результат работы кода по поиску и редактированию элемента справочника

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

СправочникиМенеджер – доступен через свойство глобального контекста Справочники. Предназначен для управления справочниками, позволяет получить доступ к объекту СправочникМенеджер конкретного справочника.

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

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

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

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

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

Иногда возникает путаница с понятиями "данные, хранящиеся в справочнике" и "метаданные справочника". Данные справочника – это элементы справочника – например, в справочнике ЕдиницыИзмерения может храниться элемент с наименованием "Штука", и кодом "0001". Метаданные – это, как принято говорить, "данные о данных". То есть, например – это имя справочника, набор его реквизитов, список владельцев справочника и так далее. Метаданные, другими словами – это то, что мы редактируем, работая в Конфигураторе, а данные – это то, с чем мы взаимодействуем, работая со справочником в пользовательском режиме. При работе со справочником как с объектом метаданных, мы можем обращаться к свойствам этого объекта только для чтения – операции по модификации метаданных производятся в визуальном режиме с помощью Конфигуратора. При программной работе с данными справочника, мы имеем полный набор инструментов для управления этими данными.

Есть еще один тип данных, имеющий отношение к справочникам, о котором мы здесь не упоминали. Это – СправочникСписок – он используется для управления списком элементов справочника в табличных полях.

Обсудив программную работу со справочниками, перейдем к разговору об отчетах

Лариса Дятчина
Лариса Дятчина

Код 

&НаКлиенте

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

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

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

КонецЕсли;

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

 

&НаСервере

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

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

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

&НаСервере

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

 

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

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

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

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

 

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

максим матасов
максим матасов
Алексей Ломакин
Алексей Ломакин
Россия, Владимир