Как заполнить табличную часть документа Установка цен номенклатуры из Excel

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

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

Анализируем причину проблемы: почему данные не видны

Первое, что мы должны понять: документ Установка цен номенклатуры хранит данные в двух табличных частях — Товары и ТипыЦен. Однако на форме документа пользователь видит реквизит формы (обычно с именем ТаблицаЦен), который программно заполняется при открытии формы на основании данных из этих двух ТЧ. Это сделано для того, чтобы представить цены в виде удобной сетки (кросс-таблицы).

Если мы просто заполним табличную часть Товары через внешнюю обработку заполнения, форма об этом «не узнает». Она продолжит показывать старое содержимое своего внутреннего реквизита. Чтобы решить эту задачу, нам необходимо не только правильно заполнить объектные данные, но и инициировать обновление интерфейса.

Шаг 1: Подготовка и подключение к Excel

Начнем с классического метода через COM-соединение. Рассмотрим процедуру инициализации, которая будет выполняться в контексте внешней обработки заполнения табличных частей.


Процедура Инициализировать(Объект, ИмяТабличнойЧасти, ТабличноеПоле) Экспорт
    
    ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогВыбора.Заголовок = "Выберите файл Excel";
    ДиалогВыбора.Фильтр = "Excel (*.xls;*.xlsx)|*.xls;*.xlsx";
    
    Если Не ДиалогВыбора.Выбрать() Тогда
        Возврат;
    КонецЕсли;

    ИмяФайла = ДиалогВыбора.ПолноеИмяФайла;

    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.WorkBooks.Open(ИмяФайла);
    Исключение
        Сообщить("Не удалось открыть Excel! " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // Работаем с первым листом
    Лист = Excel.Sheets(1);
КонецПроцедуры

Шаг 2: Алгоритм заполнения табличных частей объекта

Проанализируем структуру заполнения. Чтобы документ корректно провелся и отобразил данные, нам нужно соблюдать следующие правила:

  1. Заполнить ТЧ ТипыЦен: В этой таблице должны быть перечислены все типы цен, которые мы планируем установить. Если мы загружаем «Оптовую» цену, ссылка на этот тип цены обязана присутствовать в этой ТЧ.
  2. Заполнить ТЧ Товары: Для каждой позиции номенклатуры создается строка. Если для одной номенклатуры устанавливается несколько типов цен, в ТЧ Товары будет создано несколько строк.
  3. Установить Единицу измерения: Это должен быть не просто элемент справочника, а единица, подчиненная данной номенклатуре (владелец).

Рассмотрим пример кода для обхода строк Excel и заполнения данных:


// Предположим, ТипЦенСсылка уже выбран пользователем или определен
ТабличнаяЧастьТовары = Объект.Товары;
ТабличнаяЧастьТипыЦен = Объект.ТипыЦен;

// Проверим, есть ли наш тип цен в документе
СтрокаТипа = ТабличнаяЧастьТипыЦен.Найти(ТипЦенСсылка, "ТипЦен");
Если СтрокаТипа = Неопределено Тогда
    НоваяСтрокаТипа = ТабличнаяЧастьТипыЦен.Добавить();
    НоваяСтрокаТипа.ТипЦен = ТипЦенСсылка;
КонецЕсли;

КоличествоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;

Для НомерСтроки = 2 По КоличествоСтрок Цикл
    
    Артикул = СокрЛП(Лист.Cells(НомерСтроки, 1).Text);
    ЦенаЗначение = Лист.Cells(НомерСтроки, 2).Value; // Используем .Value для чисел
    
    НоменклатураСсылка = Справочники.Номенклатура.НайтиПоКоду(Артикул);
    
    Если Не НоменклатураСсылка.Пустая() Тогда
        НоваяСтрока = ТабличнаяЧастьТовары.Добавить();
        НоваяСтрока.Номенклатура = НоменклатураСсылка;
        НоваяСтрока.ТипЦен = ТипЦенСсылка;
        НоваяСтрока.Цена = Число(ЦенаЗначение);
        
        // Важно: берем единицу хранения остатков у номенклатуры
        НоваяСтрока.ЕдиницаИзмерения = НоменклатураСсылка.ЕдиницаХраненияОстатков;
        НоваяСтрока.Валюта = ТипЦенСсылка.Валюта;
    КонецЕсли;
    
КонецЦикла;

Шаг 3: Обработка типов данных и типичные ошибки

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

Шаг 4: Обновление формы (Главный секрет)

Как мы уже выяснили, после работы обработки заполнения табличная часть объекта заполнена, но на экране пользователя ничего не изменилось. Выясним, как заставить форму «перерисоваться».

В обычных формах 1С (8.2/8.3) нет прямого метода «ОбновитьДанныеФормы» для серверного объекта. Однако есть несколько обходных путей:

Вариант А: Запись и переоткрытие. Это самый надежный метод. В конце вашей процедуры вы вызываете Объект.Записать(). После завершения работы обработки заполнения форма документа может быть переоткрыта. Однако это не всегда удобно для пользователя.

Вариант Б: Вызов экспортного метода формы. В типовой УТ 10.3 в модуле формы документа УстановкаЦенНоменклатуры есть процедура ЗаполнитьТабличнуюЧастьЦен(). Если ваша обработка вызывается из формы, вы можете попробовать достучаться до этого метода. Но так как стандартный механизм «Заполнение ТЧ» передает только объект, лучшим решением будет использование ОповеститьОбИзменении(Тип("ДокументОбъект.УстановкаЦенНоменклатуры")).

Вариант В: Создание собственной формы в обработке. Вместо использования стандартного механизма заполнения ТЧ (кнопка «Заполнить»), создайте у своей обработки форму. На этой форме пользователь выберет файл, увидит результат в таблице, и по кнопке «Перенести в документ» вы программно заполните ТЧ документа и, если нужно, принудительно перезаполните реквизит формы ТаблицаЦен через ЭтаФорма.ВладелецФормы.

Итоги

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

← На главную