Как программно создать и заполнить документ "Реализация товаров и услуг" в 1С:УТ 11.5 (Управляемые формы)?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При работе с 1С часто возникает необходимость автоматизировать рутинные операции, такие как создание документов по данным из внешних источников. Одной из таких задач является программное формирование документа "Реализация товаров и услуг" с заполнением его табличной части — есть автоматизация создания реализаций из прайс-листов Excel. Давайте подробно рассмотрим, как мы можем реализовать этот процесс в конфигурации "1С:Управление торговлей" версии 11.5 на управляемых формах.

Мы выясним, какие объекты 1С необходимо использовать, как правильно инициализировать документ, заполнить его основные реквизиты, а затем перейти к самому важному — наполнению табличной части "Товары". Также мы разберем важные нюансы, такие как поиск справочных данных, установка цен, работа с договорами и обработка исключений.

Шаг 1: Создание нового экземпляра документа "Реализация товаров и услуг"

Первым делом нам необходимо получить ссылку на менеджер документа "Реализация товаров и услуг" и создать новый экземпляр этого документа. Для этого мы будем использовать объект Документы.

  1. Мы обращаемся к менеджеру документа через Документы.РеализацияТоваровУслуг.
  2. Затем вызываем метод СоздатьДокумент(), который возвращает новый, еще не записанный в базу данных объект документа.
  3. Крайне полезным, особенно в типовых конфигурациях вроде УТ, будет вызов метода ЗаполнитьПоУмолчанию(). Этот метод автоматически подставит значения во многие поля документа (например, организацию, склад, тип цен, вид операции) исходя из настроек пользователя, данных контрагента или стандартных настроек системы. Это значительно сократит объем кода и уменьшит вероятность ошибок.

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

// Заполняем документ значениями по умолчанию из настроек системы/пользователя
НовыйДокумент.ЗаполнитьПоУмолчанию(); 

// Устанавливаем дату документа (часто это текущая дата)
НовыйДокумент.Дата = ТекущаяДата(); 

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

Шаг 2: Заполнение основных реквизитов шапки документа

Каждый документ в 1С имеет набор реквизитов, которые формируют его "шапку" – основные данные, относящиеся ко всему документу. Для "Реализации товаров и услуг" это, как правило, организация, контрагент, склад, договор, вид цены и другие. Мы рассмотрим, как программно получить ссылки на необходимые справочные данные и установить их.

  1. Организация: Мы должны указать, от имени какой организации происходит реализация. Мы можем найти организацию по наименованию или коду.
    
    // Поиск организации по наименованию
    НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("Наша Организация"); 
    // Или по коду: Справочники.Организации.НайтиПоКоду("000000001");
    
  2. Контрагент: Это наш покупатель. Поиск аналогичен поиску организации.
    
    // Поиск контрагента по наименованию
    НовыйДокумент.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("Покупатель");
    
  3. Склад: Указываем склад, с которого будут отгружаться товары.
    
    // Поиск склада по наименованию
    НовыйДокумент.Склад = Справочники.Склады.НайтиПоНаименованию("Основной Склад");
    
  4. Договор: Если в системе ведется учет по договорам, его указание является обязательным. Договор обычно связан с контрагентом и организацией. Если у нас несколько договоров с одним контрагентом, нам может потребоваться более сложный запрос.
    
    // Проверяем, что контрагент и организация найдены, прежде чем искать договор
    Если НЕ НовыйДокумент.Контрагент.Пустая() И НЕ НовыйДокумент.Организация.Пустая() Тогда
        ЗапросДоговора = Новый Запрос;
        ЗапросДоговора.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 Ссылка ИЗ Справочник.ДоговорыКонтрагентов ГДЕ Владелец = &Контрагент И Организация = &Организация И ПометкаУдаления = ЛОЖЬ УПОРЯДОЧИТЬ ПО ДатаСоздания УБЫВ";
        ЗапросДоговора.УстановитьПараметр("Контрагент", НовыйДокумент.Контрагент);
        ЗапросДоговора.УстановитьПараметр("Организация", НовыйДокумент.Организация);
        ВыборкаДоговора = ЗапросДоговора.Выполнить().Выбрать();
        Если ВыборкаДоговора.Следующий() Тогда
            НовыйДокумент.Договор = ВыборкаДоговора.Ссылка;
        Иначе
            Сообщить("Внимание: Не удалось найти активный договор для контрагента " + НовыйДокумент.Контрагент + " и организации " + НовыйДокумент.Организация + ". Документ может быть проведен некорректно.");
        КонецЕсли;
    Иначе
        Сообщить("Внимание: Контрагент или организация не определены. Поиск договора невозможен.");
    КонецЕсли;
    
  5. Вид цены: Вид цены важен для автоматического подтягивания цен. В УТ 11.5 вид цены часто определяется автоматически на основе соглашений или настроек. Однако, мы можем установить его явно, если это требуется. Более того, цены должны быть получены с учетом этого вида цены.
    
    // Устанавливаем вид цены. Он может быть установлен по умолчанию методом ЗаполнитьПоУмолчанию.
    // Если требуется переопределить:
    НовыйДокумент.ВидЦены = Справочники.ВидыЦен.НайтиПоНаименованию("Оптовая"); 
    
  6. Комментарий: Необязательный, но полезный реквизит для указания источника или цели создания документа — поможет загрузка данных из Excel в реализацию товаров и услуг.
    
    НовыйДокумент.Комментарий = "Документ создан программно по данным из внешнего файла Excel.";
    

Важный совет: Всегда проверяйте, что результаты поиска по справочникам не Неопределено. Если ссылка не найдена, это может привести к ошибкам при записи документа. Мы можем добавить проверки после каждого НайтиПоНаименованию() или НайтиПоКоду().

Шаг 3: Заполнение табличной части "Товары"

Табличная часть "Товары" является ключевой для документа реализации. Мы рассмотрим, как добавлять строки и заполнять их данными о номенклатуре, количестве, цене и сумме.

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

  1. Создать новую строку: Мы обращаемся к коллекции табличной части НовыйДокумент.Товары и используем метод Добавить().
  2. Найти номенклатуру: Так же, как и с другими справочниками, мы ищем нужный элемент номенклатуры.
    • По коду или артикулу: это часто более надежный способ, если эти поля уникальны.
    • По наименованию: если наименования уникальны, но это может быть менее надежно из-за возможных расхождений в написании. В таких случаях часто помогает предварительная загрузка номенклатуры из Excel.
    • С помощью запроса: для более сложных условий поиска (например, по наименованию и группе номенклатуры).
  3. Заполнить реквизиты строки: После получения ссылки на номенклатуру, мы заполняем количество, цену, рассчитываем сумму и устанавливаем другие обязательные или важные реквизиты, такие как единица измерения, ставка НДС, сумма НДС.
  4. Учет характеристик и серий: Если в вашей конфигурации используются характеристики и/или серии номенклатуры, их также необходимо будет указать для каждой строки табличной части.

// Пример получения данных из некоего источника (например, ТаблицаЗначений)
// Допустим, у нас есть ТаблицаДанныхИзИсточника с колонками "КодНоменклатуры", "Количество", "Цена"

// Обходим строки полученных данных
Для Каждого СтрокаДанных Из ТаблицаДанныхИзИсточника Цикл

    // Ищем номенклатуру по коду. Важно: всегда проверяем, что номенклатура найдена.
    СсылкаНаНоменклатуру = Справочники.Номенклатура.НайтиПоКоду(СтрокаДанных.КодНоменклатуры);

    Если СсылкаНаНоменклатуру.Пустая() Тогда
        Сообщить("Предупреждение: Номенклатура с кодом " + СтрокаДанных.КодНоменклатуры + " не найдена. Строка будет пропущена.", СтатусСообщения.Важное);
        Продолжить; // Переходим к следующей строке данных
    КонецЕсли;

    // Если номенклатура использует характеристики
    СсылкаНаХарактеристику = Неопределено;
    Если СсылкаНаНоменклатуру.ИспользоватьХарактеристики Тогда
        // Пример поиска характеристики (например, по наименованию)
        СсылкаНаХарактеристику = Справочники.ХарактеристикиНоменклатуры.НайтиПоНаименованию("Красный"); // Допустим, берем из данных
        Если СсылкаНаХарактеристику.Пустая() Тогда
            Сообщить("Предупреждение: Характеристика для номенклатуры " + СсылкаНаНоменклатуру + " не найдена. Возможны ошибки.", СтатусСообщения.Важное);
        КонецЕсли;
    КонецЕсли;

    // Добавляем новую строку в табличную часть "Товары"
    СтрокаТабличнойЧасти = НовыйДокумент.Товары.Добавить();
    СтрокаТабличнойЧасти.Номенклатура = СсылкаНаНоменклатуру;
    СтрокаТабличнойЧасти.Количество = СтрокаДанных.Количество;
    СтрокаТабличнойЧасти.Цена = СтрокаДанных.Цена;
    СтрокаТабличнойЧасти.Сумма = СтрокаДанных.Количество * СтрокаДанных.Цена;

    // Заполняем другие обязательные реквизиты строки
    СтрокаТабличнойЧасти.ЕдиницаИзмерения = СсылкаНаНоменклатуру.ЕдиницаИзмерения; // Единица измерения из номенклатуры
    
    // Ставка НДС может быть получена из номенклатуры, вида цены, соглашения или установлена явно
    СтрокаТабличнойЧасти.СтавкаНДС = Перечисления.СтавкиНДС.НДС20; // Например, 20%
    СтрокаТабличнойЧасти.СуммаНДС = ОбщегоНазначения.ВычислитьСуммуНДС(СтрокаТабличнойЧасти.Сумма, СтрокаТабличнойЧасти.СтавкаНДС);
    СтрокаТабличнойЧасти.СуммаВключаетНДС = Истина; // Или Ложь, в зависимости от настроек
    СтрокаТабличнойЧасти.ТипЦен = НовыйДокумент.ВидЦены; // Заполняем тип цен в строке

    // Если используются характеристики:
    Если СсылкаНаХарактеристику.ЗначениеЗаполнено() Тогда
        СтрокаТабличнойЧасти.Характеристика = СсылкаНаХарактеристику;
    КонецЕсли;

    // Если используются серии (более сложный случай, обычно требуется подбор по остаткам)
    // СтрокаТабличнойЧасти.СерияНоменклатуры = СсылкаНаСерию; 
КонецЦикла;

Важно: При заполнении табличной части вручную мы также можем воспользоваться стандартными функциями получения цен. Например, в УТ есть общий модуль Ценообразование, который позволяет получить актуальную цену для номенклатуры по заданному виду цены и характеристикам. Это более предпочтительный способ, чем просто подставлять цену из внешнего файла, так как он учитывает все настройки ценообразования в 1С. Также существует возможность заполнять цены на основании документов поступления.


// Пример использования функции получения цены
// Предполагаем, что СсылкаНаНоменклатуру, СсылкаНаХарактеристику (может быть Неопределено) и НовыйДокумент.ВидЦены установлены

СтруктураПараметровЦены = Новый Структура;
СтруктураПараметровЦены.Вставить("Номенклатура", СсылкаНаНоменклатуру);
СтруктураПараметровЦены.Вставить("Характеристика", СсылкаНаХарактеристику);
СтруктураПараметровЦены.Вставить("ВидЦены", НовыйДокумент.ВидЦены);
СтруктураПараметровЦены.Вставить("ДатаЦены", НовыйДокумент.Дата);

// В конфигурациях УТ 11.5 и КА 2.5/ERP 2.5 используются функции общего модуля ЦенообразованиеСервер
ЦенаНоменклатуры = ЦенообразованиеСервер.ПолучитьЦенуНоменклатуры(СтруктураПараметровЦены);

Если ЦенаНоменклатуры = 0 Тогда
    Сообщить("Предупреждение: Цена для номенклатуры " + СсылкаНаНоменклатуру + " по виду цен " + НовыйДокумент.ВидЦены + " не найдена.", СтатусСообщения.Важное);
    // Возможно, нужно установить цену вручную или пропустить строку
Иначе
    СтрокаТабличнойЧасти.Цена = ЦенаНоменклатуры;
    СтрокаТабличнойЧасти.Сумма = СтрокаТабличнойЧасти.Количество * СтрокаТабличнойЧасти.Цена;
    // Пересчет НДС
    СтрокаТабличнойЧасти.СуммаНДС = ОбщегоНазначения.ВычислитьСуммуНДС(СтрокаТабличнойЧасти.Сумма, СтрокаТабличнойЧасти.СтавкаНДС);
КонецЕсли;

Шаг 4: Запись и проведение документа

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

  1. Запись документа: Для записи мы используем метод Записать() объекта документа. Мы можем передать в него параметр РежимЗаписиДокумента.Проведение, чтобы документ был сразу проведен.
  2. Обработка ошибок: Крайне рекомендуется оборачивать операцию записи/проведения в блок Попытка...Исключение...КонецПопытки. Это позволит нам корректно обрабатывать ситуации, когда документ не может быть записан или проведен (например, из-за нехватки остатков, отсутствия обязательных реквизитов, проблем с договорами и т.д.) и выводить пользователю информативное сообщение вместо аварийного завершения работы.

// Попытка записать и провести документ
Попытка
    НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
    Сообщить("Документ 'Реализация товаров и услуг' №" + НовыйДокумент.Номер + " от " + НовыйДокумент.Дата + " успешно создан и проведен.", СтатусСообщения.Информация);
Исключение
    Сообщить("Ошибка при создании или проведении документа 'Реализация товаров и услуг': " + ОписаниеОшибки(), СтатусСообщения.Ошибка);
    // Дополнительная логика обработки ошибки, например, запись в лог
КонецПопытки;

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

Дополнительные рекомендации и нюансы

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

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

Используя представленные шаги и примеры кода, мы можем эффективно автоматизировать процесс создания и заполнения документов "Реализация товаров и услуг" в 1С:Управление торговлей 11.5. Этот подход обеспечивает гибкость и надежность при интеграции с внешними системами или выполнении массовых операций.

← На главную