Отчёт из расширения со своей кнопкой: три пути (внешний отчёт, своя форма, штатная форма БСП)

28.07.26

Разработка - Работа с интерфейсом

Заказчику нужна кнопка «Выгрузить в JSON» на форме отчёта, конфигурация типовая и на поддержке. Казалось бы, полчаса работы — но между «кнопка появилась» и «кнопка правильно работает у пользователей» лежит десяток неочевидных ловушек: от контракта общей формы БСП до периода, который молча обнуляет отчёт в проде. Сравниваю три варианта реализации на одной сквозной задаче и разбираю каждую найденную граблю: симптом, причина, решение.

Типовая просьба заказчика: «Нужен отчёт по продажам, и чтобы на форме была кнопка — выгружает результат в JSON для внешней системы». Конфигурация — типовая УТ 11.5 на поддержке, значит — расширение или внешний отчёт.

Задача выглядит на полчаса. На деле в ней спрятан десяток граблей, и половина из них не даёт ни одной ошибки: кнопка просто не появляется, отчёт молча пустеет при очищенном периоде, а JSON-файл не принимает внешняя система из-за трёх невидимых байт в начале.

В статье разбираю три способа решения — от самого быстрого к самому правильному — и честно считаю цену каждого. Центральная часть — то, чего обычно нет в статьях на эту тему: цепочка из трёх условий, по которой БСП решает, звать обработчик вашего отчёта или промолчать, и почему у расширения она рвётся чаще всего.

Механику сверял не по памяти, а по коду выгрузки УТ 11.5.27.61 (кросс-проверка — Розница 3.0.13.374): в тексте названы конкретные модули и процедуры, чтобы вы могли посмотреть у себя. Платформа 8.3.27.2214, демо-база УТ 11.5, формат выгрузки XML 2.20.

 

Содержание

  • Задача-пример
  • Путь 1. Внешний (дополнительный) отчёт — минут двадцать
  • Путь 2. Отчёт в расширении со своей формой — минут тридцать
    • Почему своя форма конфликтует с «Вариантами отчётов»
  • Путь 3. Штатная общая форма БСП и своя кнопка
    • Шаг 1. Метаданные, подсистемы и права
    • Шаг 2. Точка А: свой отчёт объявляет себя сам
    • Три шлюза, или почему «кнопки нет, ошибок нет»
    • Точка А-штрих и точка Б: когда без чужого модуля не обойтись
    • О самом методе ОтчетыСервер.ВывестиКоманду
    • Шаг 3. Три общих модуля расширения
    • Шаг 4. Собрать действующие настройки и сериализовать в JSON
  • Грабля отдельного разговора: период «как в типовых»
  • Чек-лист «кнопки нет, ошибок нет»
  • Итог: как выбирать путь

 

Задача-пример

Чтобы разговор был предметным, возьму сквозной пример, на котором всё и отлажено.

Отчёт «Бонусы менеджеров»: по регистру накопления считаем бонус менеджера как процент от выручки по «акционным» товарам. СКД, группировка Менеджер ? Товары, стандартный период. И требование заказчика: кнопка «Выгрузить данные», которая сохраняет результат отчёта в JSON-файл — с учётом выбранного пользователем периода и отборов, а не «всё за всю историю».

Ключевое слово в требовании — с учётом настроек пользователя. Именно оно отличает «кнопку за 5 минут» от кнопки, которая реально работает.

 

Путь 1. Внешний (дополнительный) отчёт — минут двадцать

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

  1. Создаём внешний отчёт, в нём — схема компоновки данных (обычный конструктор СКД).
  2. Создаём основную форму отчёта конструктором: платформа сама положит на неё основной реквизит «Отчет», поле результата и кнопку «Сформировать».
  3. Добавляем на форму свою команду «Выгрузить данные» и пишем обработчик. Настройки берём прямо из компоновщика: Отчет.КомпоновщикНастроек — форма своя, всё под рукой.
  4. Подключаем через БСП: «НСИ и администрирование ? Печатные формы, отчёты и обработки ? Дополнительные отчёты и обработки». Там же назначаем размещение в разделах и права.

Плюсы: быстро; не трогаем ни конфигурацию, ни расширения; обновление конфигурации отчёт не задевает; можно отдать заказчику одним файлом.

Минусы — и здесь я сознательно исправляю формулировку, которая кочует по статьям. Интеграция дополнительного отчёта с подсистемой «Варианты отчётов» не «урезанная», она условная. Дополнительный отчёт полноценно живёт в панелях отчётов, имеет варианты и участвует в рассылках, если выполнены два условия:

  • в свойствах внешнего отчёта «Хранилище вариантов» указано ХранилищеВариантовОтчетов;
  • отчёт использует все три общие формы подсистемы: ФормаОтчета, ФормаНастроекОтчета, ФормаВариантаОтчета.

Комплект форм — «всё или ничего»: подключиться к части нельзя, это записано в документации прямым текстом. Формально выход есть — своя основная форма плюс своя форма настроек (или общая ВспомогательнаяФормаНастроекОтчета), документация его прямо описывает. Но для внешнего отчёта он нерабочий: сослаться из .erf на общую форму конфигурации нельзя, а своя форма настроек означает, что механику вариантов вы пишете сами. Практический вывод: у дополнительного отчёта своих форм не делаем — а значит, «кнопку на своей форме» из пункта 3 вы уже не поставите.

Штатный выход описан: в СведенияОВнешнейОбработке() выставляется ПараметрыРегистрации.ОпределитьНастройкиФормы = Истина, а в модуле объекта отчёта появляется процедура ОпределитьНастройкиФормы — дальше всё как в пути 3. Но у внешнего отчёта здесь своя стена: клиентский обработчик кнопки некуда положить. Он должен жить в клиентском общем модуле конфигурации либо в ОтчетыКлиентПереопределяемый.ОбработчикКоманды — а внутри файла .erf таких модулей нет.

И ещё особенность, из-за которой отладка внешнего отчёта превращается в гадание. Если в модуле объекта что-то не так, БСП для внешних отчётов подавляет исключение полностью и молча: в ВариантыОтчетов.НастройкиОтчета есть явная ветка «если это внешний отчёт — подменить настройки на умолчательные». В журнал регистрации в этой ветке не пишется ничего; запись возможна только на предыдущем шаге, если не удалось подключить сам объект отчёта. Для отчёта конфигурации в такой же ситуации вы получите внятное исключение на экран — для внешнего тишину и отсутствующую кнопку.

Реальные ограничения дополнительных отчётов, о которых стоит помнить: безопасный режим включён по умолчанию (запрещены COM, внешние компоненты, файловая система, интернет — расширяется только через список разрешений), обязательное поле «ВерсияБСП», статус публикации «Режим отладки» (отчёт виден только администратору — самая частая причина «а у меня его нет»), список быстрого доступа для глобальных команд и, если база работает и на мобильных клиентах, параметр НазначениеВариантаОтчета.

Вердикт: честный путь для разовых и «личных» отчётов, а также для отчётов без собственных команд. Как только к отчёту нужна своя клиентская кнопка — путь упирается в отсутствие места для клиентского кода.

 

Путь 2. Отчёт в расширении со своей формой — минут тридцать

Первое, что приходит в голову, когда отчёт должен жить в базе постоянно: объект «Отчёт» в расширении конфигурации плюс собственная основная форма, на которой рисуем что хотим.

  1. В расширении создаём отчёт, добавляем ОсновнаяСхемаКомпоновкиДанных.
  2. Конструктором создаём основную форму отчёта — получаем реквизит «Отчет», поле «Результат», кнопку «Сформировать».
  3. Добавляем свою команду на форму. Всё компилируется, из «Все функции» отчёт открывается и работает.

Выглядит как победа. А потом отчёт находят через панель отчётов раздела — и начинается интересное.

Почему своя форма конфликтует с «Вариантами отчётов»

Подсистема обходит Метаданные.Отчеты и строит коллекцию предопределённых вариантов (ВариантыОтчетов.ПредопределенныеВариантыОтчетов). Причём обходит отдельными проходами: "Внутренний" — для отчётов конфигурации, "Расширение" — для отчётов расширений.

Фильтров в цикле два, и второй бьёт именно по расширениям:

Если Не ДоступноИспользованиеРазделенныхДанных И ОтчетМетаданные.РасширениеКонфигурации() <> Неопределено Тогда
   Продолжить;
КонецЕсли;

Если ПодключенныеКХранилищу И Не ОтчетПодключенКХранилищу(ОтчетМетаданные, КэшФлажкаХранилища) Тогда
   Продолжить;
КонецЕсли;

Первый — про модель сервиса: в неразделённом сеансе отчёты расширений выбрасываются из обхода целиком. Второй — то самое подключение к хранилищу вариантов: при «полном» варианте внедрения ХранилищеВариантовОтчетов указано в свойствах конфигурации, и тогда подключены действительно все отчёты; при «частичном» — у каждого отчёта поштучно.

Открывая отчёт из панели, БСП передаёт форме ссылку на вариант и ожидает от неё поведения общей формы: структуру НастройкиОтчета в данных формы, механику вариантов, панель быстрых настроек. Самодельная форма этого не умеет. Дальше — в зависимости от точки входа: либо форма открывается пустой и без панели настроек, либо вы получаете ошибку разыменования на строке

КлючСохраненияПоложенияОкна = ОписаниеНастроекОтчета.ПолноеИмя

в общей форме настроек.

Про эту ошибку стоит сказать точнее, чем обычно пишут. ОписаниеНастроекОтчета — не мифический реквизит, а функция-обёртка &НаКлиентеНаСервереБезКонтекста, которая есть и в ФормаОтчета, и в ФормаНастроекОтчета и нужна только для подсказок типов: она возвращает аргумент как есть, никакой «ленивой» доинициализации внутри нет. В общей форме настроек структура приходит извне, параметром Параметры.НастройкиОтчета, и её ПолноеИмя используется сразу. Поэтому падение и происходит на первых строках: форму открыли без корректно заполненного параметра. Текст будет либо «Значение не является значением объектного типа (ПолноеИмя)» — если параметр не передали вовсе, либо «Поле объекта не обнаружено (ПолноеИмя)» — если передали структуру без этого ключа.

Дальше принято писать «два стула». На самом деле их четыре, и три поддерживаются официально:

  1. ВспомогательнаяФормаНастроекОтчета. Документация прямо описывает случай «у отчёта на СКД своя основная форма»: тогда ему нужна и своя форма настроек — либо в свойствах отчёта указывается эта общая вспомогательная форма. Отчёт при этом остаётся в подсистеме.
  2. ФорматНастроекСКД = Ложь в настройках отчёта. Штатный способ сказать подсистеме «отчёт нетипового формата» — после чего к нему перестают применяться проверки и механизмы, рассчитанные на типовой формат.
  3. Не делать свою форму. В девяти случаях из десяти её заводят ради одной кнопки — а кнопка прекрасно добавляется в штатную форму (путь 3).
  4. Прятать отчёт от подсистемы. Формально это «частичный» вариант внедрения, то есть не хак, но и не решение задачи.

Чего своя форма стоит на самом деле — это не «сломается при обновлении БСП». Ломается не форма, а скопированные в неё куски общей формы: гарантия совместимости распространяется только на программный интерфейс, а служебные процедуры библиотеки могут быть изменены или удалены в следующей версии. Реальная цена другая:

  • отчёт выпадает из рассылок — подсистема «Рассылка отчётов» требует типового формата настроек и формирования через СкомпоноватьРезультат, а «нетиповые» отчёты вносятся в список исключений;
  • отчёт не получает хуков формы (ОпределитьНастройкиФормы и события) — они работают только для отчётов на общих формах;
  • отчёт отстаёт: снимки отчётов, работа с колонками, «Поделиться настройками» и прочие новые возможности общей формы в него не приезжают.

Вердикт: путь годится для служебных отчётов, которые пользователь не увидит в панели разделов, и для действительно нетиповых отчётов — но тогда осознанно, с ВспомогательнаяФормаНастроекОтчета или ФорматНастроекСКД = Ложь.

 

Путь 3. Штатная общая форма БСП и своя кнопка

Правильный ответ на исходную задачу звучит парадоксально: чтобы добавить свою кнопку — не надо делать свою форму. Отчёт отдаём штатной общей форме БСП (получаем «Сформировать», период, настройки, варианты, рассылки — из коробки), а кнопку добавляем программно.

Шаг 1. Метаданные, подсистемы и права

В конфигураторе это выглядит до обидного просто. У отчёта в расширении:

  1. Собственную основную форму не создаём (создали на пути 2 — удаляем).
  2. В свойствах отчёта в группе «Формы» указываем штатные общие: «Основная форма» — ФормаОтчета, «Основная форма настроек» — ФормаНастроекОтчета, «Основная форма варианта» — ФормаВариантаОтчета (в диалоге выбора формы они в ветке «Общие формы»).
  3. Схема компоновки (ОсновнаяСхемаКомпоновкиДанных) остаётся.

Строго говоря, пункт 2 не обязателен: у самого отчёта свойства форм можно не заполнять — сработает значение корня результирующей конфигурации, а в типовой на БСП там прописано именно то, что нужно (в Configuration.xml УТ: DefaultReportForm = CommonForm.ФормаОтчета и аналогично для настроек и варианта). Я всё равно прописываю формы у отчёта явно — меньше вопросов при сопровождении. А вот чего делать не стоит — помечать модифицируемым и оставлять пустым свойство корня расширения «Основная форма отчёта»: так вы перебьёте значение конфигурации и получите автогенерируемую форму сразу у всех отчётов.

Подсистемы. Отчёту нужны две:

  • раздел командного интерфейса (например, «Продажи») — чтобы отчёт появился в панели отчётов этого раздела. Обе подсистемы заимствуются: удалить из состава заимствованной подсистемы чужое нельзя, а добавить своё — можно;
  • ПодключаемыеОтчетыИОбработки — без неё не заработает точка А (см. ниже).

Панель отчётов, кстати, сама по себе не появляется: раздел должен быть перечислен в ВариантыОтчетовПереопределяемый.ОпределитьРазделыСВариантамиОтчетов, а в командном интерфейсе — быть команда ПоказатьПанельОтчетов. В типовых это уже сделано, но если вы добавляете отчёт в собственный раздел — проверьте.

Права. Самый частый «а у них не работает»: платформа при создании расширения заводит роль <Префикс>ОсновнаяРоль с правами на собственные объекты, но в конфигурации на БСП этого мало. По стандарту 1С заводим в расширении роль вида <Префикс>ОбщиеПрава, даём в ней право «Просмотр» на свой отчёт и включаем её в «Основные роли» расширения — тогда БСП добавит её в профили групп доступа. Без этого отчёт увидит только администратор. Заимствовать и править ПолныеПрава и АдминистраторСистемы при этом нельзя.

Шаг 2. Точка А: свой отчёт объявляет себя сам

Это штатный механизм БСП, и для собственного отчёта — правильный. Отчёт сам сообщает подсистеме, что хочет влиять на общую форму, и получает управление в её ПриСозданииНаСервере. Ни одного заимствованного общего модуля: всё живёт внутри вашего объекта (заимствуются только две подсистемы из шага 1 — это дёшево и обновление типовой этого не ломает).

2.1. Включить отчёт в состав подсистемы ПодключаемыеОтчетыИОбработки. Это не косметика: в коде подсистемы «Варианты отчётов» состав именно этой подсистемы проверяется явно, и только для входящих в неё объектов читаются настройки из модуля менеджера. Документация формулирует то же самое: настройки отчётов конфигурации задаются в ВариантыОтчетовПереопределяемый, а для отчётов из расширений следует включать их в подсистему ПодключаемыеОтчетыИОбработки.

Важно: в поставке УТ 11.5.27.61 (как и Розницы 3.0.13.374) состав этой подсистемы пуст — типовые отчёты настраиваются другим маршрутом. Ваш отчёт станет её первым участником, так что после подключения расширения имеет смысл убедиться, что состав действительно пополнился.

2.2. В модуле менеджера отчёта — объявить программный интерфейс:

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
#Область ДляВызоваИзДругихПодсистем

// СтандартныеПодсистемы.ПодключаемыеКоманды

Процедура ПриОпределенииНастроек(Настройки) Экспорт

   Настройки.ОпределитьНастройкиФормы = Истина; // хотим влиять на общую форму отчёта
   Настройки.НастроитьВариантыОтчета = Истина; // и сами настроим размещение в панели

КонецПроцедуры

// Конец СтандартныеПодсистемы.ПодключаемыеКоманды
// СтандартныеПодсистемы.ВариантыОтчетов

// ВНИМАНИЕ: два параметра. Подробности — сразу после листинга.

Процедура НастроитьВариантыОтчета(Настройки, НастройкиОтчета) Экспорт

   НастройкиОтчета.Описание = НСтр("ru = 'Бонусы менеджеров по акционным товарам.'");
   НастройкиОтчета.Размещение.Вставить(Метаданные.Подсистемы.Продажи);

КонецПроцедуры

// Конец СтандартныеПодсистемы.ВариантыОтчетов

#КонецОбласти
#КонецОбласти
#КонецЕсли

Про «внимание» с сигнатурой. В УТ 11.5 сосуществуют два разных вызова одной и той же процедуры модуля менеджера: библиотечный ВариантыОтчетов.НастроитьОтчетВМодулеМенеджера зовёт её с двумя параметрами, а прикладной ВариантыОтчетовУТПереопределяемый — напрямую и, как правило, с одним (в 17 случаях вторым параметром идёт прикладной флаг вроде ИспользоватьПроизводство, но это никогда не НастройкиОтчета). В выгрузке 11.5.27.61 объявлений с одним параметром 193, с двумя — 92, из них 75 канонические (Настройки, НастройкиОтчета).

Ваш отчёт из расширения идёт по библиотечному маршруту, значит параметров должно быть два. Если скопировать шаблон из «ближайшего типового отчёта» и объявить один — вы получите не ошибку на экране, а запись в журнале регистрации с довольно сбивающим с толку текстом: «Недопустимое значение параметра КлючВарианта в процедуре ВариантыОтчетов.НастроитьОтчетВМодулеМенеджера». Отчёт при этом останется без ваших настроек.

2.3. В модуле объекта отчёта — подписка на событие и сам обработчик:

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область СлужебныйПрограммныйИнтерфейс

// Настройки общей формы отчета подсистемы "Варианты отчетов".
//
// ВНИМАНИЕ: Форма здесь может быть Неопределено — БСП зовёт эту процедуру
// из ВариантыОтчетов.НастройкиОтчета вообще без контекста формы.
// Обращаться к Форма.* тут нельзя, только заполнять Настройки.
//

Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт

   Настройки.События.ПриСозданииНаСервере = Истина;

КонецПроцедуры

// См. ОтчетыПереопределяемый.ПриСозданииНаСервере.

Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт

   Команда = Форма.Команды.Добавить("вт_ВыгрузитьДанные");
   Команда.Заголовок = НСтр("ru = 'Выгрузить данные'");
   Команда.Подсказка = НСтр("ru = 'Выгрузить результат отчёта в файл JSON'");
   Команда.Действие = "вт_БонусыМенеджеровКлиент.ВыгрузитьДанные";
   ОтчетыСервер.ВывестиКоманду(Форма, Команда, "Интеграция");

КонецПроцедуры

#КонецОбласти
#КонецЕсли

Обратите внимание: здесь нет ни Попытка, ни проверки «а тот ли это отчёт» — обработчик вызывается только для вашей формы, защищаться не от чего. Это главное отличие точки А от точки Б.

Эталон, с которым стоит сверяться, — Отчет.ПрогрессОтложенногоОбновления: в модуле менеджера двухпараметрическая НастроитьВариантыОтчета с НастройкиОтчета.ОпределитьНастройкиФормы = Истина, в модуле объекта — ОпределитьНастройкиФормы и ПриСозданииНаСервере с двумя вызовами ВывестиКоманду. Учтите две его особенности: как библиотечный код он вызывает ВывестиКоманду через ОбщегоНазначения.ОбщийМодуль("ОтчетыСервер") (мягкая зависимость от подсистемы) и использует диспетчерский вариант Команда.Действие = "Подключаемый_Команда", а не строку «Модуль.Процедура», как у нас.

А вот Отчет.ABCXYZРаспределениеКлиентов копировать не надо, хотя он и выглядит подходящим: у него НастроитьВариантыОтчета объявлена с одним параметром, потому что его зовут напрямую из ВариантыОтчетовУТПереопределяемый. Это второй маршрут, не ваш.

Три шлюза, или почему «кнопки нет, ошибок нет»

Вот это место — самое ценное во всей задаче, потому что без него объектный обработчик выглядит «нестабильным». Он не нестабилен: между вашим кодом и формой стоят три последовательных условия.

Шлюз 1 — кэш «отчётов с настройками». В ВариантыОтчетов.НастройкиОтчета первым делом:

ОтчетыСНастройками = ВариантыОтчетовПовтИсп.Параметры().ОтчетыСНастройками;

Если ОтчетыСНастройками.Найти(ОтчетСсылка) = Неопределено
И (ОтчетОбъект = Неопределено Или Метаданные.Отчеты.Содержит(ОтчетОбъект.Метаданные()))Тогда

   Возврат НастройкиОтчета;

КонецЕсли;

Условие составное, и второй множитель — как раз про внешние отчёты: их метаданных нет в Метаданные.Отчеты, поэтому для них шлюз 1 не срабатывает и ОпределитьНастройкиФормы зовётся всегда. Для отчёта конфигурации и для отчёта расширения условие вырождается в «нет в кэше — выходим». Список наполняется при регистрации предопределённых вариантов: туда попадают отчёты с признаком ОпределитьНастройкиФормы.

Шлюз 2 — вызов ОпределитьНастройкиФормы в модуле объекта. Только пройдя шлюз 1, подсистема обращается к вашему отчёту. Это единственное место, где можно поднять флаг события.

Шлюз 3 — сам флаг. В общей форме отчёта вызов выглядит так:

ИнтеграцияПодсистемБСП.ПриСозданииНаСервереВариантыОтчетов(ЭтотОбъект, Отказ, СтандартнаяОбработка);
ОтчетыПереопределяемый.ПриСозданииНаСервере(ЭтотОбъект, Отказ, СтандартнаяОбработка);

Если НастройкиОтчета.События.ПриСозданииНаСервере Тогда

   ОтчетОбъект.ПриСозданииНаСервере(ЭтотОбъект, Отказ, СтандартнаяОбработка);

КонецЕсли;

По умолчанию События.ПриСозданииНаСервере — Ложь (ОтчетыКлиентСервер.НастройкиОтчетаПоУмолчанию), так что без шлюзов 1 и 2 условие просто не выполнится.

Теперь — почему это особенно бьёт по расширениям. Список ОтчетыСНастройками для расширений хранится отдельно от списка конфигурации: ВариантыОтчетовПовтИсп.Параметры() дополняет его из СтандартныеПодсистемыСервер.ПараметрРаботыРасширения — и только при заполненном ПараметрыСеанса.ВерсияРасширений. Сами предопределённые варианты расширений лежат в справочнике ПредопределенныеВариантыОтчетовРасширений, а кэш — в регистре сведений ПараметрыРаботыВерсийРасширений под ключом СтандартныеПодсистемы.ВариантыОтчетов.ОтчетыСНастройками.

Хорошая новость: если параметра для текущей версии расширений нет, БСП перестраивает его сама — тут же вызывает ВариантыОтчетов.ПриЗаполненииВсехПараметровРаботыРасширений(). То есть «обновлять вспомогательные данные руками» обычно не требуется.

Плохая новость — три сценария молчаливого отказа, и первый из них объясняет почти все жалобы «работает через раз»:

  1. Сеанс. Расширение подключается к сеансу один раз, при его старте, и живёт в нём до конца. Обновили расширение — существующие сеансы продолжают работать со старой версией: ПараметрыСеанса.ВерсияРасширений там прежний, а значит и кэш вариантов прежний. Первое, что делаем при «не появилось», — перезаходим в базу.
  2. ПараметрыСеанса.ВерсияРасширений пуст — блок расширений в ВариантыОтчетовПовтИсп.Параметры() просто пропускается.
  3. Недоступны разделённые данные (неразделённый сеанс в модели сервиса) — отчёты расширений отсеиваются ещё в начале ПредопределенныеВариантыОтчетов.

И есть отличный диагностический маркер: если отчёт уже зарегистрирован как «с настройками», а процедуры ОпределитьНастройкиФормы в модуле объекта нет, БСП выбрасывает исключение с прямым текстом — «отчёт подключен к подсистеме "Варианты отчетов", но при получении настроек возникла следующая ошибка (возможно процедура ОпределитьНастройкиФормы не указана разработчиком отчета или не обновлен кэш вариантов отчетов)». Увидели этот текст — значит, шлюз 1 пройден и вы споткнулись на шлюзе 2.

Отдельно про несколько расширений: порядок их подключения в общем случае не определён, а одинаковые имена команд формы дадут исключение при добавлении второй. Поэтому имя команды префиксуем по расширению — как и всё остальное.

Точка А-штрих и точка Б: когда без чужого модуля не обойтись

Точка А закрывает случай «отчёт мой». Если отчёт чужой или состав подсистем вам не подвластен, остаются ещё два входа — оба через заимствование общего модуля типовой.

Точка А-штрих: &После на ВариантыОтчетовПереопределяемый.НастроитьВариантыОтчетов. Этот переопределяемый модуль вызывается и на проходе по отчётам расширений, поэтому флаг можно поднять и оттуда:

&После("НастроитьВариантыОтчетов")

Процедура вт_НастроитьВариантыОтчетов(Настройки)

   ОписаниеОтчета = ВариантыОтчетов.ОписаниеОтчета(Настройки, Метаданные.Отчеты.вт_БонусыМенеджеров);
   ОписаниеОтчета.ОпределитьНастройкиФормы = Истина;
   ОписаниеОтчета.Размещение.Вставить(Метаданные.Подсистемы.Продажи);

КонецПроцедуры

Цена — заимствование чужого общего модуля; выигрыш — не нужна подсистема ПодключаемыеОтчетыИОбработки. Дальше всё как в точке А: ОпределитьНастройкиФормы и ПриСозданииНаСервере в модуле объекта.

Точка Б: &После на ОтчетыПереопределяемый.ПриСозданииНаСервере. Вход глобальный, и он не «неправильный»: пример добавления команды приведён прямо в шапке этой процедуры в самой библиотеке. Просто задача у него другая — влиять на формы отчётов, которые вам не принадлежат: навесить команду на чужой типовой отчёт или сразу на несколько.

&После("ПриСозданииНаСервере")

Процедура вт_ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка)

// Отчёт формы определяем по структуре НастройкиОтчета в данных формы.
// Дёшево и НЕ создаёт объект отчёта на КАЖДОЙ открываемой форме отчёта.
// Отсутствие структуры — не ошибка приложения, а проверка контекста,

   Попытка
      ПолноеИмяОтчета = Форма.НастройкиОтчета.ПолноеИмя;
   Исключение
      Возврат;
   КонецПопытки;

   Если ПолноеИмяОтчета <> "Отчет.вт_БонусыМенеджеров" Тогда
      Возврат;
   КонецЕсли;
   
   Команда = Форма.Команды.Добавить("вт_ВыгрузитьДанные");
   Команда.Заголовок = НСтр("ru = 'Выгрузить данные'");
   Команда.Действие = "вт_БонусыМенеджеровКлиент.ВыгрузитьДанные";

// Локальная Попытка: сбой вывода кнопки не должен блокировать открытие отчёта.
// Оборачиваем только рискованный вызов — чтобы не проглотить ошибки соседнего
// кода и других расширений 

   Попытка
      ОтчетыСервер.ВывестиКоманду(Форма, Команда, "Интеграция");
   Исключение
      ЗаписьЖурналаРегистрации(
         вт_БонусыМенеджеровСервер.ИмяСобытияЖурналаРегистрации(),
         УровеньЖурналаРегистрации.Ошибка,
         Метаданные.Отчеты.вт_БонусыМенеджеров,,
         ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
   КонецПопытки;

КонецПроцедуры

Четыре момента, каждый из которых стоил мне времени.

Только &После, не &Вместо. В УТ 11.5 процедура ОтчетыПереопределяемый.ПриСозданииНаСервере не пустая — она проксирует вызов в ОтчетыУТПереопределяемый, а тот дальше в механизмы событий форм. Замещение убьёт прикладную логику УТ на всех формах отчётов. Заодно помните ограничение платформы: &После применим только к процедурам; для функций остаётся &Вместо с ПродолжитьВызов.

Проверка по Форма.НастройкиОтчета.ПолноеИмя — а не по типу реквизита. Напрашивающийся ТипЗнч(Форма.Отчет) = Тип("ОтчетОбъект.вт_БонусыМенеджеров") не работает вовсе: значение основного реквизита формы в рантайме — ДанныеФормыСтруктура, сравнение всегда ложно, защитная проверка молча выходит, симптом — «кнопки нет, ошибок нет». Вариант через Форма.РеквизитФормыВЗначение("Отчет") работает, но создаёт объект отчёта на каждой открываемой форме каждого отчёта. А ПолноеИмя кладётся в структуру настроек функцией ВариантыОтчетов.НастройкиФормыОтчета (как ОтчетМетаданные.ПолноеИмя()) задолго до вызова хуков — форма использует его сама ещё на этапе сбора используемых таблиц. К моменту нашего &После оно гарантированно заполнено и стоит копейки.

Ранний выход обязателен. Перехватчик отрабатывает при открытии каждой формы отчёта в базе. Никаких запросов к ИБ, чтения настроек и обращений к внешним ресурсам здесь быть не должно: всё, что делается при создании формы, замедляет её открытие. Нужны справочные данные — только через модуль с повторным использованием возвращаемых значений.

Имя события журнала — двухуровневое и без данных. Стандарт требует формат «Название группы событий.Название события», а метаданные и данные передавать отдельными параметрами метода, а не склеивать в строку. Сама БСП пишет ровно так: НСтр("ru = 'Варианты отчетов.Формирование отчета'", ОбщегоНазначения.КодОсновногоЯзыка()).

И предупреждение для эксплуатации: перед исполнением расширенного модуля платформа проверяет применимость — соответствие имён и состава параметров. Если в новой версии типовой сигнатура изменится, расширение метода не применится с предупреждением: приложение продолжит работать, а ваша кнопка тихо исчезнет. Точки А это не касается — там вы работаете со своим объектом.

О самом методе ОтчетыСервер.ВывестиКоманду

Полная сигнатура:

Процедура ВывестиКоманду(ФормаОтчета, КомандаИлиКоманды, ТипГруппы,
ВНачалоГруппы = Ложь, ТолькоВоВсехДействиях = Ложь, СуффиксПодгруппы = "") Экспорт

Главное, ради чего им стоит пользоваться вместо ручной вставки кнопки, видно прямо в коде: он запоминает ваш обработчик «Модуль.Процедура» в ПостоянныеКоманды и подменяет Действие на служебное "Подключаемый_Команда" — без этого диспетчер формы вашу процедуру не найдёт и команда просто ничего не сделает. Попутно метод кладёт кнопку в нужную группу командной панели и дублирует её в подменю «Ещё».

Шапка метода в БСП обещает ещё и защиту от удаления при перерисовке формы. Здесь я обязан быть точным: в ФормаОтчета УТ 11.5.27.61 (и Розницы) цикла «команды нет в ПостоянныеКоманды ? удалить» нет — список там только пополняется и один раз читается в Подключаемый_Команда. Такая чистка есть в общей форме ПанельОтчетов и только под веб-клиентом. Так что полагаться на ручную вставку кнопки всё равно не стоит, но и приписывать ВывестиКоманду больше, чем он делает, не надо.

Допустимых значений ТипГруппы ровно шесть, любое другое — исключение:

Значение Куда попадёт кнопка
"Главное" группа с «Сформировать» и «Формировать сразу»
"Настройки" «Настройки», «Изменить вариант отчёта» и т. п.
"РаботаСТабличнымДокументом" «Найти», «Развернуть все группы» и т. п.
"Интеграция" «Печать», «Сохранить», «Отправить» — логичное место для выгрузки
"ПодменюОтправить" подменю отправки по почте внутри «Интеграции»
"Прочее" основная командная панель формы

Механика Действие такая: если в нём есть точка — строка вида "МодульКлиент.Процедура" — метод запоминает её как обработчик, а само Действие перезаписывает. При нажатии форма находит запомненный обработчик и вызывает вашу процедуру через ОписаниеОповещения. Если точки нет — управление уходит в ИнтеграцияПодсистемБСПКлиент.ПриОбработкеКоманды и ОтчетыКлиентПереопределяемый.ОбработчикКоманды. Оба варианта штатные: первый удобнее для своего расширения, второй — когда команд много и нужен один диспетчер.

Событий, на которые может подписаться отчёт, не одно: в структуре Настройки.События их больше десятка — от ПередЗагрузкойНастроекВКомпоновщик (например, чтобы подключить схему, собранную программно, через ОтчетыСервер.ПодключитьСхему) до ПередФормированиемОтчета (показать предупреждение «отчёт будет считаться долго»).

Шаг 3. Три общих модуля расширения

Для кнопки нужны три общих модуля — разделение диктуют стандарты 1С:

  • вт_БонусыМенеджеровКлиент — Клиент (управляемое приложение), Сервер = Ложь;
  • вт_БонусыМенеджеровВызовСервера — Сервер, Вызов сервера = Истина;
  • вт_БонусыМенеджеровСервер — Сервер, Вызов сервера = Ложь (сюда кладём всё, что не должно быть доступно с клиента).

Серверный:

#Область ПрограммныйИнтерфейс
// Имя события журнала регистрации механизма выгрузки бонусов менеджеров.
//
// Возвращаемое значение:
// Строка
//

Функция ИмяСобытияЖурналаРегистрации() Экспорт

   Возврат НСтр("ru = 'Бонусы менеджеров.Выгрузка данных'", ОбщегоНазначения.КодОсновногоЯзыка());

КонецФункции

#КонецОбласти

Клиентский — общая форма вызовет процедуру с сигнатурой (Форма, Команда), это два первых параметра ОтчетыКлиентПереопределяемый.ОбработчикКоманды:

Процедура ВыгрузитьДанные(Форма, Команда) Экспорт

// проблема: ПолучитьНастройки() — серверный метод компоновщика, на тонком клиенте
// он недоступен. В типовых на клиенте тоже работают только со свойствами
// Настройки / ПользовательскиеНастройки, а сборку делают на сервере.

   Настройки = Форма.Отчет.КомпоновщикНастроек.Настройки;
   ПользовательскиеНастройки = Форма.Отчет.КомпоновщикНастроек.ПользовательскиеНастройки;
   Адрес = вт_БонусыМенеджеровВызовСервера.АдресВыгрузкиJSON(
   Настройки, ПользовательскиеНастройки, Форма.УникальныйИдентификатор);
   Если Не ЗначениеЗаполнено(Адрес) Тогда
      ПоказатьПредупреждение(, НСтр("ru = 'Нет данных за выбранный период.'"));
      Возврат;
   КонецЕсли;

// проблема: НЕ НачатьПолучениеФайлов (его первый аргумент — ОписаниеОповещения,
// получите «Несоответствие типов (параметр 1)»). Штатное сохранение БСП проще,
// и 1С прямо требует использовать именно его:

   ПараметрыСохранения = ФайловаяСистемаКлиент.ПараметрыСохраненияФайла();
   ПараметрыСохранения.Диалог.Фильтр = НСтр("ru = 'JSON (*.json)|*.json'");
   ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, "БонусыМенеджеров.json", ПараметрыСохранения);

КонецПроцедуры

Про веб-клиент уточню честно: СохранитьФайл в нём работает, но интерактивное сохранение требует установленного расширения работы с 1С:Предприятием — при его отсутствии БСП сама покажет предложение установить (текст настраивается свойством ТекстПредложения в параметрах сохранения).

Шаг 4. Собрать действующие настройки и сериализовать в JSON

Модуль вт_БонусыМенеджеровВызовСервера. Задача — из пары «настройки + пользовательские настройки» получить то, что пользователь реально видит на форме, скомпоновать и отдать адрес во временном хранилище:

Функция АдресВыгрузкиJSON(Настройки, ПользовательскиеНастройки, ИдентификаторФормы) Экспорт

// Модуль с признаком «Вызов сервера» — точка входа снаружи, право проверяем сами.
   Если Не ПравоДоступа("Просмотр", Метаданные.Отчеты.вт_БонусыМенеджеров) Тогда
      ВызватьИсключение НСтр("ru = 'Недостаточно прав для выгрузки данных отчёта.'");
   КонецЕсли;

// Имя макета берём из метаданных, а не строкой — так же делает БСП.

   МетаданныеОтчета = Метаданные.Отчеты.вт_БонусыМенеджеров;
   Схема = Отчеты.вт_БонусыМенеджеров.ПолучитьМакет(МетаданныеОтчета.ОсновнаяСхемаКомпоновкиДанных.Имя);
   Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
   Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
   
   Если Настройки <> Неопределено Тогда
      Компоновщик.ЗагрузитьНастройки(Настройки);
   Иначе
      Компоновщик.ЗагрузитьНастройки(Схема.НастройкиПоУмолчанию);
   КонецЕсли;
   
   Если ПользовательскиеНастройки <> Неопределено Тогда
      Компоновщик.ЗагрузитьПользовательскиеНастройки(ПользовательскиеНастройки);
   КонецЕсли;

   ДействующиеНастройки = Компоновщик.ПолучитьНастройки();
   КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
   МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, ДействующиеНастройки, , ,
   Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
   ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
   ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
   Дерево = Новый ДеревоЗначений;
   ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
   ПроцессорВывода.УстановитьОбъект(Дерево);
   ПроцессорВывода.Вывести(ПроцессорКомпоновки);
   
   ЗаписьJSON = Новый ЗаписьJSON;
   ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, Символы.Таб));
   ЗаписьJSON.ЗаписатьНачалоМассива();

   Для Каждого СтрокаМенеджера Из Дерево.Строки Цикл
// проблема: корневая запись дерева компоновки имеет пустое поле группировки —
// без этой проверки в выгрузку попадёт фантомная строка «Итого» как ещё один менеджер.

      Если Не ЗначениеЗаполнено(СтрокаМенеджера.Менеджер) Тогда
         Продолжить;
      КонецЕсли;

      ЗаписьJSON.ЗаписатьНачалоОбъекта();
      ЗаписьJSON.ЗаписатьИмяСвойства("менеджер");
      ЗаписьJSON.ЗаписатьЗначение(Строка(СтрокаМенеджера.Менеджер));
      ЗаписьJSON.ЗаписатьИмяСвойства("бонус");
      ЗаписьJSON.ЗаписатьЗначение(СтрокаМенеджера.Бонус);
      ЗаписьJSON.ЗаписатьКонецОбъекта();

   КонецЦикла;

   ЗаписьJSON.ЗаписатьКонецМассива();
   ТекстJSON = ЗаписьJSON.Закрыть();

   Если Не ЗначениеЗаполнено(ТекстJSON) Тогда
      Возврат "";
   КонецЕсли;

// проблема: третьим параметром управляется добавление BOM. Без него строка уедет
// с меткой порядка байт, и строгие парсеры на приёмной стороне падают.

   Двоичные = ПолучитьДвоичныеДанныеИзСтроки(ТекстJSON, КодировкаТекста.UTF8, Ложь);
   Возврат ПоместитьВоВременноеХранилище(Двоичные, ИдентификаторФормы);

КонецФункции

Последовательность «загрузить настройки ? загрузить пользовательские ? ПолучитьНастройки()» — типовая, она же используется в модулях самой конфигурации. Если её пропустить и компоновать по Схема.НастройкиПоУмолчанию, кнопка будет выгружать не то, что пользователь видит на экране: без его периода, отборов и структуры.

Ещё тонкость компоновщика: если у отчёта есть фиксированные настройки и они пересекаются по отборам или параметрам с пользовательскими, ПолучитьНастройки() выдаст ошибку. Это не про наш пример, но про контекстные отчёты — сплошь и рядом.

 

Грабля отдельного разговора: период «как в типовых»

Требование «стандартный период, как в типовых отчётах» выглядит тривиально, но одиночный параметр типа СтандартныйПериод в СКД рендерится на форме пустым пикером без дат «с… по…». В типовых сделано хитрее, и повторять нужно ровно их схему (эталон — «Валовая прибыль по оплаченным отгрузкам»):

  • параметр ПериодОтчета (тип СтандартныйПериод, заголовок «Период», значение Custom с пустыми датами, useRestriction = false, и без use = Always);
  • два производных параметра НачалоПериода и КонецПериода (useRestriction = true) с выражениями &ПериодОтчета.ДатаНачала и &ПериодОтчета.ДатаОкончания;
  • в варианте настроек — ПериодОтчета = ThisMonth с userSettingID.

Тогда интерфейс становится привычным: флажок, две даты и кнопка выбора стандартных периодов, а конец периода автоматически равен концу дня.

И здесь же — самая коварная грабля всей задачи, из категории «внешне всё работает». Рука тянется на всякий случай обернуть конец периода в запросе: КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ). Не делайте этого с производным параметром стандартного периода. Во-первых, это не нужно — ДатаОкончания уже конец дня. Во-вторых, когда пользователь очищает период, пустая дата — это начало отсчёта, 01.01.0001 00:00:00, и КОНЕЦПЕРИОДА превращает её в реальную границу того же первого года. Условия МЕЖДУ честно отсекают по ней все данные — отчёт молча пуст, без единой ошибки. Дефолтный ThisMonth маскирует проблему: она выстреливает только у пользователя, который очистил период, — то есть уже в проде.

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

ГДЕ

(Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода

ИЛИ &КонецПериода = ДАТАВРЕМЯ(1, 1, 1)

И Продажи.Период >= &НачалоПериода)

И <прочие условия отбора>

Внешние скобки обязательны. Приоритет операций в языке запросов — НЕ, потом И, потом ИЛИ; без скобок первое же дописанное И Организация = &Организация приклеится к правой ветке ИЛИ, и условие периода перестанет работать при заполненном периоде. В эталоне скобки стоят ровно по этой причине.

Раз речь зашла о границах: по тому, как это сделано в типовых (в остатки эталон передаёт не голую дату, а ГраницаПериода(..., "Включая")), граница у остатков ведёт себя как невключающая, у оборотов — как включающая. Отсюда правило: «конец дня» нужен оборотам, а для остатков «на конец дня» корректнее передавать границу с видом «Включая» или начало следующего дня. И отдельно, по #std733: если нужны текущие остатки, дату в параметр виртуальной таблицы лучше вообще не передавать — с датой платформа читает не только хранимые итоги, но и таблицу движений.

 

Чек-лист «кнопки нет, ошибок нет»

Порядок совпадает с порядком, в котором отрабатывает БСП.

  1. Роль. Есть ли у непривилегированного пользователя право «Просмотр» на ваш отчёт? Без роли расширения отчёт видит только администратор.
  2. Сеанс. Перезашли в базу после изменения расширения? Версия расширений фиксируется на старте сеанса — старый сеанс работает со старым кэшем.
  3. Хранилище вариантов. Отчёт подключён — через свойство конфигурации или своё собственное?
  4. Формы. Указаны все три общие формы (или они наследуются от корня конфигурации)?
  5. Подсистема. Отчёт в составе ПодключаемыеОтчетыИОбработки, а в модуле менеджера есть ПриОпределенииНастроек с ОпределитьНастройкиФормы = Истина? Это шлюз 1. Альтернатива — точка А-штрих.
  6. Модуль объекта. Есть ОпределитьНастройкиФормы, и в ней поднят Настройки.События.ПриСозданииНаСервере? Это шлюзы 2 и 3. Если отчёт прошёл шлюз 1, а процедуры нет — увидите явное исключение с упоминанием ОпределитьНастройкиФормы и кэша. Для внешних отчётов это исключение подавляется молча и в журнал тоже ничего не пишется — там остаётся только собственное логирование.
  7. Сигнатура. НастроитьВариантыОтчета объявлена с двумя параметрами? Иначе — тихая запись в журнал про «КлючВарианта».
  8. Вывод команды. Кнопка выводится через ОтчетыСервер.ВывестиКоманду? Ручная вставка КнопкаФормы без регистрации в ПостоянныеКоманды даст кнопку, по которой диспетчер не найдёт ваш обработчик.
  9. Расширение применилось? Если перехватываете чужой модуль — при несовпадении сигнатуры платформа тихо отключает расширение метода с предупреждением.
  10. Модель сервиса. В неразделённом сеансе отчёты расширений в подсистему не попадают вовсе.

 

Итог: как выбирать путь

 

  Внешний (дополнительный) отчёт Расширение, своя форма Расширение, форма БСП
Время до результата ~20 минут ~30 минут 2–4 часа в первый раз
Варианты, панели отчётов, рассылки да, при хранилище + трёх общих формах нет (или с оговорками) полностью, из коробки
Своя кнопка серверная часть — да, клиентский обработчик положить некуда тривиально штатно, ОтчетыСервер.ВывестиКоманду
Точка подключения кнопки ОпределитьНастройкиФормы в модуле объекта модуль своей формы А — свой модуль объекта; А-штрих и Б — заимствование модуля
Живёт в базе, версионируется с решением нет да да
Кому подходит разовые задачи, отчёты без своих команд служебные и нетиповые отчёты пользовательские отчёты «навсегда»

 

Мой вывод после того, как я прошёл все три пути на одной задаче: если отчёт станет частью прикладного решения и им пользуется кто-то кроме вас — сразу идите путём 3, точкой А. Она требует на полчаса больше внимания в начале (подсистема, модуль менеджера, модуль объекта, роль), но не заимствует ни одного общего модуля типовой и не выполняется на чужих формах.

Точка А-штрих и точка Б — не «плохие практики», а инструменты под другие задачи: поднять флаг отчёту, когда состав подсистем вам не подвластен, и добавить команду отчётам, которые вам не принадлежат. Первый и второй пути тоже имеют право на жизнь — просто теперь понятно, за что именно вы платите, выбирая их.

Главный же вывод шире одной кнопки: почти все «мистические» отказы БСП — это непройденные шлюзы, о которых библиотека молчит по дизайну. Как только видишь цепочку целиком, «работает через раз» превращается в «не выполнено условие номер три».

* * *

Проверено на: платформа 1С:Предприятие 8.3.27.2214, «Управление торговлей» ред. 11.5 (демо) и БСП из её состава, формат выгрузки XML 2.20. Механику подсистемы «Варианты отчётов» сверял по двум выгрузкам — УТ 11.5.27.61 и Розница 3.0.13.374: там она совпадает дословно (сигнатура ВывестиКоманду, шесть значений ТипГруппы, порядок хуков в ФормаОтчета, условие раннего выхода в НастройкиОтчета). На КА 2.5, ERP 2.5, БП 3.0 и УНФ рецепт должен работать так же — это тот же код БСП, — но лично я его там не проверял.

Если на другой версии платформы или БСП поведение отличается — напишите в комментариях: интересно собрать карту различий между релизами.

Вступайте в нашу телеграмм-группу Инфостарт

БСП СКД расширение конфигурации ОтчетыПереопределяемый варианты отчётов внешний отчёт стандартный период JSON 1С:Управление торговлей 11

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Работа с интерфейсом Анализ учета Мониторинг 1С:Предприятие 8 1С 8.3 1C:Бухгалтерия 1С:Бухгалтерия 3.0 1С:ERP Управление предприятием 2 1С:Управление холдингом 1С:Зарплата и Управление Персоналом 3.x 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 11 Платные (руб)

Создайте свой функциональный интерфейс в любой конфигурации 1С с помощью расширения Infostart Dashboard. Настраивайте панели виджетов с метриками, индикаторами и показателями на начальном экране. Узнайте возможность внедрения подсистемы у себя в конфигурации с помощью бесплатной обработки "Анализ внедрения подсистемы 1С Infostart Dashboard"!

31720 руб.

27.03.2025    88224    63    44    

74

Работа с интерфейсом Программист 1С:Предприятие 8 1C:Бухгалтерия 1С:ERP Управление предприятием 2 Платные (руб)

Обработка предназначена для создания и управления дашбордами (виджетами) в 1С.

5246 руб.

29.06.2020    25435    34    6    

53

Консолидация данных Работа с интерфейсом Программист Пользователь 1С:Предприятие 8 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 1C:ERP Узбекистан Беларусь Кыргызстан Россия Казахстан Платные (руб)

Знакомая ситуация? Пользователи, особенно менеджеры, уверены: отборов много не бывает. Идут пожелания добавить в форму списка еще один быстрый фильтр, еще два, еще пять... В итоге интерфейс превращается в нагромождение полей отбора, а потребность в «самом главном» отборе, который «вот прямо сейчас нужен», все равно не закрыта. Универсальное расширение, которое решает эту проблему элегантно и технологично. С его помощью в любую форму списка можно легко добавить панель настраиваемых кнопок-закладок, каждая из которых применяет сложный фильтр-запрос, а так же показывает актуальное количество элементов в реальном времени.

6088 руб.

17.10.2025    2661    3    0    

2

Разработка Инструментарий разработчика Работа с интерфейсом Адаптация типовых решений Нейросети 1C:Бухгалтерия 1C:ERP 1С:ЗУП 1С:КА 1С:УНФ 1С:УТ 1С:Розница 1С:ДО 1С:ERP Управление предприятием 2 Платные (руб)

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

36600 руб.

28.08.2025    8858    2    2    

6

Работа с интерфейсом Программист Стажер 1С:Предприятие 8 Бесплатно (free)

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

20.08.2024    52907    mrXoxot    44    

139

Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

Пример простого и симпатичного прогресс-бара в динамическом списке, без картинок, используя редактирование запроса.

27.05.2024    27847    smielka    39    

117

Инструментарий разработчика Работа с интерфейсом Программист 1С 8.3 Абонемент ($m)

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

1 стартмани

10.04.2023    18079    183    acces969    31    

132

Работа с интерфейсом Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

12.08.2022    14205    top_1c    39    

97
Для отправки сообщения требуется регистрация/авторизация