Как эффективно модифицировать объемные процедуры в типовых конфигурациях 1С с помощью расширений и альтернативных методов?

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

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

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

Основные сложности модификации типовых процедур

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

Разработчики 1С не всегда проектируют типовые модули с расчетом на легкое наследование и модификацию, что приводит к так называемой "проблеме хрупкого базового класса" (fragile base class problem). Это означает, что даже небольшое изменение в типовой конфигурации может привести к некорректной работе наших доработок.

Механизмы расширений и их применение

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

  1. Аннотации &Перед, &После, &Вместо и ПродолжитьВызов

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

    • &Перед: Метод расширения выполняется перед оригинальным методом. Это полезно для предварительной подготовки данных, проверки условий или изменения входных параметров.
    • &После: Метод расширения выполняется после оригинального метода. Мы можем использовать его для пост-обработки результатов, логирования или изменения выходных параметров.
    • &Вместо: Метод расширения полностью замещает оригинальный метод. Это мощный инструмент, но он требует осторожности, так как полностью перекрывает типовой алгоритм. Если нам нужно вызвать оригинальный метод внутри замещающего, мы можем использовать конструкцию ПродолжитьВызов().

    Преимущества: Позволяют гибко внедрять логику без изменения исходного кода конфигурации.

    Недостатки: Могут возникнуть трудности с обновлением, если оригинальный метод сильно изменится. Использование &Вместо несколькими расширениями может привести к конфликтам, так как только одно из них будет применено (порядок определяется приоритетом расширений).

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

  2. Механизм &ИзменениеИКонтроль

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

    • #Вставка ... #КонецВставки: Используются для добавления нового кода в модуль.
    • #Удаление ... #КонецУдаления: Используются для удаления фрагментов существующего кода.

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

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

    На практике, некоторые разработчики сознательно переходят на использование &ИзменениеИКонтроль, находя его эффективным для экономии времени на обновлениях, несмотря на необходимость ручного контроля.

Альтернативные подходы к модификации печатных форм

Для печатных форм обсуждение особенно активно, так как это частая точка доработок. Здесь существует принципиальный выбор между использованием внешних печатных форм (ВПФ) и размещением печатных форм в расширении.

  1. Внешние печатные формы (ВПФ)

    ВПФ разрабатываются как отдельные файлы (.epf), которые подключаются к базе в пользовательском режиме. Они взаимодействуют с системой через стандартизированные интерфейсы БСП (Библиотека стандартных подсистем).

    Преимущества:

    • Гибкость и независимость: ВПФ предоставляют полную свободу в настройке дизайна и функционала. Мы можем создавать уникальные макеты и алгоритмы печати, не затрагивая типовую конфигурацию.
    • Минимальный риск конфликтов: Поскольку ВПФ работают через стандартизированные точки интеграции, риск конфликтов при обновлении типовой конфигурации минимален. Если БСП не меняется кардинально, ВПФ обычно продолжают работать.
    • Простота подключения/отключения: Пользователи могут самостоятельно подключать, отключать или обновлять ВПФ в режиме "Предприятие" без участия разработчика и перезапуска сеансов.
    • Легкость тиражирования: Мы можем создать одну ВПФ и легко подключить ее к множеству баз, даже если они находятся на разных серверах.
    • Независимость от обновлений: ВПФ можно исправлять и обновлять, не дожидаясь "демонического обновления" всей конфигурации.

    Недостатки:

    • Отсутствие прямого доступа: ВПФ имеют ограниченный доступ к внутренним модулям и объектам конфигурации по сравнению с расширениями.
    • Сложность разработки и отладки: Иногда разработка ВПФ может быть сложнее, если требуется сложная логика, которая тесно связана с внутренними алгоритмами.
    • Хранение дополнительных данных: ВПФ не могут хранить дополнительные данные в метаданных, что иногда может усложнить реализацию специфических требований.

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

  2. Печатные формы в расширениях

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

    Преимущества:

    • Интеграция с конфигурацией: Печатные формы в расширении могут более глубоко интегрироваться с общими модулями, подписками на события и другими механизмами платформы.
    • "Все в одном": Если наше расширение уже содержит другие изменения, связанные с документом (новые реквизиты, измененные формы), то размещение печатной формы там же может казаться логичным.
    • Централизованное управление: Для множества баз, которые должны иметь идентичные доработки, расширение может быть проще обновлять скриптом, если мы уверены в его стабильности.

    Недостатки:

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

    Когда применять: Печатные формы в расширениях подходят для небольших "косметических" доработок типовых макетов (например, добавление телефона или адреса клиента), а также в случаях, когда требуется глубокая интеграция с уже модифицированными в расширении объектами или алгоритмами. Необходимо тщательно соблюдать стиль написания процедур, чтобы минимизировать риски при обновлениях.

Технические приемы для инъекции логики в середину процедур

Если нам необходимо внести изменения в середину большой процедуры, которая не разбита на подпроцедуры и не имеет удобных точек расширения, нам придется прибегнуть к более изощренным методам. Одним из таких методов является модификация результатов запросов через ТаблицаЗначений.

Модификация результатов запросов через ТаблицуЗначений (ТЗ)

Предположим, у нас есть типовая процедура, которая формирует данные для отчета или печатной формы с помощью сложного запроса, оперирующего временными таблицами (Менеджер Временных Таблиц – МВТ). Если нам нужно добавить новую колонку, изменить значения или отфильтровать данные, но мы не можем напрямую изменить текст запроса, мы можем использовать следующий подход:

  1. Выгружаем данные из временной таблицы в ТаблицаЗначений.

    Для этого мы используем метод ПолучитьДанные().Выгрузить() от менеджера временных таблиц.

    
    ТЗ = Запрос.МенеджерВременныхТаблиц.Таблицы["Какаятовременнаятаблица"].ПолучитьДанные().Выгрузить();
    

    Здесь "Какаятовременнаятаблица" - это имя временной таблицы, которая была создана ранее в запросе.

  2. Модифицируем ТаблицаЗначений.

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

    • Добавлять новые колонки: ТЗ.Колонки.Добавить("НоваяКолонка");
    • Заполнять значения новых или существующих колонок, используя данные из других колонок или внешние источники:
      
      Для Каждого СтрокаТЗ из ТЗ Цикл
          СтрокаТЗ.НоваяКолонка = СтрокаТЗ.Колонка1 * СтрокаТЗ.Колонка2;
          // ... тут какая-то дополнительная логика по модификации ТЗ
      КонецЦикла;
      
    • Фильтровать или удалять строки.
  3. Помещаем модифицированную ТаблицаЗначений обратно во временную таблицу.

    После всех необходимых изменений мы формируем новый запрос, который уничтожает старую временную таблицу (если она больше не нужна) и создает новую, используя нашу модифицированную ТаблицаЗначений как источник данных.

    
    МассивПолейВыборки = Новый Массив;
    Для Каждого Колонка Из ТЗ.Колонки Цикл
        МассивПолейВыборки.Добавить(Колонка.Имя);
    КонецЦикла;
    ТекстПолейВыборки = СтрСоединить(МассивПолейВыборки, ",");
    
    ТекстЗапроса = "
        |УНИЧТОЖИТЬ Какаятовременнаятаблица // Уничтожаем старую ВТ, если нужно
        |;
        |ВЫБРАТЬ
        |    " + ТекстПолейВыборки + "
        |ПОМЕСТИТЬ Какаятовременнаятаблица // Создаем новую ВТ с обновленными данными
        |ИЗ 
        |    &Таблица КАК Таблица";
    
    Запрос.Текст = ТекстЗапроса;
    Запрос.УстановитьПараметр("Таблица", ТЗ); // Передаем нашу модифицированную ТЗ как параметр
    Запрос.Выполнить();
    

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

Нюансы и рекомендации:

Радикальный подход: Снятие конфигурации с поддержки

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

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

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

Общие рекомендации для разработчиков

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

  1. Вдумчивый выбор метода доработки: Перед началом работы всегда анализируйте характер и объем требуемых изменений. Для печатных форм часто оптимальным решением являются внешние печатные формы. Для модификации алгоритмов — используйте механизмы расширений с аннотациями &Перед, &После, &Вместо или &ИзменениеИКонтроль, осознавая их ограничения и риски.
  2. Используйте специальные модули: Обращайте внимание на модули типа ХХХ_Переопределяемый. Они специально предусмотрены для расширения функциональности.
  3. Освойте технические трюки: Методы, подобные модификации запросов через ТаблицаЗначений, могут быть спасением в сложных ситуациях, когда нужно вклиниться в середину алгоритма.
  4. Тщательное тестирование: После каждого обновления типовой конфигурации обязательно проводите тщательное тестирование всех доработок, особенно тех, что реализованы с помощью расширений.
  5. Документирование: Всегда документируйте свои доработки, чтобы в будущем было легче понять, что и зачем было изменено, и как это взаимодействует с типовой конфигурацией.

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

← На главную