Почему возникает ошибка «Метод объекта не обнаружен (Инициализировать)» при заполнении табличных частей в 1С?

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

При активной многопользовательской работе в конфигурациях на обычных формах (таких как УПП или КА 1.1) периодически возникает трудноуловимая плавающая ошибка. Пользователь нажимает кнопку заполнения табличной части документа, после чего программа выдает сообщение: «Заполнение ТЧ не произведено! Метод объекта не обнаружен (Инициализировать)». При этом разработчик проверяет внешнюю обработку заполнения табличной части (ОЗТЧ) и видит, что экспортная процедура Инициализировать() присутствует в модуле объекта со всеми необходимыми параметрами. Интерактивная проверка под учетной записью того же пользователя в большинстве случаев проходит без сбоев.

Разберем природу этого поведения, выясним скрытую причину возникновения коллизии в терминальной среде и рассмотрим способы гарантированного устранения проблемы.

Анализ механизма работы типовых внешних обработок

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

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

В процедурах ОбработатьНажатиеНаДополнительнуюКнопкуЗаполненияТЧ и ПечатьПоДополнительнойКнопке разработчиками платформенных библиотек было заложено сохранение файла с жестко заданным именем PrnForm.tmp через конструкцию вида КаталогВременныхФайлов() + "PrnForm.tmp".

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

Рассмотрим ситуацию, когда множество сотрудников работают на терминальном сервере (RDS). В момент формирования печатной формы одним сотрудником двоичные данные печатной формы записываются в файл PrnForm.tmp. Если в эту же долю секунды другой пользователь (или тот же сотрудник во втором сеансе 1С) запускает обработку заполнения табличной части, возникает состояние гонки:

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

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

  1. Отсутствие изоляции каталогов TEMP в Windows Server: Если в политиках RDS включен общий каталог временных файлов, системная функция КаталогВременныхФайлов() возвращает единый для всех пользователей путь (например, C:\Windows\Temp).
  2. Несколько сеансов одного пользователя: Даже при настроенной изоляции по сессиям открытие нескольких окон 1С одним сотрудником использует одну и ту же пользовательскую директорию %USERPROFILE%\AppData\Local\Temp.
  3. Кэширование внешних файлов платформой 1С: Платформа кэширует скомпилированные модули внешних файлов, и при одинаковом имени файла может обращаться к старому дескриптору в памяти.

Способ 1. Исправление кода в общем модуле (Рекомендуемый)

Наиболее надежное решение — отказаться от статического имени PrnForm.tmp и перейти на генерацию уникальных имен файлов для каждого вызова. Для этого найдем в общем модуле УниверсальныеМеханизмы процедуры ОбработатьНажатиеНаДополнительнуюКнопкуЗаполненияТЧ и ПечатьПоДополнительнойКнопке.

Заменим жестко прописанное имя файла на вызов функции ПолучитьИмяВременногоФайла(). Посмотрим на пример доработки:


// Формируем уникальное имя файла для исключения коллизий
ИмяФайла = ПолучитьИмяВременногоФайла("epf");

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

При использовании уникального имени временного файла параллельные сеансы пользователей и разные потоки никогда не будут перезаписывать данные друг друга.

Способ 2. Настройка изоляции сеансов на терминальном сервере

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

  1. Откроем редактор локальной групповой политики (команда gpedit.msc).
  2. Перейдем по пути: Конфигурация компьютера -> Административные шаблоны -> Компоненты Windows -> Службы удаленных рабочих столов -> Узел сеансов удаленных рабочих столов -> Временные папки.
  3. Найдем параметр «Не использовать временные папки для каждой сессии» (Do not use temporary folders per session) и переведем его в состояние «Отключено» (Disabled).
  4. Включим параметр «Удалять временные папки при выходе», чтобы предотвратить засорение диска накопившимися временными файлами.

После применения этих политик каждый терминальный сеанс получит изолированную подпапку вида Temp\<SessionID>, что снизит вероятность взаимной перезаписи файлов между разными пользователями.

Способ 3. Перенос алгоритма в состав конфигурации

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

← На главную