К статье
Практический материал

Разработка и Конфигурация · 12 мин

1С: как программно заполнить объекты и табличные части

Как программно заполнить в 1С документ, справочник и табличную часть: методы записи, обработка заполнения, типовые ошибки и примеры кода на встроенном языке.

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

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

Ошибка выбора механизма — самая частая причина проблем: код «вроде работает», но документ не проводится, обработчики событий не вызываются, а пользователи видят пустые поля. Ниже разобраны рабочие сценарии с примерами кода и способами проверки результата.

Какие сценарии программного заполнения существуют в 1С

Прежде чем писать код, определите, в каком контексте выполняется заполнение. От этого зависят доступные объекты и методы.

  • Создание и заполнение объекта на сервере — загрузка данных, обмены, регламентные задания, обработки. Работа идёт с объектом в памяти через менеджер типа.
  • Заполнение при интерактивном вводе — пользователь создаёт документ «на основании» или по кнопке. Используется событие ОбработкаЗаполнения.
  • Заполнение открытой формы — код на клиенте меняет данные формы, видимые пользователю прямо сейчас.
  • Заполнение табличной части обработкой — типовой механизм «Заполнить» в документах, реализуется через экспортную процедуру в модуле объекта или формы.

Заполнение документа через СоздатьДокумент()

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

НовыйДок = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

НовыйДок.Дата = ТекущаяДатаСеанса();

НовыйДок.Организация = Организация;

НовыйДок.Контрагент = Контрагент;

НовыйДок.ДоговорКонтрагента = Договор;

НоваяСтрока = НовыйДок.Товары.Добавить();

НоваяСтрока.Номенклатура = Номенклатура;

НоваяСтрока.Количество = 2;

НоваяСтрока.Цена = 1500;

НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;

НовыйДок.Записать(РежимЗаписиДокумента.Запись);

Обратите внимание: Записать() с режимом «Запись» сохраняет документ без проведения. Для проведения используйте РежимЗаписиДокумента.Проведение, но учтите, что проведение может завершиться ошибкой из-за контроля остатков или незаполненных обязательных реквизитов — обрабатывайте её через Попытка/Исключение.

Номер документа при записи платформа присвоит автоматически, если не задавать его вручную. Дату лучше устанавливать явно: по умолчанию новый документ получает текущую дату сеанса, что при загрузке исторических данных приведёт к неверному учёту.

Заполнение справочника через СоздатьЭлемент()

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

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Кабель ВВГ 3х2.5";

НовыйЭлемент.Родитель = ГруппаКабели;

НовыйЭлемент.ЕдиницаИзмерения = ЕдиницаМетр;

НовыйЭлемент.Записать();

Если справочник подчинённый (например, договоры контрагентов), обязательно установите свойство Владелец до записи — иначе получите ошибку. Для иерархических справочников группу создают через СоздатьГруппу(), а не СоздатьЭлемент().

При загрузке данных извне проверяйте дубли: ищите существующий элемент через НайтиПоНаименованию() или НайтиПоРеквизиту() и обновляйте его вместо создания нового. Иначе повторный запуск обработки задвоит справочник.

Заполнение табличной части: типовые приёмы

Табличная часть — это коллекция строк. Основные операции: Добавить() создаёт новую строку, Очистить() удаляет все строки, Найти(Значение, "Колонка") ищет строку по значению, Итог("Колонка") считает сумму по колонке.

Типовой приём — заполнение табличной части из результата запроса:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Номенклатура, КоличествоОстаток

|ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад)";

Запрос.УстановитьПараметр("Дата", Дата);

Запрос.УстановитьПараметр("Склад", Склад);

Объект.Товары.Очистить();

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Строка = Объект.Товары.Добавить();

Строка.Номенклатура = Выборка.Номенклатура;

Строка.Количество = Выборка.КоличествоОстаток;

КонецЦикла;

Для массовой загрузки из таблицы значений удобен метод Загрузить(): Объект.Товары.Загрузить(ТаблицаЗначений) — он заменяет содержимое табличной части, сопоставляя колонки по именам. Колонки таблицы значений должны называться так же, как реквизиты табличной части.

Обработка заполнения при вводе на основании

Когда пользователь создаёт документ «на основании», платформа вызывает процедуру ОбработкаЗаполнения в модуле объекта нового документа. Параметр ДанныеЗаполнения содержит объект-основание:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказКлиента") Тогда

Контрагент = ДанныеЗаполнения.Контрагент;

ДоговорКонтрагента = ДанныеЗаполнения.ДоговорКонтрагента;

Для Каждого СтрокаЗаказа Из ДанныеЗаполнения.Товары Цикл

НоваяСтрока = Товары.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаЗаказа);

КонецЦикла;

КонецЕсли;

КонецПроцедуры;

Функция ЗаполнитьЗначенияСвойств() копирует значения одноимённых свойств из источника в приёмник — это резко сокращает код при совпадающих структурах. Но она копирует всё подряд, поэтому при разных типах колонок (например, в основании «Количество» — число, а в приёмнике ожидается другой состав) заполняйте поля явно.

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

Порядок действий при добавлении заполнения на основании
  1. 1
    Определите тип объекта-основания и сопоставьте его реквизиты с реквизитами нового документа
  2. 2
    Добавьте процедуру ОбработкаЗаполнения в модуль объекта с проверкой ТипЗнч(ДанныеЗаполнения)
  3. 3
    Заполните шапку и табличные части, используя ЗаполнитьЗначенияСвойств там, где имена совпадают
  4. 4
    Проверьте создание документа из интерфейса: команда «Создать на основании» должна открыть заполненную форму
  5. 5
    Убедитесь, что документ проводится без ошибок и движения корректны

Заполнение данных в открытой форме

Если нужно изменить значения в уже открытой форме (например, из внешней обработки, подключённой к форме), работайте с реквизитом формы Объект:

// В модуле формы документа

&НаКлиенте

Процедура ЗаполнитьЦены(Команда)

ЗаполнитьЦеныНаСервере();

КонецПроцедуры

&НаСервере

Процедура ЗаполнитьЦеныНаСервере()

Для Каждого Строка Из Объект.Товары Цикл

Строка.Цена = ПолучитьЦену(Строка.Номенклатура, Объект.Дата);

Строка.Сумма = Строка.Количество * Строка.Цена;

КонецЦикла;

КонецПроцедуры

Здесь ключевой момент: изменения через Объект в форме видны пользователю, но не сохранены в базе, пока он не нажмёт «Записать». Это безопасный режим — пользователь может отменить изменения. При программной записи через объект (без формы) изменения фиксируются сразу.

Не пытайтесь менять данные формы с сервера «напрямую по ссылке», ожидая, что открытая у пользователя форма обновится сама. Для оповещения форм об изменениях используйте Оповестить() и обработчик ОбработкаОповещения в форме.

Маршрут решения

Как выбрать механизм заполнения

Данные загружаются пакетно из файла или другой системыСоздавайте объекты через менеджер (СоздатьДокумент/СоздатьЭлемент) и записывайте в транзакции
Пользователь создаёт документ кнопкой «на основании»Используйте ОбработкаЗаполнения в модуле объекта
Нужно пересчитать или дополнить данные в открытой формеДобавьте команду формы и меняйте реквизит Объект на сервере
Заполнение должно срабатывать при записи независимо от источникаИспользуйте события ПередЗаписью или ПриЗаписи в модуле объекта

Проверка результата и типичные ошибки

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

Контрольные точки

Как проверить результат

Ссылка после Записать()
Норма

Свойство Ссылка заполнено, Пустая() возвращает Ложь

Тревожный признак

Ссылка пустая — запись не выполнилась, ищите исключение

Табличная часть в базе
Норма

Запрос к табличной части возвращает добавленные строки

Тревожный признак

Строки видны в коде, но не в базе — забыли Записать() или откатилась транзакция

Проведение документа
Норма

Документ проводится, движения по регистрам соответствуют ожиданиям

Тревожный признак

Ошибка контроля остатков или незаполненные обязательные реквизиты

Обработчики событий
Норма

При интерактивном изменении полей срабатывают пересчёты

Тревожный признак

Программное заполнение «мимо» обработчиков — суммы и налоги не пересчитаны

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

Типичные ошибки
01
Забыли вызвать Записать() — объект остался только в памяти и потерялся после завершения кода
02
Заполнили табличную часть, но не пересчитали итоговые реквизиты шапки — сумма документа не сходится со строками
03
Использовали ОбменДанными.Загрузка = Истина без необходимости — пропущены проверки, в базе некорректные данные
04
Ожидали срабатывания обработчиков ПриИзменении при программном присвоении — они не вызываются, пересчёт нужно делать явно
05
Создали дубли справочника при повторном запуске обработки — не выполнен поиск существующего элемента
При массовом создании документов оборачивайте запись каждого объекта в отдельную транзакцию или хотя бы в Попытка/Исключение с записью ошибки в журнал. Так один «битый» документ не остановит всю загрузку, а вы получите список проблемных строк для разбора.
ПЗ
Практическое замечание

Часто задаваемые вопросы

Как программно заполнить реквизит типа «ТаблицаЗначений» в документе?

Реквизиты документа не могут иметь тип «ТаблицаЗначений» — для хранения списков строк используются табличные части. Создайте табличную часть в метаданных и заполняйте её методами Добавить() или Загрузить().

Почему программно созданный документ не виден в журнале?

Чаще всего запись не выполнилась из-за необработанного исключения, или документ записан с датой вне текущего периода журнала, или у журнала настроен отбор. Проверьте ссылку после Записать() и снимите отборы в журнале.

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

Вызовите Записать(РежимЗаписиДокумента.Проведение). Учтите, что проведение выполняет контроль (остатки, обязательные реквизиты), поэтому оберните вызов в Попытка/Исключение и при ошибке записывайте текст исключения для анализа.

Чем ЗаполнитьЗначенияСвойств отличается от ручного присвоения?

Функция копирует все одноимённые свойства источника в приёмник одной строкой кода. Это удобно, но опасно при расхождении типов: лишние или несовместимые свойства могут вызвать ошибку или подставить неожиданные значения. Для критичных полей присваивайте значения явно.

Как заполнить табличную часть из файла Excel или CSV?

Прочитайте файл в таблицу значений (через ТабличныйДокумент для Excel или построчный разбор для CSV), приведите типы колонок к типам реквизитов табличной части и вызовите Объект.Товары.Загрузить(ТаблицаЗначений). После загрузки пересчитайте зависимые поля, если они рассчитываются в обработчиках.

Нужно ли вызывать УстановитьНовыйНомер() при создании документа?

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

Итог

Что важно запомнить

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