При работе с системой 1С:Бухгалтерия 3.0, особенно при автоматизации рутинных операций, часто возникает необходимость программного заполнения табличных частей документов. Правильное программное создание документов в 1С 8.3 позволяет значительно ускорить ввод данных, избежать ошибок и интегрировать различные подсистемы. Для решения подобных задач часто используется инструмент для гибкой настройки автоматического заполнения реквизитов и табличных частей, который позволяет автоматизировать процесс без написания сложного кода. В этой статье мы подробно разберем, как можно реализовать заполнение табличных частей документов в управляемых формах, используя как стандартные механизмы Библиотеки стандартных подсистем (БСП), так и прямые запросы к данным.
Мы рассмотрим несколько подходов к решению этой задачи, выясним особенности каждого из них и предоставим примеры кода, чтобы вы могли применить эти знания на практике. Наша цель — помочь вам эффективно управлять данными в 1С:Бухгалтерии 3.0, сделав процесс заполнения документов максимально автоматизированным.
Прежде чем приступить к программному заполнению, важно четко определить, какие данные и из каких источников необходимо перенести в табличную часть документа. Типичные сценарии включают:
В нашем случае, мы сосредоточимся на программном заполнении табличной части, когда необходимо получить данные из базы и поместить их в строки табличной части документа.
Платформа 1С:Предприятие 8.3 и конфигурации, разработанные с применением БСП, предоставляют разработчику использование Библиотеки стандартных подсистем (БСП) для автоматизации заполнения документов. Это предпочтительный подход, так как он обеспечивает типовую логику и переиспользуемость кода. Для расширения возможностей системы часто применяется универсальный механизм добавления табличных частей с помощью расширения на основе БСП, который позволяет модифицировать формы без изменения основной конфигурации.
Для начала, мы создадим структуру параметров, которая будет передаваться в функцию заполнения. Эта структура будет содержать исходные данные, на основании которых должен быть заполнен документ. Например, это может быть ссылка на документ-основание или набор критериев отбора.
Рассмотрим пример, когда мы хотим заполнить табличную часть документа "РеализацияТоваровУслуг" на основании неких исходных данных. Предположим, у нас есть коллекция объектов, которые мы хотим перенести в табличную часть.
Давайте создадим новый документ и затем вызовем процедуру заполнения. Для этого нам понадобится форма документа, ее объект и соответствующая команда.
Вот пример кода, который демонстрирует создание нового документа, открытие его формы и вызов метода заполнения, используя стандартные механизмы:
&НаКлиенте
Процедура ЗаполнитьТЧ(Команда)
// Создадим новый документ
НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = ПолучитьОрганизациюПоУмолчанию(); // Ваша логика получения организации
НовыйДокумент.Контрагент = ПолучитьКонтрагентаПоУмолчанию(); // Ваша логика получения контрагента
// Откроем форму нового документа
ПараметрыФормы = Новый Структура("Ключ", НовыйДокумент.Ссылка);
ОткрытаяФорма = ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаДокумента", ПараметрыФормы);
Если ОткрытаяФорма <> Неопределено Тогда
// Теперь вызовем метод Заполнить
// Это может быть общая команда формы или специализированная процедура
// Например, если есть команда "Заполнить" в форме
ОткрытаяФорма.ВыполнитьКоманду("Заполнить"); // Вызов команды формы
// Или если есть экспортная процедура в модуле объекта или формы
// ОткрытаяФорма.ЗаполнитьТабличнуюЧастьПоДанным(...);
КонецЕсли;
КонецПроцедуры
// Пример вспомогательной функции для получения организации по умолчанию
&НаСервере
Функция ПолучитьОрганизациюПоУмолчанию()
Возврат УправлениеПользователями.ПолучитьЗначениеПоУмолчанию("ОсновнаяОрганизация");
КонецФункции
// Пример вспомогательной функции для получения контрагента по умолчанию
&НаСервере
Функция ПолучитьКонтрагентаПоУмолчанию()
Возврат Справочники.Контрагенты.НайтиПоКоду("000000001"); // Пример: первый контрагент
КонецФункции
В этом примере ОткрытаяФорма.ВыполнитьКоманду("Заполнить") предполагает, что в форме документа есть команда с именем "Заполнить", которая выполняет типовое заполнение. Обычно это команда "Заполнить" -> "Добавить из подбора" или "Заполнить" -> "Подобрать товары".
БСП предоставляет регистр сведений РегистрыСведений.ПараметрыЗаполненияДокументов. Этот регистр позволяет хранить настройки для автоматического заполнения документов. Также существует универсальное заполнение документа по любому документу-основанию для конфигураций на БСП (удобно через универсальное заполнение по документу-основанию для БСП), которое значительно упрощает этот процесс. Мы можем программно записать туда необходимые параметры, а затем вызвать стандартное заполнение, которое их учтет.
Как правило, для использования этого механизма, необходимо выполнить следующие действия:
ПараметрыЗаполненияДокументов.Предположим, у нас есть документ-основание (например, "Поступление (акты, накладные)"), и мы хотим на его основе заполнить новый документ "Перемещение товаров".
&НаСервереБезКонтекста
Процедура ЗаполнитьПеремещениеНаОсновании(СсылкаДокументаОснования)
НовыйДокументОбъект = Документы.ПеремещениеТоваров.СоздатьДокумент();
НовыйДокументОбъект.Дата = ТекущаяДата();
НовыйДокументОбъект.Организация = СсылкаДокументаОснования.Организация;
НовыйДокументОбъект.СкладОтправитель = СсылкаДокументаОснования.Склад;
НовыйДокументОбъект.СкладПолучатель = ПолучитьСкладПриемникПоУмолчанию(); // Ваша логика
// Формируем параметры заполнения
ПараметрыЗаполнения = Новый Структура();
ПараметрыЗаполнения.Вставить("ДокументОснование", СсылкаДокументаОснования);
ПараметрыЗаполнения.Вставить("ЗаполнятьТолькоТовары", Истина); // Дополнительные параметры
// Записываем параметры в регистр сведений
УникальныйИдентификаторПараметров = РегистрыСведений.ПараметрыЗаполненияДокументов.ЗаписатьПараметры(ПараметрыЗаполнения);
// Передаем уникальный идентификатор в параметры формы для открытия
ПараметрыФормы = Новый Структура();
ПараметрыФормы.Вставить("Ключ", НовыйДокументОбъект.Ссылка);
ПараметрыФормы.Вставить("ПараметрыЗаполнения", УникальныйИдентификаторПараметров);
// Открываем форму документа.
// При открытии формы, если она поддерживает механизм БСП,
// она автоматически прочитает параметры заполнения по УИД и заполнит себя.
ОткрытьФорму("Документ.ПеремещениеТоваров.ФормаДокумента", ПараметрыФормы);
КонецПроцедуры
&НаСервере
Функция ПолучитьСкладПриемникПоУмолчанию()
// Пример получения склада приемника
Возврат Справочники.Склады.НайтиПоКоду("00002");
КонецФункции
Важный момент: Чтобы этот механизм сработал, форма документа должна быть адаптирована для работы с ПараметрамиЗаполненияДокументов. Обычно это делается в модуле формы при открытии. Например, в обработчике события ПриСозданииНаСервере или ПриОткрытии может быть такой код:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ПараметрыЗаполнения") Тогда
// Прочитать параметры из регистра по УИД
ПараметрыЗаполнения = РегистрыСведений.ПараметрыЗаполненияДокументов.ПрочитатьПараметры(Параметры.ПараметрыЗаполнения);
Если ПараметрыЗаполнения <> Неопределено Тогда
// Вызвать процедуру заполнения документа на основании полученных параметров
// Например, вызвать типовой метод Заполнить() из БСП
Документы.УправлениеЗапасами.ЗаполнитьТабличнуюЧастьНаОсновании(ЭтотОбъект, ПараметрыЗаполнения);
// Если документ еще не записан, можно установить его в режим ЗаписьДокумента.Разрешена
// и записать после заполнения.
// Удалить использованные параметры, чтобы не засорять регистр
РегистрыСведений.ПараметрыЗаполненияДокументов.УдалитьПараметры(Параметры.ПараметрыЗаполнения);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Мы должны убедиться, что используемая конфигурация и конкретный документ поддерживают такую логику, часто реализованную в общих модулях, таких как УправлениеЗапасамиКлиентСервер или ЗаполнениеДокументов.
В некоторых случаях, когда стандартные механизмы не подходят или требуется специфическая логика заполнения, мы можем напрямую работать с табличными частями документа. Для упрощения переноса данных между объектами можно использовать копирование и вставку данных объектов по шаблону, что минимизирует ручной ввод. Прямое заполнение требует более глубокого понимания структуры данных и работы с запросами.
Наиболее эффективный способ получить данные из базы 1С — это использование запросов. Запрос позволяет выбрать необходимые поля из различных таблиц (справочников, регистров, документов) и объединить их. Это особенно полезно, когда нужно заполнить множество реквизитов табличной части из разных источников.
Представим, что мы хотим заполнить табличную часть "Товары" документа "РеализацияТоваровУслуг" данными о номенклатуре и ее ценах из регистра сведений "ЦеныНоменклатуры".
&НаСервере
Процедура ЗаполнитьТабличнуюЧастьТовары(ОбъектДокумента)
// Очищаем существующую табличную часть, если необходимо
ОбъектДокумента.Товары.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Номенклатура,
| Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| ЦеныНоменклатурыСрезПоследних.Цена КАК Цена
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, ТипЦен = &ТипЦен) КАК ЦеныНоменклатурыСрезПоследних
| ПО Номенклатура.Ссылка = ЦеныНоменклатурыСрезПоследних.Номенклатура
|ГДЕ
| Номенклатура.ПометкаУдаления = ЛОЖЬ
| И Номенклатура.ЭтоГруппа = ЛОЖЬ";
Запрос.УстановитьПараметр("Дата", ОбъектДокумента.Дата);
// Для примера, возьмем базовый тип цен
Запрос.УстановитьПараметр("ТипЦен", Справочники.ТипыЦенНоменклатуры.НайтиПоНаименованию("Закупочная"));
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
НоваяСтрока = ОбъектДокумента.Товары.Добавить();
НоваяСтрока.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
НоваяСтрока.ЕдиницаИзмерения = ВыборкаДетальныеЗаписи.ЕдиницаИзмерения;
НоваяСтрока.Количество = 1; // Устанавливаем количество по умолчанию
НоваяСтрока.Цена = ВыборкаДетальныеЗаписи.Цена;
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
// Здесь можно заполнить и другие реквизиты, например, СтавкаНДС, СуммаНДС и т.д.
КонецЦикла;
// После заполнения, возможно, потребуется пересчет итогов или применение скидок
Документы.РеализацияТоваровУслуг.РассчитатьСуммыДокумента(ОбъектДокумента);
КонецПроцедуры
В этом примере мы получаем список номенклатуры и ее цены, а затем для каждой позиции создаем новую строку в табличной части "Товары". Документы.РеализацияТоваровУслуг.РассчитатьСуммыДокумента(ОбъектДокумента) — это типовой метод общего модуля документа, который пересчитывает суммы и налоги после изменения табличной части.
Для более сложных сценариев, когда данные нужно обрабатывать в несколько этапов или когда источники данных сильно различаются, эффективная работа с запросами и временными таблицами в 1С становится необходимостью. Это позволяет значительно оптимизировать выполнение операций и упростить их структуру.
Предположим, нам нужно получить данные о товарах из нескольких источников (например, из документа-основания и из остатков на складах), а затем объединить их в одной временной таблице для дальнейшей обработки.
&НаСервере
Процедура ЗаполнитьТабличнуюЧастьСложнымЗапросом(ОбъектДокумента, ДокументОснование)
// Очищаем существующую табличную часть
ОбъектДокумента.Товары.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыОснования.Номенклатура КАК Номенклатура,
| ТоварыОснования.Количество КАК КоличествоИзОснования,
| ТоварыОснования.Цена КАК ЦенаИзОснования,
| ТоварыОснования.Сумма КАК СуммаИзОснования
|ПОМЕСТИТЬ ВТ_ДанныеОснования
|ИЗ
| Документ.ПоступлениеТоваровУслуг.Товары КАК ТоварыОснования
|ГДЕ
| ТоварыОснования.Ссылка = &ДокументОснование
|;
|
|ВЫБРАТЬ
| ВТ_ДанныеОснования.Номенклатура,
| ВТ_ДанныеОснования.КоличествоИзОснования,
| ВТ_ДанныеОснования.ЦенаИзОснования,
| ВТ_ДанныеОснования.СуммаИзОснования,
| ЕдиницыИзмерения.Ссылка КАК ЕдиницаИзмерения
|ИЗ
| ВТ_ДанныеОснования КАК ВТ_ДанныеОснования
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО ВТ_ДанныеОснования.Номенклатура = Номенклатура.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ЕдиницыИзмерения КАК ЕдиницыИзмерения
| ПО Номенклатура.ЕдиницаХранения = ЕдиницыИзмерения.Ссылка
|ГДЕ
| Номенклатура.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("ДокументОснование", ДокументОснование.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
НоваяСтрока = ОбъектДокумента.Товары.Добавить();
НоваяСтрока.Номенклатура = ВыборкаДетальныеЗаписи.Номенклатура;
НоваяСтрока.Количество = ВыборкаДетальныеЗаписи.КоличествоИзОснования;
НоваяСтрока.Цена = ВыборкаДетальныеЗаписи.ЦенаИзОснования;
НоваяСтрока.Сумма = ВыборкаДетальныеЗаписи.СуммаИзОснования;
НоваяСтрока.ЕдиницаИзмерения = ВыборкаДетальныеЗаписи.ЕдиницаИзмерения;
// ... другие реквизиты
КонецЦикла;
Документы.РеализацияТоваровУслуг.РассчитатьСуммыДокумента(ОбъектДокумента);
КонецПроцедуры
Здесь мы сначала помещаем данные из документа-основания во временную таблицу ВТ_ДанныеОснования, а затем объединяем эти данные с информацией из справочника "ЕдиницыИзмерения", чтобы получить нужные реквизиты для табличной части.
Многие документы в 1С имеют стандартные механизмы подбора номенклатуры в типовых конфигурациях, которые можно вызвать программно. Это часто является частью общего модуля ДополнительныеПроцедурыИФункцииКлиентСервер или УправлениеЗапасамиКлиентСервер. Использование этих механизмов упрощает разработку, так как они уже содержат всю необходимую логику для сбора данных и их корректного размещения в табличной части.
Для того чтобы использовать механизмы подбора, мы обычно должны:
В типовых конфигурациях 1С:Бухгалтерия 3.0 команды подбора часто имеют префикс "Заполнить" и находятся в командной панели табличной части или в меню "Заполнить" документа.
Предположим, мы хотим программно вызвать подбор товаров в документе "Реализация товаров и услуг". Для этого нам потребуется открыть форму документа и выполнить соответствующую команду:
&НаКлиенте
Процедура ВызватьПодборНоменклатуры(Команда)
// Создаем или получаем объект документа, который будем заполнять
ОбъектДокумента = РеквизитФормыВЗначение("Объект"); // Если вызываем из формы существующего документа
// Если нужно создать новый документ:
// ОбъектДокумента = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// ... заполнить основные реквизиты ...
// ОбъектДокумента.Записать(); // Записать, если это новый документ
// Получаем ссылку на текущий документ
СсылкаНаДокумент = ОбъектДокумента.Ссылка;
// Параметры для открытия формы документа.
// Если документ уже открыт, можно использовать существующую форму.
// Если нет, то открываем новую форму.
Если СсылкаНаДокумент.Пустая() Тогда
ПоказатьПредупреждение(,"Документ не записан. Для подбора запишите документ.");
Возврат;
КонецЕсли;
// Открываем форму документа (если она еще не открыта) и вызываем команду подбора.
// В большинстве случаев форма уже будет открыта, если процедура вызывается из нее.
// Если вызывается из внешней обработки или другой формы, то потребуется открыть форму.
// Найдем форму текущего документа
ФормаДокумента = ПолучитьФорму(); // Если вызываем из модуля формы
// Или
// ФормаДокумента = ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаДокумента", Новый Структура("Ключ", СсылкаНаДокумент));
Если ФормаДокумента <> Неопределено Тогда
// Вызываем команду формы, которая отвечает за подбор
// Название команды может отличаться, например, "ЗаполнитьПодбор", "КомандаПодборНоменклатуры"
// Необходимо уточнить имя команды в конфигураторе для конкретной формы.
// Примерная команда:
Если ФормаДокумента.Команды.Найти("ЗаполнитьПодбор") <> Неопределено Тогда
ФормаДокумента.ВыполнитьКоманду("ЗаполнитьПодбор");
Иначе
ПоказатьПредупреждение(,"Команда подбора 'ЗаполнитьПодбор' не найдена в форме документа. Проверьте конфигурацию.");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Для определения точного имени команды подбора, вам потребуется открыть форму документа в конфигураторе, найти элемент "Табличная часть" и посмотреть, какие команды с ним связаны, или исследовать меню "Заполнить". Обычно это команды, которые вызывают обработку "Подбор товаров" или схожие механизмы.
При работе в управляемых формах следует учитывать следующие моменты:
&НаСервере и &НаКлиенте для указания контекста выполнения.Объект = РеквизитФормыВЗначение("Объект"), а затем ЗначениеВРеквизитФормы(Объект, "Объект") после изменения. Это позволяет правильно синхронизировать данные между клиентом и сервером.ЗначениеВРеквизитФормы.Документы.РеализацияТоваровУслуг.РассчитатьСуммыДокумента().Мы рассмотрели несколько подходов к программному заполнению табличных частей документов в 1С:Бухгалтерии 3.0. Выбор конкретного метода зависит от сложности задачи, требований к производительности и необходимости использования типовой логики:
РегистрыСведений.ПараметрыЗаполненияДокументов или универсальную обработку для заполнения по любому документу-основанию. Это наиболее предпочтительный и поддерживаемый подход.Всегда стремитесь к тому, чтобы ваш код был читаемым, поддерживаемым и максимально использовал существующие механизмы платформы и конфигурации. Это позволит избежать проблем при сопровождении и обновлении системы. Для упрощения работы с реквизитами и ТЧ рекомендуем обратить внимание на инструмент для автоматического заполнения реквизитов объекта.
Надеемся, что это подробное руководство поможет вам эффективно решать задачи по автоматическому заполнению документов в 1С:Бухгалтерии 3.0.