Задачи по оперативному учету, связанные с хранением специфического товара (в данном случае — живых рыбок), требуют грамотного проектирования архитектуры базы данных. Основная сложность здесь заключается не только в самом учете остатков, но и в автоматизации бизнес-процессов, таких как автоматический подбор места хранения (аквариума) на основании параметров номенклатуры. Разберем подробно, как реализовать такую систему на платформе «1С:Предприятие».
Прежде чем переходить к программному коду, проанализируем необходимые объекты метаданных. Для решения задачи нам понадобятся следующие объекты:
Номенклатура (или Рыбы): Здесь мы будем хранить виды рыб (например, Гуппи, Меченосец, Скалярия).Размеры: Поскольку набор размеров обычно фиксирован (S, M, L, XL), использование перечисления будет более оправданным, чем создание отдельного справочника. Это упростит логику и исключит дублирование данных пользователями.Аквариумы: Этот объект будет выступать в роли мест хранения. В зависимости от масштаба системы, аквариумы могут быть как отдельным справочником, так и элементами справочника Склады (или ячейками склада при использовании адресного хранения).Важный момент: согласно условию ТЗ, одна комбинация «Вид рыбы + Размер» жестко закреплена за одним аквариумом. Это ключевое ограничение, которое мы должны заложить в логику системы.
Для того чтобы система «понимала», в какой именно аквариум нужно поместить рыбку определенного размера, нам необходимо создать механизм хранения этих связей. Оптимальным решением здесь является Регистр сведений (например, СвязьРыбаАквариум).
Настроим структуру регистра:
ВидРыбы (тип: СправочникСсылка.Рыбы), Размер (тип: ПеречислениеСсылка.Размеры).Аквариум (тип: СправочникСсылка.Аквариумы).Использование регистра сведений позволяет нам легко менять «прописку» рыб без изменения кода. Рассмотрим ситуацию: если завтра Гуппи размера L решат переселить из Аквариума №1 в Аквариум №5, пользователю достаточно будет изменить запись в этом регистре.
Теперь разберем, как сделать так, чтобы при выборе рыбки и ее размера в табличной части документа поле Аквариум заполнялось само. Рассмотрим по шагам работу в модуле формы документа.
Нам необходимо создать обработчики событий ПриИзменении для колонок ВидРыбы и Размер. Логика будет следующей: при изменении любого из этих полей система должна проверить, заполнены ли оба параметра, и если да — выполнить поиск в регистре сведений.
Пример программного кода для реализации этой логики:
&НаКлиенте
Процедура СписокРыбВидРыбыПриИзменении(Элемент)
СтрокаТЧ = Элементы.СписокРыб.ТекущиеДанные;
ЗаполнитьАквариум(СтрокаТЧ);
КонецПроцедуры
&НаКлиенте
Процедура СписокРыбРазмерПриИзменении(Элемент)
СтрокаТЧ = Элементы.СписокРыб.ТекущиеДанные;
ЗаполнитьАквариум(СтрокаТЧ);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьАквариумИзРегистра(ВидРыбы, Размер)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СвязьРыбаАквариум.Аквариум КАК Аквариум
|ИЗ
| РегистрСведений.СвязьРыбаАквариум КАК СвязьРыбаАквариум
|ГДЕ
| СвязьРыбаАквариум.ВидРыбы = &ВидРыбы
| И СвязьРыбаАквариум.Размер = &Размер";
Запрос.УстановитьПараметр("ВидРыбы", ВидРыбы);
Запрос.УстановитьПараметр("Размер", Размер);
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
Возврат Выборка.Аквариум;
КонецЕсли;
Возврат Справочники.Аквариумы.ПустаяСсылка();
КонецФункции
&НаКлиенте
Процедура ЗаполнитьАквариум(СтрокаТЧ)
Если ЗначениеЗаполнено(СтрокаТЧ.ВидРыбы) И ЗначениеЗаполнено(СтрокаТЧ.Размер) Тогда
Аквариум = ПолучитьАквариумИзРегистра(СтрокаТЧ.ВидРыбы, СтрокаТЧ.Размер);
Если ЗначениеЗаполнено(Аквариум) Тогда
СтрокаТЧ.Аквариум = Аквариум;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Проанализируем этот код: мы используем серверную функцию ПолучитьАквариумИзРегистра, чтобы эффективно извлечь данные. Если связь в регистре не найдена, поле остается пустым или требует ручного заполнения, что также является сигналом для администратора базы о необходимости настройки связей.
Для того чтобы мы могли формировать отчеты об остатках на любую дату, нам необходим Регистр накопления (например, ОстаткиРыб) с видом «Остатки».
Рассмотрим структуру измерений этого регистра. Здесь есть два подхода, которые обсуждались экспертами:
Рыба, Размер, Аквариум. Это позволяет видеть полную картину в одном регистре.Аквариум. Однако для учебных и большинства практических задач лучше использовать полную аналитику (Рыба + Размер + Аквариум), так как это делает отчеты более гибкими и понятными без дополнительных соединений таблиц.При проведении документа «Расходная накладная» проанализируем ситуацию с остатками. Программа должна проверять наличие нужного количества рыб в конкретном аквариуме. Это реализуется в процедуре ОбработкаПроведения модуля документа с помощью запроса к виртуальной таблице Остатки регистра накопления.
В реальной жизни рыбки имеют свойство расти. Рассмотрим, как отразить это в 1С. Если рыбка Гуппи размера S выросла до размера M, нам нужно отразить это в системе, иначе остатки станут некорректными. Проанализируем способы реализации:
Гуппи S, а в результате получаем Гуппи M.Также не стоит забывать о естественной убыли. Для этого в системе должен быть предусмотрен документ Списание товаров с отдельной статьей расходов «Падеж/Гибель животных».
Для вывода информации в виде: Вид аквариумных рыб | Размер | Остаток | Аквариум, лучше всего воспользоваться механизмом Системы компоновки данных (СКД). Мы создаем новый отчет, выбираем в качестве источника данных таблицу Остатки нашего регистра накопления и настраиваем группировки по виду рыб и размеру.
Подведем итог: автоматизация учета в аквариумном бизнесе требует связки справочной информации через регистры сведений и четкого контроля за движением товара через регистры накопления. Использование обработчиков событий на форме позволяет сделать интерфейс дружелюбным для пользователя, минимизируя риск ошибок при приходовании живого товара.