Почему измененная схема компоновки данных типового отчета 1С не работает в расширении и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

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

В чем заключается проблема

Обычно проблема проявляется, когда мы пытаемся добавить новое поле (например, "Объект.Код", как в нашем случае) в отчет, основанный на СКД, такой как "СправкаРасчетАмортизации". Мы изменяем макет СКД отчета, добавляем поле в запрос и в настройки схемы, и в основной конфигурации все работает. Однако, при заимствовании этого макета в расширение и попытке использования отчета, система сообщает об ошибке: "Отчет не сформирован! Поле не найдено 'Объект.Код'". Это происходит из-за особенностей работы расширений с заимствованными объектами, особенно с макетами. Например, в конфигурации 1С:Предприятие 8.3 (8.3.20.1674) Бухгалтерия предприятия КОРП, редакция 3.0 (3.0.108.36), отчет "СправкаРасчетАмортизации" ведет себя именно так при попытке добавить поле "Код" основного средства через расширение.

Почему заимствованный макет СКД не работает напрямую

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

Рекомендуемые подходы для изменения отчетов на СКД в расширении

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

Подход 1: Полное копирование отчета и его макета СКД в расширение

Этот метод является наиболее простым и обеспечивает максимальную свободу действий. Мы полностью создаем копию стандартного отчета в расширении, фактически создавая новый отчет на основе типового. Давайте рассмотрим шаги, которые нам необходимо выполнить:

  1. Создание нового отчета в расширении: Мы открываем наше расширение в конфигураторе. В дереве объектов расширения создаем новый объект "Отчет". Даем ему уникальное и понятное имя, например, СправкаРасчетАмортизации_Расширенная или СправкаРасчетАмортизацииСКодомОС. Важно, чтобы это имя не конфликтовало с существующими отчетами.
  2. Копирование макета СКД: Переходим к исходному типовому отчету в основной конфигурации (например, Отчет.СправкаРасчетАмортизации). Открываем его макет схемы компоновки данных. Копируем содержимое этого макета. Возвращаемся в наш новый отчет в расширении и вставляем скопированный макет. Присваиваем ему уникальное имя (например, ОсновнаяСхемаКомпоновкиДанныхРасш).
  3. Модификация макета: Теперь, когда у нас есть полная копия макета СКД внутри нашего нового отчета в расширении, мы можем свободно его редактировать:
    • Изменение запроса: Открываем макет СКД, переходим на вкладку "Наборы данных". Выбираем набор данных типа "Запрос" и модифицируем текст запроса. Добавляем новое поле в инструкцию ВЫБРАТЬ, используя необходимые соединения с другими таблицами, если это требуется. Например, для добавления кода основного средства нам может потребоваться присоединить таблицу справочника "Основные средства" и выбрать из нее реквизит Код.
      
      ВЫБРАТЬ
          СпрОС.Код КАК КодОсновногоСредства,
          ТаблицаДвижений.ОсновноеСредство КАК ОсновноеСредство,
          // ... другие поля типового запроса
      ИЗ
          РегистрНакопления.АмортизацияОС.ОстаткиИОбороты КАК ТаблицаДвижений
              ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ОсновныеСредства КАК СпрОС
              ПО ТаблицаДвижений.ОсновноеСредство = СпрОС.Ссылка
      // ... прочие соединения и условия
      
    • Добавление поля в структуру СКД: После изменения запроса необходимо убедиться, что новое поле присутствует в списке полей набора данных СКД. Находясь на вкладке "Наборы данных", нажмите кнопку "Заполнить выражения" (или "Заполнить" для старых версий). Наше новое поле (например, КодОсновногоСредства) должно появиться в списке "Поля". Убеждаемся, что для него корректно определены тип данных и заголовок.
    • Настройка использования поля: Далее переходим на вкладки "Настройки", "Поля", "Вычисляемые поля" или "Ресурсы" макета СКД и добавляем наше новое поле в соответствующие списки в зависимости от того, как мы планируем его использовать в отчете (как измерение, ресурс, просто выводимое поле и т.д.).
  4. Перенаправление использования отчета: Чтобы пользователи могли получить доступ к нашему новому, расширенному отчету, мы можем:
    • Добавить его в соответствующую подсистему в расширении, создав новый пункт меню или добавив его в существующий.
    • Если наша цель полностью заменить стандартный отчет, можно заимствовать команду вызова оригинального отчета в расширении и изменить ее действие так, чтобы она открывала наш новый отчет, а оригинальный отчет при этом скрыть или сделать недоступным.

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

Подход 2: Механизм подмены схемы компоновки данных (для типовых бухгалтерских отчетов)

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

  1. Копирование макета СКД в расширение: В этом подходе мы не создаем новый отчет. Вместо этого, мы заимствуем сам объект "Отчет" из основной конфигурации в расширение (например, Отчет.СправкаРасчетАмортизации). Затем в расширении создаем новый макет, копируя содержимое макета СКД из типового отчета и присваиваем ему уникальное имя (например, СхемаСправкаРасчетАмортизации_Расш).
  2. Модификация скопированного макета: Как и в предыдущем подходе, вносим все необходимые изменения в этот новый макет, который теперь находится в расширении. Добавляем поля в запрос, описываем их в наборах данных, настраиваем использование в СКД. Это точно такие же действия, как и в пункте 3 "Подхода 1".
  3. Добавление реквизита ТекущаяСхемаКомпоновкиДанных: Заимствуем объект "Отчет" в расширении. В метаданных заимствованного отчета (в расширении) проверяем наличие реквизита с именем ТекущаяСхемаКомпоновкиДанных строкового типа. Если его нет, создаем его. Если он уже есть, просто убеждаемся, что он строкового типа. Этот реквизит будет использоваться для динамического хранения имени макета СКД, который должен быть использован.
  4. Реализация процедур подмены в модуле менеджера отчета: Самый важный шаг – это реализация в модуле менеджера заимствованного отчета в расширении двух специальных процедур, которые будут использоваться платформой для определения, какую схему компоновки данных применить. Эти процедуры переопределяют стандартное поведение выбора схемы:
    • Процедура НовыеПараметрыВыбораСхемыКомпоновкиДанных: Эта процедура предназначена для определения параметров, которые могут влиять на выбор схемы. Если у вас нет особых условий для выбора схемы (например, в зависимости от прав пользователя, версии программы или других настроек), она может возвращать пустую структуру или просто ничего. Мы можем использовать ее для передачи дополнительных сведений.
    • Процедура ТекущаяСхемаКомпоновкиДанных: Эта процедура принимает структуру параметров (которая была заполнена в предыдущей процедуре, если это необходимо) и должна возвращать имя макета СКД, который будет использоваться для формирования отчета. Именно здесь мы указываем имя нашего нового, измененного макета из расширения.

    Вот пример кода, который мы должны добавить в модуль менеджера заимствованного отчета в расширении:

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

    Обратите внимание, что имя ОсновнаяСхемаКомпоновкиДанных – это стандартное имя макета СКД в большинстве типовых отчетов 1С, и его мы возвращаем, если не хотим использовать расширенную схему. Имя СхемаСправкаРасчетАмоновкиДанных_Расш – это имя нашего макета в расширении, которое мы создали на первом шаге.

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

Причины ошибки "Поле не найдено 'Объект.Код'"

Давайте подробнее разберем, почему возникает ошибка "Поле не найдено 'Объект.Код'", даже если кажется, что все сделано правильно. Понимание этих причин поможет нам избежать подобных ошибок в будущем:

  1. Отсутствие поля в запросе: Самая частая причина. Мы можем скопировать макет и даже добавить поле в доступные поля СКД, но забыть фактически изменить текст запроса в наборе данных СКД. Или изменить его некорректно. Запрос, который формируется в наборе данных СКД, должен явно выбирать новое поле из базы данных. Убедитесь, что запрос SQL-подобного языка внутри макета СКД содержит новое поле, и оно правильно присоединено или выбрано. Например, если мы добавляем код объекта (как в исходной проблеме), запрос должен выглядеть примерно так:
    
    ВЫБРАТЬ
        // ... другие поля
        Объекты.Код КАК КодОбъекта
    ИЗ
        Справочник.Объекты КАК Объекты
    // ... прочие соединения и условия, например, соединение с таблицей,
    // из которой мы выбираем другие данные для отчета
    

    Если поле КодОбъекта не будет выбрано запросом, СКД никогда его не "увидит", и при попытке обратиться к нему возникнет ошибка.

  2. Некорректное описание поля в СКД: Даже если поле добавлено в запрос, необходимо убедиться, что оно корректно "объявлено" в самой схеме компоновки данных. Это отдельный шаг после модификации запроса:
    • Перейдите на вкладку "Наборы данных" в макете СКД.
    • Откройте набор данных (обычно это запрос), в котором вы изменили текст запроса.
    • Нажмите кнопку "Заполнить выражения" (или "Заполнить" в более старых версиях платформы). Это обновит список полей, доступных в наборе данных, на основе модифицированного запроса. Наше новое поле должно появиться в списке "Поля".
    • Убедитесь, что для нового поля корректно указаны тип данных, выражение представления и, при необходимости, роль.
    • После этого перейдите на вкладки "Доступные поля", "Вычисляемые поля" или "Ресурсы" и добавьте наше поле в нужный список с правильными настройками. Если поле присутствует в запросе, но не описано в наборе данных СКД или не добавлено в доступные поля, оно не будет видно для дальнейших настроек и использования в отчете.
  3. Конфликты объектов или некорректное заимствование: Если новое поле, которое мы добавляем в отчет, берется из объекта метаданных (например, справочника, документа, регистра), который сам был изменен или добавлен в расширение, необходимо убедиться, что:
    • Сам объект метаданных (например, справочник "Основные средства", если мы добавили в него новый реквизит) был корректно заимствован или создан в расширении.
    • Все реквизиты, на которые ссылается запрос в СКД, также присутствуют в расширении (либо заимствованы, либо созданы).
    • При заимствовании объекта (например, справочника), его структура в расширении должна соответствовать нашим ожиданиям (т.е. содержать все необходимые поля).

Программное изменение СКД

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


// Пример программного добавления вычисляемого поля
// Эта функция может быть вызвана из модуля отчета или общего модуля расширения.
Процедура ДобавитьВычисляемоеПоле(СхемаКомпоновкиДанных)
    // Создаем новый элемент коллекции полей СКД
    НовоеПоле = СхемаКомпоновкиДанных.Поля.Добавить(Тип("ПолеКомпоновкиДанных"));
    // Указываем имя поля, как оно будет использоваться в СКД
    НовоеПоле.Поле = "МоеНовоеВычисляемоеПоле";
    // Определяем заголовок, который будет отображаться пользователю
    НовоеПоле.Заголовок = "Мое новое вычисляемое поле";
    // Задаем выражение для вычисления значения поля.
    // Оно может ссылаться на другие поля в схеме или на параметры.
    НовоеПоле.Выражение = "Число(Объект.Код) * 10"; 
    // Указываем роль поля (Измерение, Ресурс, Реквизит и т.д.)
    НовоеПоле.Роль = "Измерение"; 
КонецПроцедуры

// Пример использования в модуле отчета или обработки, которая формирует отчет
// ...
// Получаем макет СКД из расширения (используя наш измененный макет)
МакетСКД = ОтчетОбъект.ПолучитьМакет("СхемаСправкаРасчетАмортизации_Расш");
// Создаем объект СхемаКомпоновкиДанных из макета
СхемаКомпоновкиДанных = МакетСКД.ПолучитьМакет("ОсновнаяСхема");

// Вызываем нашу процедуру для добавления вычисляемого поля
ДобавитьВычисляемоеПоле(СхемаКомпоновкиДанных);

// Далее работаем с компоновщиком данных, передавая ему модифицированную схему
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ПараметрыДанных);
// ... дальнейшая работа с процессором компоновки данных

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

Важные рекомендации

Для успешной работы с расширениями и СКД, а также для предотвращения возможных проблем, мы должны учесть следующие важные моменты:

  1. Режим совместимости: Крайне важно убедиться, что режим совместимости расширения соответствует режиму совместимости основной конфигурации. Иногда несовпадение режимов может вызывать непредсказуемое поведение, ошибки при доступе к данным или некорректную работу функционала. Проверить и изменить режим совместимости мы можем в свойствах расширения в конфигураторе.
  2. Включение всех необходимых объектов: Если наш измененный отчет ссылается на новые таблицы, реквизиты или другие метаданные, обязательно убедитесь, что все эти объекты также присутствуют в расширении. Мы либо заимствуем их из основной конфигурации, либо создаем новые в расширении, если они уникальны для нашей доработки. Иначе платформа не сможет их найти при выполнении запросов или обращении к данным.
  3. Отладка: Активно используйте отладчик 1С. Мы можем пошагово пройтись по коду отчета, особенно в момент формирования схемы компоновки данных, получения макета и работы компоновщика. Это поможет точно определить, на каком этапе теряется новое поле или возникает ошибка. Поставьте точки останова в процедурах, отвечающих за получение схемы компоновки данных (например, в процедурах, которые мы создали для подмены СКД), а также в местах, где происходит выполнение запроса СКД. Это поможет нам увидеть, какой запрос фактически выполняется и какие поля он возвращает.
  4. Внешние отчеты: Если доработка типового отчета оказывается слишком сложной, или механизмы заимствования и подмены не подходят для реализации наших специфических требований, рассмотрите вариант создания полностью внешнего отчета на СКД. Такой отчет мы можем разработать с нуля, а затем подключить его через расширение. Он будет работать абсолютно независимо от типового, давая полную свободу в его модификации и разработке, без привязки к внутренней структуре типовой конфигурации.

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

← На главную