Как исправить ошибку «СоздатьОбъект не определена» при переносе данных из 1С 7.7 в 1С 8.3?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Перенос данных со старых платформ 1С (таких как 1С:Предприятие 7.7) на современные конфигурации 1С:Предприятие 8.3 — задача, с которой регулярно сталкиваются разработчики. Для настройки правил обмена традиционно используется конфигурация «Конвертация данных 2.1». Однако в процессе выгрузки могут возникать весьма специфические ошибки компиляции, способные поставить в тупик даже опытного специалиста. Проанализируем одну из таких типовых проблем.

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

Симптомы проблемы выглядят следующим образом. При попытке выгрузки данных система выдает ошибку:

Ошибка в обработчике события ПередОбработкойВыгрузки группы свойств... ОписаниеОшибки = Ошибка компиляции при вычислении выражения или выполнении фрагмента кода: {(1,4)}: Процедура или функция с указанным именем не определена (СоздатьОбъект)

---

Причина 1. Контекст выполнения кода (Конфликт платформ 7.7 и 8.3)

Выясним, почему платформа выдает ошибку о неопределенности функции СоздатьОбъект. Эта функция является базовым методом платформы 1С 7.7 для инициализации объектов (таблиц значений, справочников, документов). В платформе 1С 8.x такого метода нет — вместо него используется оператор Новый.

Подобный сбой происходит в двух сценариях:

  1. Выгрузка через прямое подключение (COM/OLE): Если вы запускаете процесс выгрузки (или загрузки) непосредственно из базы 1С 8.3, выбирая режим «Подключение к информационной базе источнику», то обработка УниверсальныйОбменДаннымиXML пытается скомпилировать и выполнить код обработчиков непосредственно в контексте 8-ки. Встретив там чистый код 7.7, платформа 1С 8.3 закономерно выдает ошибку компиляции.
  2. Неправильно сгенерированные правила обмена: В настройках ПКО (Правила конвертации объектов) или ПКГС (Правила конвертации групп свойств) не было четко разграничено, на какой стороне должен выполняться данный код. Если обработчик написан для 1С 7.7, он должен компилироваться исключительно на стороне источника.

Рассмотрим два основных варианта решения этой архитектурной проблемы.

---

Решение варианта 1. Классический файловый обмен (Рекомендуемый способ)

При переносе данных из 1С 7.7 настоятельно рекомендуется отказаться от прямого COM-подключения из базы 8.3. Архитектурные различия платформ и утечки памяти при работе OLE-соединений могут приводить к зависаниям. Гораздо надежнее использовать выгрузку в промежуточный XML-файл.

Разберем по шагам, как настроить этот процесс правильно:

  1. Откройте конфигурацию «Конвертация данных 2.1», в которой хранятся ваши правила обмена.
  2. Перейдите к выгрузке правил. При сохранении файла правил (кнопка «Выгрузить правила») перейдите на закладку «Параметры выгрузки».
  3. Нажмите кнопку «Сформировать модуль выгрузки для 7.7». Система сгенерирует текстовый файл, содержащий программный код всех обработчиков, адаптированный под синтаксис 7.7.
  4. Откройте конфигуратор вашей информационной базы 1С 7.7. Найдите специализированную внешнюю обработку выгрузки (обычно это V77Exp.ert, поставляемая вместе с КД 2.1). Откройте её модуль и полностью замените существующий код сгенерированным текстом модуля выгрузки. Сохраните обработку.
  5. Запустите базу 1С 7.7 в режиме Предприятия, откройте подготовленную обработку V77Exp.ert, укажите файл правил обмена и выполните выгрузку в XML-файл. При этом код отработает корректно, так как он будет выполняться в родной среде 1С 7.7.
  6. В базе 1С 8.3 запустите стандартную обработку УниверсальныйОбменДаннымиXML и загрузите полученный файл данных.

---

Решение варианта 2. Исправление кода для работы по COM-соединению

Если по каким-то причинам вам необходимо производить выгрузку именно в режиме прямого подключения из базы 1С 8.3, то писать код на «чистом» языке 7.7 в обработчиках КД нельзя. Платформа 8.3 должна обращаться к объектам 7.7 через COM-соединение.

В правилах обмена при COM-подключении доступна глобальная переменная (обычно это БазаОле или V77). Все вызовы функций создания объектов должны адресоваться к ней. Посмотрим на пример изменения синтаксиса:


// Вместо прямого создания объектов в 7.7:
// тз = СоздатьОбъект("ТаблицаЗначений");
// сп = СоздатьОбъект("Справочник.Сотрудники");

// Используем обращение через OLE-соединение:
тз = БазаОле.CreateObject("ТаблицаЗначений");
сп = БазаОле.CreateObject("Справочник.Сотрудники");

Важно: При использовании OLE-соединения вам придется переписать абсолютно весь алгоритм обработчика, поскольку методы обхода выборки (ВыбратьЭлементы(), ПолучитьЭлемент()) также должны будут вызываться через COM-объект, что существенно снижает скорость работы и усложняет отладку.

---

Анализ и исправление ошибок в коде обработчика 1С 7.7

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

Посмотрим еще раз на исходный фрагмент кода:


тз=СоздатьОбъект("ТаблицаЗначений"); 
тз.НоваяКолонка("Сотрудник"); 
тз.НоваяКолонка("ДатаПриема"); 
// ...
Пока сп.ПолучитьЭлемент()=1 Цикл 
    Если Источник.Дт Тогда 
        Продолжить; 
    КонецЕсли; 
    тз.НоваяСтрока(); 
    тз.Сотрудник = сп.ТекущийЭлемент(); 
    тз.ДатаНачала = Источник.Дт; // Ошибка! Такой колонки нет в ТЗ
    // ...
КонецЦикла; 
КоллекцияОбъектов = тз;

Ошибка 1. Отсутствие булева типа в 1С 7.7 и некорректная работа с датами

Строка кода Если Источник.Дт Тогда гарантированно вызовет ошибку времени выполнения в 1С 7.7 по двум причинам:

Для проверки заполнения даты в 1С 7.7 необходимо использовать функцию ПустоеЗначение():


Если ПустоеЗначение(Источник.Дт) = 0 Тогда
    // Дата заполнена, выполняем действия
КонецЕсли;

Ошибка 2. Несоответствие имен колонок Таблицы Значений

При объявлении структуры таблицы значений разработчик создает колонку с именем "ДатаПриема":

тз.НоваяКолонка("ДатаПриема");

Однако ниже по тексту при заполнении строки ТЗ значение присваивается в несуществующую колонку "ДатаНачала":

тз.ДатаНачала = Источник.Дт;

Это неминуемо приведет к падению выгрузки с ошибкой «Поле агрегатного объекта не обнаружено». Имена колонок при объявлении и при обращении должны строго совпадать.

Ошибка 3. Катастрофическое падение производительности (Логическая ошибка)

Посмотрим на обход справочника сотрудников внутри обработчика:


сп = СоздатьОбъект("Справочник.Сотрудники"); 
сп.ВыбратьЭлементы(); 
Пока сп.ПолучитьЭлемент()=1 Цикл 
    // Заполнение ТЗ...
КонецЦикла;

Данный обработчик написан для ПКГС (Правила конвертации группы свойств) табличной части документа. Это означает, что данный код выполняется при выгрузке каждого отдельного документа «Приказ на прием на работу».

Если в вашей базе 1 000 документов приема на работу и 1 000 сотрудников в справочнике, то при выгрузке система выполнит 1 000 000 (один миллион!) итераций цикла, перебирая весь справочник сотрудников для каждого документа. Выгрузка базы просто зависнет.

В документе приема на работу в 1С 7.7 (например, в ЗиК 7.7) обычно фигурирует конкретный сотрудник (или список сотрудников, если это групповой приказ). Нам не нужно выбирать всех сотрудников из базы — нужно получать данные только по тем сотрудникам, которые указаны в самом документе (в объекте Источник).

---

Пишем правильный, оптимизированный код для 1С 7.7

Проанализируем структуру документа-источника. Допустим, мы выгружаем документ приема на работу, где сотрудник указан в шапке документа (реквизиты Сотрудник, Ставка, Оклад, а дата приема хранится в реквизите ДатаПриема или Дт). Нам нужно сформировать строку табличной части для приемника в 1С 8.3.

Рассмотрим правильный, чистый вариант кода для обработчика ПередОбработкойВыгрузкиГруппыСвойств табличной части РаботникиОрганизации:


// Инициализируем Таблицу Значений с правильными именами колонок
тз = СоздатьОбъект("ТаблицаЗначений"); 
тз.НоваяКолонка("Сотрудник"); 
тз.НоваяКолонка("ДатаПриема"); 
тз.НоваяКолонка("ПодразделениеОрганизации"); 
тз.НоваяКолонка("Должность"); 
тз.НоваяКолонка("ЗанимаемыхСтавок"); 
тз.НоваяКолонка("МесячнаяТарифнаяСтавка"); 

// Проверяем, задан ли сотрудник в документе-источнике
Если ПустоеЗначение(Источник.Сотрудник) = 0 Тогда
    
    // Создаем ОДНУ строку в ТЗ для текущего сотрудника из документа
    тз.НоваяСтрока(); 
    тз.Сотрудник = Источник.Сотрудник; 
    
    // Безопасно определяем дату приема
    Если ПустоеЗначение(Источник.Дт) = 0 Тогда
        тз.ДатаПриема = Источник.Дт; 
    Иначе
        тз.ДатаПриема = Источник.ДатаДок; // Альтернативная дата, если Дт пустая
    КонецЕсли;
    
    // Получаем периодические реквизиты сотрудника на дату приема
    спСотр = Источник.Сотрудник;
    тз.ПодразделениеОрганизации = спСотр.Подразделение.Получить(тз.ДатаПриема); 
    тз.Должность = спСотр.Должность; 
    
    Ставка = спСотр.Ставка.Получить(тз.ДатаПриема); 
    тз.ЗанимаемыхСтавок = ?(Ставка = 0, 1, Ставка); 
    
    тз.МесячнаяТарифнаяСтавка = спСотр.Оклад.Получить(тз.ДатаПриема); 
    
КонецЕсли;

// Передаем заполненную таблицу в коллекцию объектов выгрузки
КоллекцияОбъектов = тз;

Проанализируем, почему этот код работает правильно и быстро:

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

← На главную