При работе со стандартными отчетами в конфигурации «1С:Бухгалтерия предприятия 3.0» (БП 3.0), особенно с популярной «Оборотно-сальдовой ведомостью» (ОСВ), пользователи часто сталкиваются с неприятной особенностью. Если в настройках отчета задан отбор по большому количеству элементов (например, по 10–15 складам, подразделениям или номенклатурным позициям), то в печатной форме заголовка этот отбор отображается не полностью. Текст принудительно обрезается на третьей строке, а в конце ставится троеточие «...».
Для бухгалтера или аудитора крайне важно видеть, какие именно условия были применены при формировании отчета, чтобы гарантировать достоверность данных. В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем технические ограничения платформы и предложим несколько эффективных способов решения — от простых пользовательских настроек до программной доработки через расширение.
Первое, что пытается сделать опытный пользователь или администратор, — зайти в настройки отчета, открыть вкладку «Оформление» и установить для области отборов свойство «Размещение» в значение «Переносить» или включить «Автовысоту». Однако на практике это не дает никакого результата. Давайте разберем техническую изнанку этого процесса.
Ограничение на длину вывода списков накладывается непосредственно платформой 1С на уровне движка компоновки данных. Когда в виде сравнения используется оператор В списке или В группе из списка, система автоматически формирует строковое представление этого списка. Если количество элементов превышает определенный лимит, платформа принудительно усекает строку представления еще до момента передачи данных в табличный документ. В результате в макет вывода попадает уже обрезанный текст с троеточием на конце. Любые свойства ячеек («Переносить», «Автовысота») применяются уже к этой усеченной строке, поэтому переноситься будет только обрезанный текст.
Кроме того, в БП 3.0 шапка отчетов формируется программно через общий модуль БухгалтерскиеОтчетыВызовСервера (процедура СформироватьОтчет). Вывод параметров и отборов опирается на общий макет ОбщиеОбластиСтандартногоОтчета, ячейки которого имеют жестко заданные параметры высоты, переопределяющие пользовательские настройки оформления.
Ниже мы подробно рассмотрим пять практических способов решения этой проблемы, начиная с организационных методов без программирования и заканчивая гибкой программной доработкой.
Если в вашей информационной базе отборы делаются по длинным плоским спискам элементов (например, конкретным складам или магазинам), самым простым решением без изменения метаданных будет использование иерархии справочников.
Рассмотрим этот вариант на примере складов:
Склады.В группе и укажем только одну или две созданные папки.В результате в заголовке отчета вместо длинного списка из полутора десятков элементов отобразится короткая и понятная строка: Склад В группе "Розничные магазины". Это решит проблему читаемости отчета и полностью исключит обрезание текста.
Что делать, если иерархия справочника заблокирована, неудобна для пользователей или справочник в принципе не поддерживает иерархическую структуру? В этом случае мы можем задействовать универсальный штатный механизм дополнительных реквизитов и сведений.
Проанализируем шаги по настройке этого механизма:
Склады или Подразделения) новое дополнительное сведение, например, «Группа отчета ОСВ» с типом значения «Дополнительное значение».Склад.[Группа отчета ОСВ] Равно "Западный куст".Система сформирует отчет только по тем складам, у которых заполнено данное сведение. При этом в печатной форме шапки отобразится всего одна строка отбора, которая гарантированно не будет урезана платформой.
Часто необходимость видеть весь список отбора в печатной форме обусловлена тем, что один сотрудник (например, рядовой бухгалтер) готовит отчет, а другой (главный бухгалтер или аудитор) должен проверить правильность установленных фильтров. Читать мелкий печатный текст в шапке для этого совсем не обязательно.
Давайте разберем, как передать настройки отчета штатным способом:
В этом случае проверяющий пользователь может открыть стандартную панель настроек отчета прямо на экране и детально изучить весь список элементов без каких-либо платформенных ограничений вывода.
Если пользователям критически важно видеть весь список непосредственно на бумаге или в сохраненном файле PDF/Excel, нам потребуется внести изменения в логику вывода отчета. Чтобы сохранить конфигурацию на поддержке и обеспечить легкое обновление, все доработки мы будем выполнять в расширении конфигурации.
Для начала рассмотрим визуальный метод исправления ограничений высоты строки в общем макете:
ОбщиеОбластиСтандартногоОтчета и добавим его в наше расширение.ПараметрыОтчета, ВыбранныеПоля или аналогичные структуры вывода шапки).Этот способ позволит табличному документу автоматически раздвигать строки по высоте, если текст отборов переносится на новые строки. Однако помните, что этот метод не спасет от жесткого платформенного усечения длинного списка значений символами «...» на уровне СКД. Чтобы победить и это ограничение, перейдем к финальному программному методу.
Чтобы обойти системное ограничение платформы 1С на длину строкового представления списков в компоновке данных, мы можем программно перехватить процесс формирования отчета и вручную сформировать полное строковое представление отбора, записав его в свойство Представление элемента отбора компоновки.
Проанализируем программное решение. Нам необходимо перехватить событие компоновки. Лучше всего это сделать в модуле менеджера конкретного отчета или в общем модуле, отвечающем за формирование бухгалтерской отчетности. В нашем случае мы внедримся в процедуру ПередКомпоновкойМакета.
Создадим в расширении обработчик этого метода и напишем следующий код:
&Вместо("ПередКомпоновкойМакета")
Процедура Расш_ПередКомпоновкойМакета(ПараметрыКомпоновки)
// Выполняем стандартный системный вызов
ПродолжитьВызов(ПараметрыКомпоновки);
// Получаем доступ к пользовательским настройкам отчета
ПользовательскиеНастройки = ЭтотОбъект.КомпоновщикНастроек.ПользовательскиеНастройки;
Для Каждого Элемент Из ПользовательскиеНастройки.Элементы Цикл
// Проверяем, является ли элемент группой отборов
Если ТипЗнч(Элемент) = Тип("ОтборКомпоновкиДанных") Тогда
Для Каждого ЭлементОтбора Из Элемент.Элементы Цикл
ИсправитьПредставлениеДлинногоОтбора(ЭлементОтбора);
КонецЦикла;
// Либо это одиночный элемент отбора
ИначеЕсли ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
ИсправитьПредставлениеДлинногоОтбора(Элемент);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ИсправитьПредставлениеДлинногоОтбора(ЭлементОтбора)
// Проверяем, что отбор активен и использует сравнение по списку
Если ЭлементОтбора.Использование
И (ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке
Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВГруппеИзСписка) Тогда
СписокЗначений = ЭлементОтбора.ПравоеЗначение;
Если ТипЗнч(СписокЗначений) = Тип("СписокЗначений") И СписокЗначений.Количество() > 0 Тогда
МассивЭлементов = Новый Массив;
Для Каждого ЭлементСписка Из СписокЗначений Цикл
// Если у элементов списка используются пометки, берем только отмеченные
Если ЭлементСписка.Пометка Тогда
МассивЭлементов.Добавить(Строка(ЭлементСписка.Значение));
ИначеЕсли Не ЭлементСписка.Пометка И СписокЗначений.Количество() = 1 Тогда
МассивЭлементов.Добавить(Строка(ЭлементСписка.Значение));
КонецЕсли;
КонецЦикла;
// Если пометки не использовались, заполняем массив всеми значениями списка
Если МассивЭлементов.Количество() = 0 Тогда
Для Каждого ЭлементСписка Из СписокЗначений Цикл
МассивЭлементов.Добавить(Строка(ЭлементСписка.Значение));
КонецЦикла;
КонецЕсли;
// Объединяем все элементы в одну сплошную строку через запятую
Если МассивЭлементов.Количество() > 0 Тогда
ПолныйТекстОтбора = СтрСоединить(МассивЭлементов, ", ");
// Принудительно устанавливаем сформированное представление.
// Платформа выведет его в печатную форму целиком, минуя алгоритм усечения.
ЭлементОтбора.Представление = ПолныйТекстОтбора;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Рассмотрим подробнее работу представленного алгоритма. Программа обходит коллекцию активных настроек компоновщика отчета. При обнаружении элементов с видами сравнения ВСписке или ВГруппеИзСписка код извлекает реальный список значений. Мы перебираем все элементы списка, преобразуем их к строковому представлению (получаем наименования складов, номенклатуры или контрагентов) и объединяем в единую строку через функцию СтрСоединить.
Ключевой момент решения заключается в заполнении свойства Представление у объекта ЭлементОтбораКомпоновкиДанных. Когда это свойство заполнено вручную, платформа 1С считает его приоритетным и выводит в шапку отчета именно этот готовый текст, полностью игнорируя стандартный механизм автоматического формирования представлений списков и их усечения.
Совместное использование визуальных настроек высоты строк макета (Способ 4) и этого программного заполнения представлений (Способ 5) гарантирует, что даже самый огромный список отборов будет выведен в Оборотно-сальдовую ведомость в полном объеме, аккуратно переносясь на новые строки по словам.