Как рассчитать количество кормодней в 1С:Селекция в животноводстве. КРС?

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

Расчет кормодней является одной из ключевых задач в автоматизации животноводства. Кормодень — это показатель, отражающий фактическое количество дней нахождения животного на откорме или содержании в определенном подразделении (ферме, секции). Несмотря на кажущуюся простоту, реализация такого отчета требует глубокого понимания работы с регистрами накопления и языком запросов 1С, особенно в части обработки перемещений внутри одного дня.

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

Разбор бизнес-логики расчета

Прежде чем приступать к написанию запроса, проанализируем правила, по которым должен строиться расчет:

  1. День поступления на ферму всегда считается как 1 кормодень.
  2. День выбытия (реализация, падеж, перевод в другое хозяйство) НЕ считается кормоднем.
  3. Перемещение внутри дня: если животное утром было в одной секции, а днем его перевели в другую, этот день должен зачесться как кормодень в новом месте нахождения.
  4. Кратность кормления: количество фактов кормления в течение дня не влияет на показатель — это всегда 1 кормодень.

Анализ источников данных в конфигурации

В конфигурации "1С:Селекция в животноводстве. КРС" основным источником данных является регистр накопления ЖивотныеХозяйства. Этот регистр хранит информацию о количестве голов в разрезе ферм, групп и состояний.

Проанализируем структуру регистра. Как правило, он содержит измерения:

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

Способ №1: Использование виртуальной таблицы "Остатки и обороты"

Самый эффективный способ получить данные о периодах нахождения животного в определенном разрезе — это обращение к виртуальной таблице ОстаткиИОбороты с периодичностью День. Это позволит нам увидеть состояние животного на каждый день периода.

Рассмотрим пример построения запроса:


ВЫБРАТЬ
    ЖивотныеОстаткиИОбороты.Период КАК ДатаКормления,
    ЖивотныеОстаткиИОбороты.Животное,
    ЖивотныеОстаткиИОбороты.Ферма,
    ЖивотныеОстаткиИОбороты.Секция,
    ЖивотныеОстаткиИОбороты.ПоловозрастнаяГруппа,
    ЖивотныеОстаткиИОбороты.КоличествоКонечныйОстаток КАК Количество
ИЗ
    РегистрНакопления.ЖивотныеХозяйства.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК ЖивотныеОстаткиИОбороты
ГДЕ
    ЖивотныеОстаткиИОбороты.КоличествоКонечныйОстаток > 0

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

Способ №2: Использование функции РАЗНОСТЬДАТ

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

Логика в запросе СКД может выглядеть следующим образом:


ВЫБРАТЬ
    Животное,
    Ферма,
    Секция,
    СУММА(ВЫБОР
        КОГДА ДатаУбытия > &КонецПериода ТОГДА РАЗНОСТЬДАТ(ДатаПрихода, ДОБАВИТЬКДАТЕ(&КонецПериода, ДЕНЬ, 1), ДЕНЬ)
        ИНАЧЕ РАЗНОСТЬДАТ(ДатаПрихода, ДатаУбытия, ДЕНЬ)
    КОНЕЦ) КАК Кормодни
ИЗ
    ВременнаяТаблицаДвижений
СГРУППИРОВАТЬ ПО
    Животное, Ферма, Секция

Важный момент: функция РАЗНОСТЬДАТ с параметром ДЕНЬ возвращает количество границ дат. Например, разность между 1-м и 3-м числом будет равна 2. Это идеально подходит под условие "день прихода считаем, день ухода — нет".

Обработка перемещений внутри одного дня

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

Рассмотрим шаг за шагом:

  1. Выбираем все движения по регистрам за период.
  2. Для каждой даты и каждого животного определяем последнее движение (максимальный ПериодСекунда или НомерСтроки).
  3. Именно аналитика из этого последнего движения (новая секция или новая группа) будет определять, куда "уйдет" кормодень.

Настройка отчета в Системе компоновки данных (СКД)

Для реализации иерархии (Ферма -> Секция -> Половозрастная группа) лучше всего использовать СКД. Это позволит пользователю произвольно менять группировки.

В настройках СКД выполним следующие действия:

Если в регистре ЖивотныеХозяйства отсутствует разрез "Состояния", проанализируем связанные регистры сведений (например, СостоянияЖивотных). В этом случае в запросе необходимо будет выполнить Левое Соединение регистра накопления с регистром сведений по животному и условию нахождения даты кормления внутри периода состояния.

Рекомендации по оптимизации

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

  1. Индексация: убедитесь, что в регистре установлены индексы по измерениям Животное и Ферма.
  2. Временные таблицы: при сложных соединениях (например, с состояниями или ветеринарными событиями) сначала выбирайте данные во временную таблицу, а затем делайте расчет кормодней.
  3. Фильтрация: всегда накладывайте условия на период и организацию в параметрах виртуальной таблицы, а не в предложении ГДЕ.

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

← На главную