Как заполнить табличную часть документа 1С из Excel-файла?

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

При работе в конфигурациях на обычных формах (например, «Управление торговлей 10.3») часто возникает задача автоматизации рутинного ввода данных. Типичный сценарий: у компании есть обработка для парсинга прайс-листов или накладных из Excel, которая создает новый документ и заполняет его. Однако пользователям гораздо удобнее открыть уже существующий или только что созданный (но еще не сохраненный) документ, нажать кнопку и импортировать строки непосредственно в текущую экранную форму.

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

Критические ошибки при реализации (анализ подходов форума)

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


Форма = ОткрытьФорму("Обработка.ЗагрузкаДанныхИзТабличногоДокумента.Форма");
Форма.ЭтотОбъект.СсылкаИсточника = ЭтаФорма.ЭтотОбъект.Ссылка;

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

  1. Проблема нового (несохраненного) документа. Если пользователь нажал кнопку «Создать» в списке документов, форма открылась, но документ еще не был записан в базу данных, свойство ЭтотОбъект.Ссылка вернет пустую ссылку (ДокументСсылка.Пустая()). В результате обработка не сможет определить документ-источник и выдаст ошибку.
  2. Конфликт изменения данных (блокировка версии). Если обработка получает реальную ссылку, считывает данные из Excel, записывает их в документ на стороне сервера и выполняет метод Записать(), то в базе данных сохраняется новая версия объекта. При этом у пользователя на экране остается открытой старая копия данных. При попытке пользователя нажать «Записать» или «Провести» на форме документа, платформа 1С выдаст критическую ошибку: «Данные были изменены или удалены другим пользователем».

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


Способ 1. Внешняя обработка заполнения табличной части (Рекомендуемый метод)

Это наиболее изящный способ, соответствующий стандартам разработки фирмы «1С». Он позволяет решить задачу вообще без изменения конфигурации. База данных останется на полной поддержке, а у пользователя над табличной частью автоматически появится стандартная кнопка «Заполнить».

Рассмотрим пошагово процесс создания такой обработки:

Шаг 1. Создание обработки в конфигураторе. Создайте новую внешнюю обработку. В модуле объекта этой обработки обязательно должна быть объявлена экспортная процедура Инициализировать. Напишем ее код:


Процедура Инициализировать(Объект, ИмяТабличнойЧасти, ТабличноеПоле) Экспорт
    // Параметр "Объект" — это и есть ДокументОбъект, открытый на экране у пользователя.
    // ИмяТабличнойЧасти — строковое имя заполняемой ТЧ (например, "Товары").
    
    // Получаем форму нашей обработки
    ФормаЗагрузки = ПолучитьФорму("Форма");
    
    // Передаем контекст документа напрямую в свойства формы обработки
    ФормаЗагрузки.ДокументОбъект = Объект; 
    ФормаЗагрузки.ИмяТабличнойЧасти = ИмяТабличнойЧасти;
    
    // Открываем форму обработки модально
    ФормаЗагрузки.ОткрытьМодально();
КонецПроцедуры

Шаг 2. Настройка формы обработки. В форме создаваемой обработки загрузки в самом верху модуля (в разделе объявления переменных) пропишите экспортные переменные для приема переданных параметров:


Перем ДокументОбъект Экспорт;
Перем ИмяТабличнойЧасти Экспорт;

Теперь напишем алгоритм чтения файла Excel и заполнения строк. Для этого лучше использовать стандартный объект 1С ТабличныйДокумент, который умеет читать файлы .xls и .xlsx напрямую, не требуя установленного пакета Microsoft Office на компьютере пользователя:


Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    // Проверим, переданы ли нам данные документа
    Если ДокументОбъект = Неопределено Тогда
        Предупреждение("Обработка запущена в автономном режиме. Заполнение невозможно.");
        Возврат;
    КонецЕсли;
    
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        ТабДок.Прочитать(ПутьКФайлу);
    Исключение
        Предупреждение("Не удалось прочитать файл Excel! " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // Начинаем обход строк таблицы Excel со второй строки (пропуская шапку)
    Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл
        
        НаименованиеТовара = СокрЛП(ТабДок.Область(НомерСтроки, 1).Текст);
        Если ПустаяСтрока(НаименованиеТовара) Тогда
            Продолжить; // Пропускаем пустые строки
        КонецЕсли;
        
        Количество = Число(ТабДок.Область(НомерСтроки, 2).Текст);
        Цена = Число(ТабДок.Область(НомерСтроки, 3).Текст);
        
        // Поиск номенклатуры в справочнике
        НайденнаяНоменклатура = Справочники.Номенклатура.НайтиПоНаименованию(НаименованиеТовара, Истина);
        
        Если НайденнаяНоменклатура.Пустая() Тогда
            Сообщить("Товар не найден в базе данных: " + НаименованиеТовара, СтатусСообщения.Внимание);
            Продолжить;
        КонецЕсли;
        
        // Добавляем строку непосредственно в переданный нам объект в памяти
        НоваяСтрока = ДокументОбъект[ИмяТабличнойЧасти].Добавить();
        НоваяСтрока.Номенклатура = НайденнаяНоменклатура;
        НоваяСтрока.Количество = Количество;
        НоваяСтрока.Цена = Цена;
        НоваяСтрока.Сумма = Количество * Цена;
        
        // Для УТ 10.3 важно также заполнить базовые реквизиты единицы измерения
        НоваяСтрока.ЕдиницаИзмерения = НайденнаяНоменклатура.ЕдиницаХраненияОстатков;
        НоваяСтрока.Коэффициент = НайденнаяНоменклатура.ЕдиницаХраненияОстатков.Коэффициент;
        
    КонецЦикла;
    
    // Закрываем форму обработки после успешного завершения
    Закрыть();
    
КонецПроцедуры

Шаг 3. Подключение обработки в режиме Предприятия. Запустите 1С в режиме предприятия. Перейдите в меню Сервис — Дополнительные отчеты и обработки — Дополнительные внешние обработки табличных частей. Добавьте созданный файл обработки, укажите в таблице принадлежности документ «Поступление товаров и услуг» и табличную часть «Товары». После этого в документе над списком товаров появится кнопка «Заполнить».


Способ 2. Внедрение кнопки непосредственно на форму документа

Если бизнес-требования предписывают жесткое наличие индивидуальной кнопки «Загрузить из Excel» прямо в интерфейсе формы документа, выполните следующие действия:

Шаг 1. Размещение кнопки. Откройте форму документа «Поступление товаров услуг» в конфигураторе, добавьте новую кнопку и в ее событии Нажатие пропишите следующий код:


Процедура ДействиеКнопкиИмпортExcel(Кнопка)
    
    // Получаем внешнюю или внутреннюю обработку
    ОбработкаОбъект = Обработки.ЗагрузкаДанныхИзФайлаXLS.Создать();
    ФормаЗагрузки = ОбработкаОбъект.ПолучитьФорму("Форма");
    
    // Передаем ссылку на текущую форму (контекст выполнения)
    ФормаЗагрузки.ДокументОбъект = ЭтотОбъект;
    ФормаЗагрузки.ИмяТабличнойЧасти = "Товары";
    
    ФормаЗагрузки.ОткрытьМодально();
    
КонецПроцедуры

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

Особенности использования стандартной обработки «Загрузка данных из табличного документа»

На форумах часто советуют использовать стандартную обработку с диска ИТС ЗагрузкаДанныхИзТабличногоДокумента.epf. Она действительно очень гибкая и универсальная, однако имеет свою специфику:

Поэтому для повседневной работы пользователей гораздо эффективнее написать простую специализированную обработку парсинга Excel с использованием объектной модели 1С, как это показано в примерах выше. Это сбережет нервы пользователям и исключит ошибки версионирования объектов в многопользовательском режиме.

← На главную