1с 8.3 множественный выбор из документов. Реализация подбора в управляемых формах. Отборы = Новый Структура("Владелец", Контрагент)

Добрый день.

Сегодня мы поговорим о том, как программно открывать формы выбора в новом управляемом интерфейсе.

Раньше в "обычном приложении" мы писали так:

форма = Справочник.номенклатура.ПолучитьФормуВыбора();

результатВыбора = форма.открытьМодальНО();

Между этими операторами мы могли изменить свойства формы, например задать отбор. Мы могли указать конкретную форму по имени. Могли изменять её внешний вид, обращаясь к свойствам элементав формы по их имени через точку (форма.Кнопка1.Видимость = Ложь;)

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

Итак приступим.

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

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

Вот пример использования:

Перем ВыбТМЦ;

МассивТипов = Новый Массив;

ОписаниеТиповТМЦ = Новый ОписаниеТипов(Массив);

Если ВвестиЗначение(ВыбТМЦ, "Выберите номенклатуру", ОписаниеТиповТМЦ) Тогда

//Обрабаботка выбранного значения

КонецЕсли;

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

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

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

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

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

Итак, смотрим описание процедуры, у неё 4 параметра. В первом мы указываем строку с полным путём к форме "Справочник.ДоговорыКонтрагентов.ФормаВыбора". Во втором мы указываем параметры выбора, о них чуть ниже. В третий - владельца, это форма или поле выбора, которое получит в себя результат выбора, мы его не заполняем. Четвертый параметр в нашем слечае тоже не используется.

Итак, для простого выбора нам подойдет строка:

&НаКлиенте

Процедура Команда1(Команда)

рез = ОткрытьФормуМодально("Справочник.ДоговорыКонтрагентов.ФормаВыбора");

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

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

Чтобы задать отбор, нам поможет второй параметр.

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

В моем примере я нарисовал в обработке поле выбора, ссылающееся на реквизит формы обработки "контрагент" с типом данных "СправочникСсылка.Контрагенты ". и написал следующий кусок кода:

&НаКлиенте

Процедура Команда1(Команда)

Отборы = Новый Структура("Владелец", Контрагент);

ПараметрыВыбора = Новый Структура("Отбор", Отборы);

рез = ОткрытьФормуМодально("Справочник.ДоговорыКонтрагентов.ФормаВыбора",ПараметрыВыбора);

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

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

На сегодня все, спасибо за внимание.

В данной статье рассматривается технология реализации подбора на платформе 1С 8.2. Статья не претендует на академизм, просто столкнувшись с рядом проблем и не нашедшим «правильной» методологии решения (возможно плохо искал), решил пройти этот путь самостоятельно, естественно пользуясь различными источниками. В основном я опираюсь на материалы мастер-групп Базового курса «Профессиональное программирование в 1С» Евгения Гилева и Насипова Фарита, участником которого я являюсь, а также соответствующей литературы (М.Г. Радченко, Е.Ю. Хрусталева Практическое пособие разработчика).

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

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

Настраиваем запрос для реквизита Товары. Здесь по идее все просто с помощью конструктора берем два справочника и виртуальную таблицу Остатков регистра Остатки товара. Если нужно видеть весь товар, то используем левое соединение Товаров с остальными источниками, если только с остатками, то полное соединение с регистром:
Код 1C v 8.2 УП ВЫБРАТЬ

Серии.СрокГодности,

ЕСТЬNULL(ТоварыНаСкладеОстатки.КоличествоОстаток, 0) КАК Количество

Справочник.Товары КАК Товары

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Серии КАК Серии

ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладе.Остатки(, Склад = &Склад) КАК ТоварыНаСкладеОстатки

ПО (ТоварыНаСкладеОстатки.Товар = Товары.Ссылка)

УПОРЯДОЧИТЬ ПО

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

И так, возвращаемся в нормальное русло решение задачи.

Для того чтобы открыть созданную форму подбора, в управляемой форме документы Продажа товара создаем команду подбор, размещаем на форме о генерируем обработчик, в котором нам необходимо открыть форму. Так как форма должна обеспечивать множественный выбор и отбор по складу, то создаем структуру параметров формы. И открываем форму соответствующей командой.
Код 1C v 8.2 УП
&НаКлиенте

Процедура Подбор(Команда)

ПараметрыПодбора = Новый Структура("ЗакрыватьПриВыборе, МножественныйВыбор, Склад", Ложь, Истина, Объект.Склад);

ОткрытьФорму("Документ.ПродажаТоваров.Форма.ФормаПодбора", ПараметрыПодбора, Элементы.Товары);

КонецПроцедуры
Соответственно в форме подбора при создании заполняем параметр запроса склад из параметров формы:
Код 1C v 8.2 УП &НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Товары.Параметры.УстановитьЗначениеПараметра("Склад",Параметры.Склад);

Склад = Параметры.Склад;

КонецПроцедуры
Теперь необходимо реализовать функционал формы подбора. При выборе соответствующей строки она должна переносится в таблицу значений, так же должен работать механизм перетаскивания. Для решения первой задачи необходимо создать обработчик события Выбор нашего динамического списка.
Код 1C v 8.2 УП &НаКлиенте

Процедура ТоварыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)

СтандартнаяОбработка = Ложь;

Для каждого НомерСтроки Из ВыбраннаяСтрока Цикл

ТекСтрока = Элемент.ДанныеСтроки(НомерСтроки);

Строка.Количество = 1;

Пока Строка.Количество > ТекСтрока.Количество Цикл

КонецЦикла;

КонецЕсли;

КонецЦикла;

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

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

Так же необходимо создать обработчик события Перетаскивание для элемента формы ВыбранныеТовары.
Код 1C v 8.2 УП &НаКлиенте

Процедура ВыбранныеТоварыПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)

Для каждого НомерСтроки Из ПараметрыПеретаскивания.Значение Цикл

ТекСтрока = Элементы.Товары.ДанныеСтроки(НомерСтроки);

Поиск = Новый Структура("Товар, Серия",ТекСтрока.Товар,ТекСтрока.Серия);

МассивСтрок = ВыбранныеТовары.НайтиСтроки(Поиск);

Если МассивСтрок.Количество() = 0 Тогда

Строка = ВыбранныеТовары.Добавить();

Строка.Товар = ТекСтрока.Товар;

Строка.Серия = ТекСтрока.Серия;

Строка.СрокГодности = ТекСтрока.СрокГодности;

Строка.Количество = 1;

ВвестиЧисло(Строка.Количество, "Введите количество");

Пока Строка.Количество > ТекСтрока.Количество Цикл

ВвестиЧисло(Строка.Количество, "Введите верное количество!");

КонецЦикла;

КонецЕсли;

КонецЦикла;

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

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

На рисунке приведен внешний вид формы подбора:

Для завершения подбора создана команда формы, с обработчиком, выполняющим оповещение о выборе:
Код 1C v 8.2 УП &НаКлиенте

Процедура Перенести(Команда)

ОповеститьОВыборе(ВыбранныеТовары);

Закрыть();

КонецПроцедуры
Соответственно, в форме документа реализован обработчик события ОбработкаВыбора:
Код 1C v 8.2 УП &НаКлиенте

Процедура ТоварыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)

Если ВыбранноеЗначение.Количество() > 0 И Объект.Товары.Количество() > 0 Тогда

Режим = РежимДиалогаВопрос.ДаНет;

Текст = "Очистить табличную часть?";

Ответ = Вопрос(Текст, Режим, 0);

Если Ответ = КодВозвратаДиалога.Да Тогда

Объект.Товары.Очистить();

КонецЕсли;

КонецЕсли;

Для каждого Подбор Из ВыбранноеЗначение Цикл

Строка = Объект.Товары.Добавить();

Строка.Товар = Подбор.Товар;

Строка.Серия = Подбор.Серия;

Строка.Количество = Подбор.Количество;

КонецЦикла;

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

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

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

Отбор на управляемых формах в 1С 8.3

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

  • Установка отбора в конфигураторе

Установка отбора в пользовательском режиме

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

Для установки отбора в режиме предприятия необходимо вызвать команду «Настроить список».

Откроется окно.


На вкладке «отбор» представлен список полей, который есть в текущем списке. Выбираем поля списка, по которым будем фильтровать. Сделать это можно двойным кликом или используя drag and drop.


Задаем вид сравнения и значение, жмем «Завершить редактирование», отбор установлен.


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


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


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

Установка отбора в конфигураторе

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

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


Откроется окно.


Отбор задается так же, как в пользовательском режиме.

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


Динамический (программный) отбор

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

Методы

Если в разрабатываемой конфигурации присутствует подсистема БСП «БазоваяФункциональность», программный отбор в динамическом списке можно установить используя типовой метод:

ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка()

Сигнатура данного метода:

ДинамическийСписок Тип: ДинамическийСписок – Список, в котором требуется установить отбор.

ИмяПоля Тип: Строка – Поле, по которому необходимо установить отбор.

ПравоеЗначение Тип: Произвольный – Значение отбора (Необязательный. Значение по умолчанию: Неопределено. Внимание! Если передать Неопределено, то значение не будет изменено).

ВидСравнения Тип: ВидСравненияКомпоновкиДанных – Условие отбора.

Представление Тип: Строка – Представление элемента компоновки данных (Необязательный. Значение по умолчанию: Неопределено. Если указано, то выводится только флажок использования с указанным представлением (значение не выводится). Для очистки, чтобы значение снова выводилось, следует передать пустую строку).

Использование Тип: Булево – Флажок использования этого отбора (Необязательный. Значение по умолчанию: Неопределено).

РежимОтображения Тип: РежимОтображенияЭлементаНастройкиКомпоновкиДанных – Способ отображения этого отбора пользователю. Возможные значения:

  • РежимОтображенияЭлементаНастройкиКомпоновкиДанных.БыстрыйДоступ – В группе быстрых настроек над списком.
  • РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Обычный – В настройка списка (в подменю Еще).
  • РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный – Запретить пользователю менять этот отбор.

ИдентификаторПользовательскойНастройки Тип: Строка – Уникальный идентификатор этого отбора (Используется для связи с пользовательскими настройками).

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

ОбщегоНазначенияКлиентСервер. УдалитьЭлементыГруппыОтбораДинамическогоСписка ()

Сигнатура данного метода:

ДинамическийСписок Тип: ДинамическийСписок – реквизит формы, для которого требуется установить отбор.

ИмяПоля Тип: Строка – имя поля компоновки (не используется для групп).

Представление Тип: Строка – представление поля компоновки.

В случае отсутствие в системе БСП отбор можно установить самостоятельно, используя объект ПолеКомпоновкиДанных.

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

Данный отбор отберет строки, в которых значение «ФИО» = «Иванов».

Для использования логических «И», «ИЛИ», «НЕ» предназначен тип данных ГруппаЭлементовОтбораКомпоновкиДанных

ГруппаОтбора = Список.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных")); ГруппаОтбора.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИЛИ; ЭлементОтбора = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ФИО"); ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; ЭлементОтбора.ПравоеЗначение = "Иванов"; ЭлементОтбора = ГруппаОтбора.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ФИО"); ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; ЭлементОтбора.ПравоеЗначение = "Петров";

Данный отбор отберет строки, в которых значение «ФИО» = «Иванов» или «Петров».

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


Для этого к тексту запроса добавляем условие «ГДЕ Истина»…


Как видно, такой подход более компактный с точки зрения написания кода. Чем сложнее условия отбора в табличной части мы хотим установить, тем более громоздким будет вариант с использованием отбора через ЭлементОтбораКомпоновкиДанных. Однако у примера с изменением текста запроса есть свои недостатки – эта реализация не устойчива к изменениям кода. Например, вы сделали такую реализацию и забыли, но если в будущем вы захотите модифицировать текст запроса, добавив в него какой-либо оператор после ГДЕ (УПОРЯДОЧИТЬ, СГРУППИРОВАТЬ), вам нужно не забыть про то, что в программном коде есть:

Список.ТекстЗапроса = Список.ТекстЗапроса + " И СправочникПользователи.ФИО В(""Иванов"",""Петров"")";

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

ГДЕ (НЕ &ОтборУстановлен ИЛИ СправочникПользователи.ФИО В (&РазрешенныеФИО))

Список.Параметры.УстановитьЗначениеПараметра("ОтборУстановлен", ФИО.Количество() > 0); Список.Параметры.УстановитьЗначениеПараметра("РазрешенныеФИО", ФИО);

Тут ФИО – массив.

Ка видно, 2 строчки кода против 10. Какой из способов выбрать, зависит от конкретной прикладной задачи.

Реализация подбор на основе управляемых форм 1С 8.2

В данной статье рассматривается технология реализации подбора на платформе 1С 8.2. Статья не претендует на академизм, просто столкнувшись с рядом проблем и не нашедшим «правильной» методологии решения (возможно плохо искал), решил пройти этот путь самостоятельно, естественно пользуясь различными источниками. В основном я опираюсь на материалы мастер-групп Базового курса «Профессиональное программирование в 1С» Евгения Гилева и Насипова Фарита, участником которого я являюсь, а также соответствующей литературы (М.Г. Радченко, Е.Ю. Хрусталева Практическое пособие разработчика).

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

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

Товары - Динамический список, в свойствах ставим галочку произвольный запрос.

Выбор - таблица значений (колонки Товар, Серия - тип ссылки на соответствующие справочники, срок годности, количество - дата, число).

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

ВЫБРАТЬ Товары.Ссылка КАК Товар, Серии.Ссылка КАК Серия, Серии.СрокГодности, ЕСТЬNULL(ТоварыНаСкладеОстатки.КоличествоОстаток, 0) КАК Количество ИЗ Справочник.Товары КАК Товары ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Серии КАК Серии ПО (Серии.Владелец.Ссылка = Товары.Ссылка) ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладе.Остатки(, Склад = &Склад) КАК ТоварыНаСкладеОстатки ПО (ТоварыНаСкладеОстатки.Товар = Товары.Ссылка) УПОРЯДОЧИТЬ ПО Товар, СрокГодности

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

И так, возвращаемся в нормальное русло решение задачи.

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

&НаКлиенте Процедура Подбор(Команда) ПараметрыПодбора = Новый Структура("ЗакрыватьПриВыборе, МножественныйВыбор, Склад", Ложь, Истина, Объект.Склад); ОткрытьФорму("Документ.ПродажаТоваров.Форма.ФормаПодбора", ПараметрыПодбора, Элементы.Товары); КонецПроцедуры

Соответственно в форме подбора при создании заполняем параметр запроса склад из параметров формы:

&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Товары.Параметры.УстановитьЗначениеПараметра("Склад",Параметры.Склад); Склад = Параметры.Склад; КонецПроцедуры

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

&НаКлиенте Процедура ТоварыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; Для каждого НомерСтроки Из ВыбраннаяСтрока Цикл ТекСтрока = Элемент.ДанныеСтроки(НомерСтроки); Поиск = Новый Структура("Товар, Серия",ТекСтрока.Товар,ТекСтрока.Серия); МассивСтрок = ВыбранныеТовары.НайтиСтроки(Поиск); Если МассивСтрок.Количество() = 0 Тогда Строка = ВыбранныеТовары.Добавить(); Строка.Товар = ТекСтрока.Товар; Строка.Серия = ТекСтрока.Серия; Строка.СрокГодности = ТекСтрока.СрокГодности; Строка.Количество = 1; ВвестиЧисло(Строка.Количество, "Введите количество"); Пока Строка.Количество >

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

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

Так же необходимо создать обработчик события Перетаскивание для элемента формы ВыбранныеТовары.

&НаКлиенте Процедура ВыбранныеТоварыПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле) Для каждого НомерСтроки Из ПараметрыПеретаскивания.Значение Цикл ТекСтрока = Элементы.Товары.ДанныеСтроки(НомерСтроки); Поиск = Новый Структура("Товар, Серия",ТекСтрока.Товар,ТекСтрока.Серия); МассивСтрок = ВыбранныеТовары.НайтиСтроки(Поиск); Если МассивСтрок.Количество() = 0 Тогда Строка = ВыбранныеТовары.Добавить(); Строка.Товар = ТекСтрока.Товар; Строка.Серия = ТекСтрока.Серия; Строка.СрокГодности = ТекСтрока.СрокГодности; Строка.Количество = 1; ВвестиЧисло(Строка.Количество, "Введите количество"); Пока Строка.Количество > ТекСтрока.Количество Цикл ВвестиЧисло(Строка.Количество, "Введите верное количество!"); КонецЦикла; КонецЕсли; КонецЦикла; КонецПроцедуры

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

На рисунке приведен внешний вид формы подбора:

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

&НаКлиенте Процедура Перенести(Команда) ОповеститьОВыборе(ВыбранныеТовары); Закрыть(); КонецПроцедуры

Соответственно, в форме документа реализован обработчик события ОбработкаВыбора:

&НаКлиенте Процедура ТоварыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка) Если ВыбранноеЗначение.Количество() > 0 И Объект.Товары.Количество() > 0 Тогда Режим = РежимДиалогаВопрос.ДаНет; Текст = "Очистить табличную часть?"; Ответ = Вопрос(Текст, Режим, 0); Если Ответ = КодВозвратаДиалога.Да Тогда Объект.Товары.Очистить(); КонецЕсли; КонецЕсли; Для каждого Подбор Из ВыбранноеЗначение Цикл Строка = Объект.Товары.Добавить(); Строка.Товар = Подбор.Товар; Строка.Серия = Подбор.Серия; Строка.Количество = Подбор.Количество; КонецЦикла; КонецПроцедуры

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

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

Реализация формы подбора в 1С 8.2

В данной статье рассматривается технология реализации подбора на платформе 1С 8.2. Статья не претендует на истину в последней инстанции, просто столкнувшись с рядом проблем и не нашедшим «правильной» методологии решения (возможно плохо искал), решил пройти этот путь самостоятельно, естественно пользуясь различными источниками. В основном я опираюсь на материалы мастер-групп Базового курса «Профессиональное программирование в 1С» Евгения Гилева и Насипова Фарита, участником которого я являюсь, а также соответствующей литературы (М.Г. Радченко, Е.Ю. Хрусталева Практическое пособие разработчика).

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

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

Товары - Динамический список, в свойствах ставим галочку произвольный запрос.

ВыбранныеТовары - таблица значений (колонки Товар, Серия - тип ссылки на соответствующие справочники, срок годности, количество - дата, число).

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

ВЫБРАТЬ
Товары.Ссылка КАК Товар,
Серии.Ссылка КАК Серия,
Серии.СрокГодности КАК СрокГодности,
ЕСТЬNULL(ТоварыНаСкладеОстатки.КоличествоОстаток, 0) КАК Количество
ИЗ
Справочник.Товары КАК Товары
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Серии КАК Серии
ПО (Серии.Владелец.Ссылка = Товары.Ссылка)
ПОЛНОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладе.Остатки(, Склад = &Склад) КАК ТоварыНаСкладеОстатки
ПО (ТоварыНаСкладеОстатки.Товар = Товары.Ссылка)
УПОРЯДОЧИТЬ ПО
Товар,
СрокГодности

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

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

И так, возвращаемся в нормальное русло решение задачи.

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

&НаКлиенте
Процедура Подбор(Команда)
ПараметрыПодбора = Новый Структура("ЗакрыватьПриВыборе, МножественныйВыбор,Склад", Ложь, Истина, Объект.Склад);
ОткрытьФорму("Документ.ПродажаТоваров.Форма.ФормаПодбора", ПараметрыПодбора, Элементы.Товары);
КонецПроцедуры

Соответственно в форме подбора при создании заполняем параметр запроса склад из параметров формы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Товары.Параметры.УстановитьЗначениеПараметра("Склад",Параметры.Склад);
Склад = Параметры.Склад;
КонецПроцедуры

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

&НаКлиенте
Процедура ТоварыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Для каждого НомерСтроки Из ВыбраннаяСтрока Цикл
ТекСтрока = Элемент.ДанныеСтроки(НомерСтроки);






Строка.Количество = 1;

Пока Строка.Количество > ТекСтрока.Количество Цикл

КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры

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

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

Так же необходимо создать обработчик события Перетаскивание для элемента формы ВыбранныеТовары.

&НаКлиенте
Процедура ВыбранныеТоварыПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
Для каждого НомерСтроки Из ПараметрыПеретаскивания.Значение Цикл
ТекСтрока = Элементы.Товары.ДанныеСтроки(НомерСтроки);
Поиск = Новый Структура("Товар, Серия",ТекСтрока.Товар,ТекСтрока.Серия);
МассивСтрок = ВыбранныеТовары.НайтиСтроки(Поиск);
Если МассивСтрок.Количество() = 0 Тогда
Строка = ВыбранныеТовары.Добавить();
Строка.Товар = ТекСтрока.Товар;
Строка.Серия = ТекСтрока.Серия;
Строка.СрокГодности = ТекСтрока.СрокГодности;
Строка.Количество = 1;
ВвестиЧисло(Строка.Количество, "Введите количество");
Пока Строка.Количество > ТекСтрока.Количество Цикл
ВвестиЧисло(Строка.Количество, "Введите верное количество!");
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры

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

На рисунке приведен внешний вид формы подбора:

(23.35 килобайт) Кол-во скачиваний: 263

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

&НаКлиенте
Процедура Перенести(Команда)
ОповеститьОВыборе(ВыбранныеТовары);
Закрыть();
КонецПроцедуры

Соответственно, в форме документа реализован обработчик события ОбработкаВыбора:

&НаКлиенте
Процедура ТоварыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
Если ВыбранноеЗначение.Количество() > 0 И Объект.Товары.Количество() > 0 Тогда
Режим = РежимДиалогаВопрос.ДаНет;
Текст = "Очистить табличную часть?";
Ответ = Вопрос(Текст, Режим, 0);
Если Ответ = КодВозвратаДиалога.Да Тогда
Объект.Товары.Очистить();
КонецЕсли;
КонецЕсли;
Для каждого Подбор Из ВыбранноеЗначение Цикл
Строка = Объект.Товары.Добавить();
Строка.Товар = Подбор.Товар;
Строка.Серия = Подбор.Серия;
Строка.Количество = Подбор.Количество;
КонецЦикла;

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



Последние материалы раздела:

Сколько в одном метре километров Чему равен 1 км в метрах
Сколько в одном метре километров Чему равен 1 км в метрах

квадратный километр - — Тематики нефтегазовая промышленность EN square kilometersq.km … квадратный километр - мера площадей метрической системы...

Читы на GTA: San-Andreas для андроид
Читы на GTA: San-Andreas для андроид

Все коды на GTA San Andreas на Андроид, которые дадут вам бессмертность, бесконечные патроны, неуязвимость, выносливость, новые машины, парашют,...

Классическая механика Закон сохранения энергии
Классическая механика Закон сохранения энергии

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