Как правильно программно создать и провести документ в 1С 7.7

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

При автоматизации учетных задач в 1С:Предприятии 7.7 разработчики часто сталкиваются с ситуацией, когда документ, созданный из внешнего кода или обработки, ведет себя некорректно: в журнале отсутствует наименование операции, в заголовке окна отображается неполное название, а при попытке проведения возникает ошибка вида «Не заполнен реквизит "Валюта документа". Документ не проводится!».

Разберем подробно, почему возникает такое поведение платформы и как правильно организовать программное заполнение и проведение документов.

Причины некорректного создания документа через код

Проанализируем исходный код создания объекта:


Процедура Сформировать()
    Док = СоздатьОбъект("Документ.СписаниеТМЦ");
    фирмы = СоздатьОбъект("Справочник.Фирмы");
    склад = СоздатьОбъект("Справочник.Склады");
    Прод = СоздатьОбъект("Справочник.Номенклатура");
    
    Док.Новый();     
    фирмы.НайтиПоКоду("00003");           
    склад.НайтиПоКоду("00004"); 
    Прод.НайтиПоКоду("41835");
    
    Док.Фирма = фирмы.ТекущийЭлемент();
    Док.Склад = склад.ТекущийЭлемент(); 
    
    Док.НоваяСтрока();
    Док.Номенклатура = Прод.ТекущийЭлемент(); 
    Док.Количество = 10;
    Док.Записать(); 
КонецПроцедуры

Выясним причину возникших сложностей:

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

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

Рассмотрим по шагам, как построить надежный алгоритм программного создания документа списания ТМЦ.

  1. Выполняем поиск элементов справочников с проверкой. Всегда проверяем, вернул ли метод поиска единицу:

Если фирмы.НайтиПоКоду("00003") = 0 Тогда
    Сообщить("Фирма с указанным кодом не найдена!");
    Возврат;
КонецЕсли;
  1. Заполняем вид операции и валюту документа. Явно указываем значения перечислений и валюту учета:

Док.ВидОперации = Перечисление.ВидыОперацийСписаниеТМЦ.СписаниеРозница;
Док.Валюта = Константа.БазоваяВалюта;
Док.Курс = 1;
Док.Кратность = 1;
  1. Используем глобальные процедуры типовых конфигураций (при наличии). В типовых решениях (например, «Торговля и Склад 7.7») можно вызывать стандартные функции заполнения, передавая контекст или заполняя зависимые реквизиты цепочкой:

глЗаполнитьШапку(Док);
Док.Фирма = фирмы.ТекущийЭлемент();
глПриИзмененииФирмы(Док);

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

  1. Управляем временной позицией документа. Чтобы документ корректно списал партии и лег на временную ось после всех существующих документов текущего дня, используем методы позиционирования по времени:

Док.АвтоВремяКонецДня();

  1. Проводим документ с контролем ошибок. Метод Записать() только сохраняет документ в базе. Для выполнения движений по регистрам необходимо вызвать метод Провести():

Если Док.Провести(РежимПроведения.Оперативный) = 0 Тогда
    Сообщить("Не удалось провести документ! Проверьте остатки на складе.");
КонецЕсли;

Итоговый пример корректного кода

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


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

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

← На главную