В разработке на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с ситуацией, когда на форме документа присутствует элемент управления (флажок или «галочка»), который не связан напрямую с данными в базе (не является реквизитом документа). При интерактивной работе пользователь может легко его переключить, но попытка сделать это программно через СоздатьОбъект часто приводит к ошибкам или отсутствию результата. Рассмотрим подробнее, почему это происходит и как решить данную задачу несколькими способами.
Разберем ситуацию, описанную в теме. Когда мы пишем код создания документа:
Док = СоздатьОбъект("Документ.Товары");
Док.Новый();
Док.ДатаДок = ТекущаяДата();
Док.Наименование = "Товар какой-то";
// Попытка установить галку
Док.Новый = 1; // Ошибка!
Док.Записать();
Проблема заключается в разделении контекстов. В 1С 7.7 объект «Документ», созданный через СоздатьОбъект, существует в памяти как набор данных. Форма документа — это визуальное представление, которое создается только в тот момент, когда документ открывается интерактивно (через ОткрытьФорму). Если флажок «Новый» нарисован на форме, но не добавлен в структуру реквизитов документа в конфигураторе, то для объекта Док его просто не существует. Программа выдаст ошибку, так как она не находит такого поля в метаданных.
Проанализируем основные способы решения этой проблемы, от самых правильных до «хитрых» обходных путей.
Самый надежный и правильный способ с точки зрения архитектуры — сделать флажок реальным реквизитом документа. Если вам нужно, чтобы состояние этой галочки влияло на ОбработкаПроведения или сохранялось при закрытии, она должна быть частью данных.
Товары.ФлагНовый) с типом Число (длина 1).Теперь ваш программный код будет работать безупречно:
Док = СоздатьОбъект("Документ.Товары");
Док.Новый();
Док.ФлагНовый = 1; // Теперь это свойство объекта
Док.Записать();
Док.Провести();
Если по каким-то причинам изменять структуру конфигурации (добавлять реквизиты) нельзя, мы можем воспользоваться Глобальным модулем. Это позволяет передать «сигнал» из вашего кода в модуль проведения документа.
Посмотрим, как это реализовать. Сначала в Глобальном модуле объявите переменную:
Перем глУстановитьФлагЭкспорт;
Затем в вашем программном коде перед записью установите её значение:
глУстановитьФлагЭкспорт = 1;
Док = СоздатьОбъект("Документ.Товары");
Док.Новый();
Док.Записать();
Док.Провести();
глУстановитьФлагЭкспорт = 0; // Очищаем после использования
В модуле документа, в процедуре ОбработкаПроведения, вы сможете проверить это значение:
Процедура ОбработкаПроведения()
Если глУстановитьФлагЭкспорт = 1 Тогда
// Выполняем логику, как будто галка стоит
КонецЕсли;
КонецПроцедуры
Если ваша задача — не просто провести документ, а именно открыть форму с уже установленной галочкой, можно использовать передачу параметров. В 1С 7.7 функция ОткрытьФорму позволяет передать контекст или список значений.
Рассмотрим пример. В обработке, которая создает документ, пишем:
Парам = СоздатьОбъект("СписокЗначений");
Парам.Установить("УстановитьГалку", 1);
ОткрытьФорму("Документ.Товары", Парам);
В модуле формы документа, в предопределенной процедуре ПриОткрытии, проанализируем входящий параметр:
Процедура ПриОткрытии()
Если ТипЗначенияСтр(Форма.Параметр) = "СписокЗначений" Тогда
Если Форма.Параметр.Получить("УстановитьГалку") = 1 Тогда
ИмяЭлементаГалка = 1; // Устанавливаем значение атрибута формы
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Существует технический прием для управления формой, когда мы не можем напрямую влиять на её создание. Можно разместить на форме текстовый объект (надпись), который будет невидим, но в поле «Формула» которого будет прописана функция. Эта функция будет срабатывать при каждом обновлении формы.
Например, создадим функцию ОбновитьСостояниеФлага():
Функция ОбновитьСостояниеФлага()
Если Выбран() = 0 Тогда
// Документ еще не записан (новый)
ИмяВашегоФлажка = 1;
КонецЕсли;
Возврат ""; // Чтобы надпись была пустой
КонецФункции
Поместив вызов этой функции в формулу текстового элемента на форме, вы добьетесь того, что при программном (или интерактивном) открытии формы нового документа флажок будет устанавливаться автоматически. Однако помните, что этот метод работает только при открытой форме и бесполезен для фонового проведения документа без участия пользователя.
Выясним важную причину, по которой новички часто ошибаются. Процедура ВводНового(), которая часто содержит логику инициализации значений, срабатывает только при интерактивном создании документа пользователем (нажатие кнопки Ins или «Новый» в журнале). Когда вы вызываете Док.Новый() программно, процедура ВводНового() в модуле формы не вызывается.
Поэтому, если вы хотите, чтобы при программном создании заполнялись те же данные, что и при ручном, вам нужно:
Док.Новый().Подведем итоги нашего анализа. Если вам нужно программно «поставить галку»:
ОткрытьФорму или анализируйте статус документа в ПриОткрытии.СоздатьОбъект невозможно.Используя эти подходы, вы сможете гибко управлять поведением документов в 1С 7.7 как при ручном вводе, так и при автоматической генерации данных.