В типовой конфигурации «1С:Торговля и Склад 7.7» (ТиС) многие пользователи и начинающие разработчики сталкиваются с неожиданной проблемой: в стандартном отчете по продажам нет отбора и группировки по складам. Бизнес часто требует видеть продажи по конкретным торговым точкам или залам, которые в программе заведены как отдельные склады. Однако архитектура платформы версии 7.7 накладывает здесь свои ограничения.
В этой статье мы подробно разберем, почему разработчики «1С» приняли такое проектное решение, проанализируем архитектурные особенности регистров и рассмотрим три практических способа решения этой задачи: от простых организационных обходов до профессиональной доработки кода.
Для начала проанализируем структуру регистров оперативного учета в конфигурации «Торговля и Склад 7.7». С точки зрения методологии учета, заложенной разработчиками «1С»:
Продажи. В измерениях этого регистра есть Фирма, Номенклатура, Покупатель, Проект, но нет измерения Склад. С точки зрения классической бухгалтерии, клиент покупает товар у юридического лица (фирмы), а не у физического места хранения (склада).ОстаткиТМЦ или ПартииНаличие). Там есть измерение Склад, но хранятся только объемы поступлений, списаний и себестоимость. Цены фактической продажи и выручка в этих регистрах отсутствуют.Таким образом, напрямую получить выручку и прибыль в разрезе складов из стандартного регистра продаж невозможно. Тем не менее, существует несколько эффективных способов обойти это ограничение.
Это самый простой и быстрый способ, не требующий изменения конфигурации и написания кода. В штатном отчете «Отчет по продажам ТМЦ» присутствует возможность группировки и фильтрации по МОЛ (Материально ответственному лицу) / Комиссионеру.
Рассмотрим по шагам, как настроить этот обходной путь:
Склады. Убедимся, что история заполнена корректно и актуальна на весь период продаж.МОЛ.Преимущества метода: Конфигурация остается полностью типовой, решение внедряется за 10 минут силами администратора или опытного пользователя.
Недостатки метода: Если на разных складах работает одно и то же материально ответственное лицо (или если один сотрудник перемещается между точками), метод перестает работать, так как одному МОЛ будет соответствовать несколько мест хранения.
Еще один встроенный и очень гибкий инструмент в «1С 7.7» — это общий реквизит документов Проект. Данный реквизит сквозным образом проходит через всю систему и присутствует в регистре Продажи в качестве измерения.
Как применить этот метод на практике:
РеализацияТМЦ, ОтчетККМ, ПродажаСоСклада) обяжем операторов вручную или с помощью несложной автоматизации заполнять реквизит Проект в шапке документа в строгом соответствии со складом отгрузки.Проект.Преимущества метода: Высокая гибкость, возможность строить любые стандартные отчёты по продажам с отбором по проектам без написания кода.
Недостатки метода: Высокий риск человеческого фактора. Если менеджер забудет указать проект или выберет его неверно, данные в отчете исказятся. Кроме того, на базах с огромным объемом информации отчеты по проектам могут формироваться медленнее.
Если типовые обходные пути не подходят (например, склады часто меняются, у них пересекаются МОЛ, а автоматизировать заполнение проектов слишком долго), задачу можно решить программно. Рассмотрим два подхода к реализации.
Мы можем написать внешний отчет (файл с расширением .ert), который будет выбирать данные из оборотного регистра Продажи, а затем для каждой записи определять склад, обращаясь напрямую к документу, совершившему движение. Этот подход сохраняет базу данных типовой.
Проанализируем пример кода запроса для такого отчета:
// Создаем объект Запрос для выборки движений регистра Продажи
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса =
"//{{ЗАПРОС(ПродажиПоСкладам)
|Период с ВыбНачПериода по ВыбКонПериода;
|Фирма = Регистр.Продажи.Фирма;
|Номенклатура = Регистр.Продажи.Номенклатура;
|Покупатель = Регистр.Продажи.Покупатель;
|Выручка = Регистр.Продажи.Выручка;
|ТекущийДокумент = Регистр.Продажи.ТекущийДокумент;
|Функция СуммаВыручки = Сумма(Выручка);
|Группировка Номенклатура без групп;
|Группировка ТекущийДокумент;
|"//}}ЗАПРОС
;
Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
Возврат;
КонецЕсли;
После выполнения этого запроса мы можем выгрузить его результаты в Таблицу Значений (ТЗ), добавить в нее колонку Склад и заполнить ее в цикле, получая склад из реквизита шапки документа-регистратора:
ТЗ = СоздатьОбъект("ТаблицаЗначений");
Запрос.Выгрузить(ТЗ, 1, 1); // Выгружаем результаты запроса с группировками
ТЗ.НоваяКолонка("Склад", "Справочник.Склады");
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
Док = ТЗ.ТекущийДокумент;
// Проверяем наличие реквизита "Склад" в документе-регистраторе
Если ШапкаШаблон(Док, "Склад") = 1 Тогда
ТЗ.Склад = Док.Склад;
ИначеЕсли Док.Вид() = "ОтчетККМ" Тогда
ТЗ.Склад = Док.Склад; // Для розничных отчетов ККМ
КонецЕсли;
КонецЦикла;
// Теперь группируем и выводим ТЗ в макет отчета по колонке "Склад"
Важное примечание: Обращение к реквизитам документа через точку в цикле (Док.Склад) на больших объемах данных может замедлить работу отчета. Однако для небольших и средних баз этот способ является оптимальным, так как не требует изменения метаданных конфигурации.
Для крупных баз данных, где критически важна скорость формирования отчетов, рекомендуется внести изменения в структуру метаданных через Конфигуратор:
Продажи.Склад (тип значения — справочник Склады).РеализацияТМЦ, ОтчетККМ, ВозвратОтПокупателя). Нам необходимо дописать строку передачи склада в движения регистра. Например, в модуле проведения документа РеализацияТМЦ в функцию движения регистра добавим заполнение нового измерения: Регистр.Продажи.Склад = Склад;.После этой операции любой стандартный отчет, работающий с регистром Продажи, сможет использовать измерение Склад для мгновенной группировки и фильтрации.
Выбор конкретного решения зависит от ваших задач и ресурсов предприятия:
Склад непосредственно в регистр Продажи, но помните о необходимости последующего перепроведения документов.