Учебный курс: Подготовка на 1С:Специалист по платформе 1С:Предприятие 8.3
Решение задач по управляемым формам – тема № 10:
Форма подбора товаров в табличную часть документа
Ввод данных в табличные части документов может занимать достаточно много времени. Например, для оформления документа реализации пользователю нужно выбрать из справочника номенклатуру, проверить при помощи отчета, что эта позиция есть в остатках на складе, ввести количество и цену. Также может потребоваться заполнить другие сведения в зависимости от специфики используемой конфигурации. Ввод всех данных вручную может сильно замедлить процесс внесения документов в систему.
Поэтому часто перед разработчиками стоит задача упростить и ускорить ввод информации в систему. Можно предложить несколько вариантов решения поставленной задачи:
- Разработать отдельную форму для подбора товаров
- Использовать механизм перетаскивания (Drag-and-Drop) номенклатуры в документ реализации. Например, из вспомогательной таблицы значений, в которой находится номенклатура, заказанная клиентом.
Аналогичные способы можно встретить при работе с интернет-магазинами. Пользователь набирает товары в корзину, видит их цены, остатки на складах. После этого из корзины данные переносятся в заказ покупателя. Таким образом экономится время на внесение заказа в систему.
Рассмотрим процесс создания формы подбора, а также механизм переноса отобранных позиций номенклатуры в табличную часть документа. Механизм перетаскивания номенклатуры с использованием возможностей платформы «1С:Предприятие» разберем в следующем блоке материалов.
Задача на экзамене может быть сформулирована следующим образом:
Необходимо обеспечить возможность множественного подбора номенклатурных позиций в документе РасходнаяНакладная. Подбор должен осуществляться в отдельной форме.
В форме подбора нужно выводить список номенклатурных позиций. Пользователь должен видеть остатки товаров на складах и уже подобранные товары. В отдельных колонках необходимо отображать следующие остатки:
- Остаток на складе, указанном в документе продажи
- Остаток на главном складе
- Остаток на всех остальных складах.
Перенос подобранных товаров в документ реализации осуществляется при нажатии на кнопку «Перенести в документ».
Рассмотрим подробнее, как решить поставленную задачу.
Как пользователь будет выполнять подбор товаров
Прежде всего спроектируем, как будет открываться подбор из документа реализации и как будет организована форма подбора.
Для формирования документа реализации пользователь заполняет шапку документа: указывает покупателя, склад, с которого отгружаются товары. Затем пользователь переходит к заполнению табличной части. Чтобы избежать ручной работы с каждой строкой табличной части, пользователь открывает специальную форму подбора. Эта форма открывается при нажатии специальной кнопки «Открыть подбор».
В каркасной конфигурации для документа РасходнаяНакладная определим реквизит Склад (тип – СправочникСсылка.Склады).
Также в каркасной конфигурации создадим команду ОткрытьПодбор формы документа РасходнаяНакладная и разместим на форме специальную кнопку:
Рисунок 1 – Создание команды для открытия формы подбора
Форма подбора выглядит следующим образом:
Рисунок 2 – Логика работы формы подбора
Форма подбора состоит из двух таблиц:
- Список товаров, содержащий информацию об остатках на складах в нужных разрезах (верхняя таблица)
- Корзина подобранных товаров (нижняя таблица).
Пользователь анализирует остатки товаров на складах и выбирает нужную позицию двойным кликом мыши по строке в верхней таблице. Выбранная номенклатурная позиция попадает в корзину – отдельную таблицу в нижней части формы подбора. Если такой номенклатуры в корзине еще нет, то считаем, что в корзину добавили 1 штуку товара. Если выбранная номенклатура уже находится в корзине, то подобранное количество увеличивается на 1.
После нажатия на специальную кнопку «Перенести в документ» подобранные товары добавляются в табличную часть СписокНоменклатуры документа РасходнаяНакладная. После чего форма подбора закрывается.
Этапы решения задачи
Разделим задачу на отдельные этапы, которые и будем последовательно реализовывать:
- Создание формы подбора
- Отображение на форме подбора списка номенклатуры с остатками на складах
- Открытие формы подбора из формы документа
- Перенос выбранных товаров в корзину
- Передача подобранных товаров из корзины в табличную часть документа.
Что нужно учитывать при создании формы подбора
Создадим форму подбора для документа РасходнаяНакладная. Поскольку это вспомогательная форма, на ней не будет производиться редактирование самого документа реализации, не требуются стандартные кнопки Провести и закрыть, Записать и т.д.
Поэтому в конструкторе необходимо выбрать тип создаваемой формы – Произвольная форма. Определим имя формы – ФормаПодбора:
Рисунок 3 – Начало создания формы подбора
Как оптимальным способом отобразить на форме список товаров с остатками
На форме подбора необходимо вывести перечень номенклатуры с остатками на складах. Для отображения остатков на форме можно использовать несколько вариантов:
- Разместить на форме таблицу значений и заполнять ее при открытии формы
- Использовать динамический список.
С точки зрения производительности использование динамического списка для решения задачи более предпочтительно.
При работе с таблицей значений необходимо получить все данные из базы и загрузить их в таблицу значений. Справочник «Номенклатура» может быть очень большим и составлять десятки тысяч позиций. Всю эту информацию необходимо считать из базы и вывести на форму. Это может занять достаточно много времени. Пользователь в этот момент может посчитать, что программа зависла.
Динамический список специально был разработан для отображения объемных списков, больших массивов данных. Отличительной особенностью динамического списка является возможность считывать данные небольшими порциями – то есть только те данные, которые в данный момент требуется вывести на экран. Когда пользователь прокручивает список, система получает из базы данных очередную порцию информации и выводит ее на экран. Это намного быстрее и удобнее.
Поэтому для решения поставленной задачи используем динамический список.
Как правильно составить текст запроса динамического списка
Создадим реквизит формы подбора с типом динамический список. В списке будет отображаться перечень номенклатуры с остатками на складе:
Рисунок 4 – Создание реквизита формы подбора
Рисунок 5 – Свойства созданного реквизита формы подбора
Для хранения данных об остатках товаров в каркасной конфигурации предусмотрен регистр накопления ОстаткиНоменклатуры.
Создадим в каркасной конфигурации справочник Склады и добавим в регистр накопления ОстаткиНоменклатуры измерение Склад (тип – СправочникСсылка.Склады). Таким образом, структура регистра будет иметь следующий вид:
- Измерение:
- Номенклатура (тип – СправочникСсылка.Номенклатура)
- Склад (тип – СправочникСсылка.Склады).
- Ресурс:
- Количество (тип – Число, 10):
Рисунок 6 – Структура регистра ОстаткиНоменклатуры
Однако данных только регистра накопления ОстаткиНоменклатуры недостаточно. Например, если товар заведен в справочнике «Номенклатура», но никогда не поступал на склад, то в регистре накопления не будет записей по этой позиции. Но в форму подбора необходимо выводить абсолютно все товары. Поэтому для получения данных необходимо использовать две таблицы: справочник Номенклатура и виртуальную таблицу Остатки регистра накопления ОстаткиНоменклатуры.
Чтобы в тексте запроса динамического списка можно было использовать несколько таблиц, в настройках динамического списка необходимо установить галочку Произвольный запрос:
Рисунок 7 – Свойства списка ПроизвольныйЗапрос
Перейдем к настройке динамического списка при помощи ссылки Открыть:
Рисунок 8 – Переход к дальнейшим настройкам динамического списка
Откроется окно настройки динамического списка с возможностью использования конструктора запроса:
Рисунок 9 – Окно настройки динамического списка
Необходимо составить текст запроса. Для получения правильного результата принципиально важно выбрать подходящий тип соединения таблиц.
Требуется выводить все номенклатурные позиции. При этом остатки выводить только для тех товаров, которые есть в наличии на складах. Поэтому в конструкторе запроса используем левое внешнее соединение. При этом левая таблица – справочник Номенклатура, правая таблица – виртуальная таблица Остатки регистра накопления ОстаткиНоменклатуры:
Рисунок 10 – Использование левого соединения в запросе
Важно разделить остатки на складах. Требуется отдельно отображать следующие остатки:
- Остаток на складе, указанном в документе продажи
- Остаток на главном складе
- Остаток на всех остальных складах.
Чтобы среди элементов справочника Склады можно было выделить «Главный склад», создадим в конфигураторе предопределенный элемент справочника:
Рисунок 11 – Создание предопределенного элемента справочника «Склады»
Для разделения остатков на складах в тексте запроса используем конструкцию языка запросов ВЫБОР. В итоге получится следующий запрос динамического списка:
ВЫБРАТЬ СпрНоменклатура.Ссылка КАК Ссылка, СпрНоменклатура.ПометкаУдаления КАК ПометкаУдаления, СпрНоменклатура.Код КАК Код, СпрНоменклатура.Наименование КАК Наименование, СУММА(ВЫБОР КОГДА ОстаткиНоменклатурыОстатки.Склад = &Склад ТОГДА ОстаткиНоменклатурыОстатки.КоличествоОстаток ИНАЧЕ 0 КОНЕЦ) КАК Склад, СУММА(ВЫБОР КОГДА ОстаткиНоменклатурыОстатки.Склад = &ГлавныйСклад ТОГДА ОстаткиНоменклатурыОстатки.КоличествоОстаток ИНАЧЕ 0 КОНЕЦ) КАК ГлавныйСклад, СУММА(ВЫБОР КОГДА ОстаткиНоменклатурыОстатки.Склад = &Склад ИЛИ ОстаткиНоменклатурыОстатки.Склад = &ГлавныйСклад ТОГДА 0 ИНАЧЕ ОстаткиНоменклатурыОстатки.КоличествоОстаток КОНЕЦ) КАК ОстальныеСклады ИЗ Справочник.Номенклатура КАК СпрНоменклатура ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки КАК ОстаткиНоменклатурыОстатки ПО СпрНоменклатура.Ссылка = ОстаткиНоменклатурыОстатки.Номенклатура СГРУППИРОВАТЬ ПО СпрНоменклатура.Ссылка, СпрНоменклатура.Код, СпрНоменклатура.Наименование
Рисунок 12 – Текст запроса динамического списка
Для каждой номенклатуры в результате запроса должна выводиться только одна строка, в которой должны отображаться все остатки на складах отдельными колонками. Однако левое соединение в запросе может приводить к тому, что по одному товару может получиться несколько строк в результате запроса. Чтобы избежать дублирования номенклатуры, в тексте запроса нужно использовать группировку (ключевое слово СГРУППИРОВАТЬ).
Для идентификации складов в тексте запроса используется два параметра – Склад (это склад, указанный в документе реализации) и ГлавныйСклад. Устанавливать значение этих параметров необходимо при открытии формы подбора.
В следующем блоке материалов будет подробно рассмотрено: какой обработчик следует использовать и какой программный код для этого нужно реализовать.
Перенесем динамический список на форму, при этом оставим только необходимые колонки:
Рисунок 13 – Размещение динамического списка на форме
Как создать на форме корзину выбранных товаров
Выбранные пользователем товары должны отображаться на форме подбора. Для хранения этих данных создадим реквизит формы Корзина, являющийся таблицей значений. В таблицу значений добавим две колонки:
- Номенклатура (тип – СправочникСсылка.Номенклатура)
- Количество (тип – Число, 10).
Рисунок 14 – Создание реквизита формы подбора Корзина
Перенесем созданную таблицу значений на форму и расположим ее под списком товаров:
Рисунок 15 – Размещение на форме таблицы значений
Таким образом, внешний вид формы подбора настроен.
Как из формы документа открыть подбор
При проектировании решения задачи было определено, что форма подбора должна открываться из формы документа РасходнаяНакладная. Ранее с этой целью в каркасной конфигурации была создана команда формы документа РасходнаяНакладная с названием ОткрытьПодбор, и на форме документа РасходнаяНакладная была размещена специальная кнопка:
Рисунок 16 – Размещение кнопки «Открыть подбор» на форме документа «Расходная накладная»
Для созданной ранее команды ОткрытьПодбор (формы документа РасходнаяНакладная) создадим клиентский обработчик. В обработчике в форму подбора будем передавать склад, на котором нужно получить остатки, после чего открывать форму подбора:
&НаКлиенте Процедура ОткрытьПодбор(Команда) ПараметрыФормы = Новый Структура("Склад", Объект.Склад); ОткрытьФорму("Документ.РасходнаяНакладная.Форма.ФормаПодбора", ПараметрыФормы, Элементы.СписокНоменклатуры, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); КонецПроцедуры
В третьем параметре метода ОткрытьФорму указывается владелец открываемой формы. Владельцем формы подбора назначаем элемент управления – таблицу СписокНоменклатуры на форме. В дальнейшем именно владельцу формы будет отправлено оповещение о выполнении подбора. Значит, именно для владельца формы (таблицы СписокНоменклатуры) в дальнейшем необходимо будет создать обработчик, в котором и выполнить заполнение табличной части подобранными товарами.
Теперь в форме подбора нужно обработать переданный параметр и установить значения параметров динамического списка.
Склад, который указан в документе реализации, в форме подбора можно получить через параметр Склад, т.к. параметр с таким именем устанавливался при открытии этой формы. Для получения главного склада обращаемся к предопределенному элементу справочника Склады.
Установка параметра динамического списка может выполняться только на сервере, поэтому создаем обработчик события ПриСозданииНаСервере:
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) Список.Параметры.УстановитьЗначениеПараметра("Склад", Параметры.Склад); Список.Параметры.УстановитьЗначениеПараметра("ГлавныйСклад", Справочники.Склады.ГлавныйСклад); КонецПроцедуры
Для проверки работоспособности кода в каркасной конфигурации в справочнике «Склады» в пользовательском режиме добавим несколько элементов. Обеспечим проведение документа ПриходнаяНакладная по регистру накопления ОстаткиНоменклатуры и оприходуем несколько товаров на разные склады. Предварительно в документе ПриходнаяНакладная необходимо добавить реквизит Склад (тип – СправочникСсылка.Склады):
Рисунок 17 – Форма подбора
Форма подбора корректно открывается, на форме отображается список товаров с остатками на различных складах.
Как реализовать работу с корзиной
Далее в форме подбора нужно реализовать перенос выбранного товара в корзину. Для этого создадим обработчик события Выбор, которое возникает при двойном щелчке мышью по динамическому списку, содержащему перечень номенклатуры с остатками:
&НаКлиенте Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; НайденныеСтроки = Корзина.НайтиСтроки(Новый Структура("Номенклатура", ВыбраннаяСтрока)); Если НайденныеСтроки.Количество() > 0 Тогда НайденныеСтроки[0].Количество = НайденныеСтроки[0].Количество + 1; Иначе НоваяСтрока = Корзина.Добавить(); НоваяСтрока.Номенклатура = ВыбраннаяСтрока; НоваяСтрока.Количество = 1; КонецЕсли; КонецПроцедуры
Первым делом отключаем стандартную обработку события, чтобы при двойном щелчке мышью по списку номенклатуры не открывалась форма элемента справочника, а выполнялось только добавление номенклатуры в корзину.
В приведенном коде ВыбраннаяСтрока – это и есть элемент справочника Номенклатура, по которому был совершен двойной щелчок мышью. Проверяем, есть ли указанная номенклатура уже в корзине. Если такой номенклатуры в корзине нет, то добавляем в корзину новую строку, количество указываем равным 1. Если же такая номенклатура уже находится в корзине, то увеличиваем подобранное количество на 1.
Проверим работоспособность формы подбора в пользовательском режиме. Если в списке товаров дважды выбрать одну и ту же позицию, то в корзине будут отображаться 2 штуки этого товара:
Рисунок 18 – Заполнение корзины в форме подбора
Как перенести выбранные товары из корзины в документ
Когда пользователь подобрал в корзину все необходимые товары, необходимо перенести их в табличную часть документа реализации.
Для этого создадим команду формы подбора Перенести в документ, на форме подбора разместим соответствующую кнопку:
Рисунок 19 – Создание команды формы подбора «Перенести в документ»
Рисунок 20 – Размещение команды на форме
Рассмотрим два варианта передачи информации из формы подбора в форму документа.
Первый вариант – непосредственная передача. В форме документа можно создать таблицу значений, где будут размещаться данные о подобранных товарах. Форма подбора будет помещать данные в таблицу значений на форме документа:
Рисунок 21 – Схема работы формы подбора
Однако при этом осуществляется избыточное хранение данных. К тому же при передаче управления с Клиента на Сервер придется передавать эти дополнительные данные.
Оптимальнее было бы создать некое общее хранилище информации, куда форма подбора поместит данные, а форма документа сможет получить к ним доступ. В таком случае уменьшится объем передаваемых данных.
В платформе «1С:Предприятие» существует механизм временных хранилищ – специальных объектов, куда можно поместить данные при клиент-серверном взаимодействии.
Взаимодействие будет производиться следующим образом. Форма подбора будет помещать информацию о выбранных пользователем товарах во временное хранилище. В форму документа будет передан только адрес во временном хранилище, а не весь объем данных. При обращении по этому адресу форма документа сможет получить доступ к данным о подобранных товарах и выполнить обработку этих данных:
Рисунок 22 – Использование временного хранилища
Поэтому при решении задачи будем использовать временное хранилище.
При нажатии на кнопку Перенести в документ в форме подбора отобранные товары из корзины будут помещены во временное хранилище. Адрес во временном хранилище передадим в исходную форму документа реализации, из которой открывали форму подбора. После этого в табличную часть документа можно загрузить отобранные товары.
Код обработчика для команды ПеренестиВДокумент:
&НаКлиенте Процедура ПеренестиВДокумент(Команда) Адрес = ПоместитьТоварыИзКорзиныВоВременноеХранилище(); ОповеститьОВыборе(Адрес); КонецПроцедуры &НаСервере Функция ПоместитьТоварыИзКорзиныВоВременноеХранилище() Возврат ПоместитьВоВременноеХранилище(Корзина.Выгрузить()); КонецФункции
В приведенном коде на Сервере помещаем данные из корзины во временное хранилище. В результате выполнения функции ПоместитьВоВременноеХранилище получаем адрес во временном хранилище, где расположена выгруженная таблица значений.
Затем при помощи метода ОповеститьОВыборе из формы подбора посылаем оповещение владельцу формы о завершении подбора и передаем владельцу формы адрес во временном хранилище, где размещается созданная таблица значений. После этого форма подбора будет закрыта.
Владельцем формы подбора является таблица СписокНоменклатуры на форме документа РасходнаяНакладная. Именно этому элементу управления отправляется оповещение о выполнении подбора. Значит, именно для него требуется создать обработчик события ОбработкаВыбора, в котором выполнить заполнение табличной части подобранными товарами. Код процедуры СписокНоменклатурыОбработкаВыбора:
&НаКлиенте Процедура СписокНоменклатурыОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка) ОбработатьПодборНаСервере(ВыбранноеЗначение); КонецПроцедуры &НаСервере Процедура ОбработатьПодборНаСервере(АдресВременногоХранилища) Объект.СписокНоменклатуры.Загрузить(ПолучитьИзВременногоХранилища(АдресВременногоХранилища)); КонецПроцедуры
В процедуру СписокНоменклатурыОбработкаВыбора в качестве параметра ВыбранноеЗначение передается адрес во временном хранилище, где располагается таблица подобранных товаров. Эту таблицу значений затем загружаем в табличную часть документа реализации.
Проверим работу программного кода в пользовательском режиме. Создадим новый документ РасходнаяНакладная. Заполним шапку документа, укажем, с какого склада будет выполняться отгрузка. Откроем форму подбора. В ней отображаются товары, для которых указывается остаток на выбранном складе. Наберем в корзину требуемый товар:
Рисунок 23 – Форма подбора с заполненной корзиной
При нажатии на кнопку «Перенести в документ» выбранные позиции загружаются в документ РасходнаяНакладная:
Рисунок 24 – Подобранные товары в табличной части документа «Расходная накладная»
Итак, поставленная задача выполнена.
Комментарии закрыты