Как исправить ошибку «Метод объекта не обнаружен (РассчитатьВсеНаСервере)» в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При обновлении типовых конфигураций (например, 1С:Зарплата и управление персоналом с версии 3.1.11 на 3.1.12 и выше) разработчики часто сталкиваются с неожиданным поведением внешних обработок. Код, который годами успешно создавал, заполнял и рассчитывал документы в фоновом режиме, внезапно начинает аварийно завершаться с ошибкой: Метод объекта не обнаружен (РассчитатьВсеНаСервере).

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

Выясняем причину: почему код работал раньше, но перестал сейчас?

Давайте проанализируем ситуацию. Типичный сценарий работы внешней обработки выглядит следующим образом:


&НаКлиенте
Процедура Загрузить(Команда)
    
    ДокументСсылка = КомандаСоздатьДокументНаСервере();
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Ключ", ДокументСсылка);
    Форма = ПолучитьФорму("Документ.Премия.ФормаОбъекта", ПараметрыФормы, ЭтаФорма);
    Форма.ВладелецФормы = ЭтаФорма;
    
    Форма.Открыть();
    Форма.РассчитатьВсеНаСервере(); // Ошибка возникает здесь!
    
КонецПроцедуры

В старых релизах конфигураций этот код успешно выполнялся. Но после обновления платформы или повышения режима совместимости конфигурации вызов Форма.РассчитатьВсеНаСервере() приводит к ошибке выполнения. При этом сама процедура РассчитатьВсеНаСервере() по-прежнему физически присутствует в модуле формы документа.

Секрет кроется в режиме совместимости платформы 1С:Предприятие:

  1. Особенность старых версий (до 8.3.13): В платформе существовала недокументированная лазейка (особенность работы клиент-серверного взаимодействия). Если внешняя обработка получала контекст управляемой формы на клиенте, она могла напрямую вызывать серверные процедуры этой формы (&НаСервере), даже если у этих процедур отсутствовало ключевое слово Экспорт.
  2. Усиление безопасности (начиная с платформы 8.3.13): Фирма «1С» ужесточила контроль вызовов процедур и функций. Теперь вызов любого неэкспортного метода объекта извне (из другой формы, внешней обработки или общего модуля) жестко блокируется платформой на уровне ядра.
  3. Обновление конфигурации: При переходе на новые релизы (в данном случае с ЗУП 3.1.11 на 3.1.12) разработчики конфигурации подняли минимальный режим совместимости. В результате «уязвимость» закрылась, и все неэкспортные вызовы превратились в фатальные ошибки.

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

---

Способ 1. Использование расширения конфигурации (Быстрый путь)

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

Разберем этот процесс по шагам:

  1. Создайте новое расширение в базе данных (или откройте существующее).
  2. Добавьте в расширение форму документа (в нашем примере — форму объекта документа Премия).
  3. В модуле формы расширения перехватите процедуру РассчитатьВсеНаСервере с помощью аннотации &Вместо и добавьте ключевое слово Экспорт:

&Вместо("РассчитатьВсеНаСервере")
&НаСервере
Процедура Расш_РассчитатьВсеНаСервере(ОписаниеТаблицы = Неопределено) Экспорт
    // Вызываем оригинальный расчет формы
    ПродолжитьВызов(ОписаниеТаблицы);
КонецПроцедуры

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

---

Способ 2. Передача параметров при открытии формы (Правильный UI-путь)

Более грамотным с точки зрения архитектуры решением является передача управляющего флага (параметра) в форму при ее открытии. Форма сама должна принимать решение о запуске расчета, анализируя переданные ей параметры.

Рассмотрим, как реализовать этот подход:

Шаг 1. Модифицируем код вызова во внешней обработке:

Вместо прямого вызова серверного метода формы после ее открытия, мы передадим специальный параметр в структуру параметров формы:


&НаКлиенте
Процедура Загрузить(Команда)
    
    ДокументСсылка = КомандаСоздатьДокументНаСервере();
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Ключ", ДокументСсылка);
    // Добавляем наш собственный параметр авторасчета
    ПараметрыФормы.Вставить("ВыполнитьАвторасчетПриОткрытии", Истина);
    
    // Открываем форму сразу с параметрами
    ОткрытьФорму("Документ.Премия.ФормаОбъекта", ПараметрыФормы, ЭтаФорма);
    
КонецПроцедуры

Шаг 2. Обработка параметра в форме документа (через расширение):

В расширении формы документа перехватываем стандартный обработчик ПриСозданииНаСервере или ПриОткрытии и запускаем расчет локально:


&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, передан ли наш параметр авторасчета
    Если Параметры.Свойство("ВыполнитьАвторасчетПриОткрытии") 
        И Параметры.ВыполнитьАвторасчетПриОткрытии Тогда
        
        // Вызываем штатный расчет локально на сервере внутри контекста формы
        РассчитатьВсеНаСервере();
        
    КонецЕсли;
    
КонецПроцедуры

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

---

Способ 3. Полностью программный расчет на сервере (Идеальный путь)

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

Наиболее надежный и профессиональный подход — полностью отказаться от интерактивного открытия формы. Современные типовые конфигурации (включая ЗУП 3) позволяют рассчитывать документы программно на стороне сервера с помощью встроенного API.

Проанализируем пример схемы программного расчета документа без открытия его формы:


&НаСервере
Процедура СоздатьИРассчитатьДокументНаСервере()
    
    // 1. Создаем новый объект документа
    НовыйДокумент = Документы.Премия.СоздатьДокумент();
    НовыйДокумент.Дата = ТекущаяДата();
    НовыйДокумент.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7701020304");
    
    // ... Заполняем табличные части (Сотрудники, Начисления и т.д.) ...
    
    // 2. Вызываем специализированный программный расчет ЗУП.
    // В зависимости от версии ЗУП это могут быть общие модули проведения расчетов.
    // Например, для автоматического заполнения НДФЛ, взносов и средних заработков:
    ПараметрыРасчета = ПроведениеРасчетовХХ.ПодготовитьПараметрыРасчета(НовыйДокумент);
    ПроведениеРасчетовХХ.ВыполнитьРасчет(НовыйДокумент, ПараметрыРасчета);
    
    // 3. Записываем и проводим готовый и полностью рассчитанный документ
    НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
    
КонецПроцедуры

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

← На главную