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

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

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

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

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

  1. Неправильная установка текущей строки. Попытка передать сам объект строки в свойство элемента формы. Свойство ТекущаяСтрока таблицы формы ожидает получить Идентификатор строки, а не объект типа ДанныеФормыЭлементКоллекции.
  2. Диалог выбора файла в цикле. Открывать модальные или асинхронные окна внутри цикла перебора строк — грубая логическая ошибка.
  3. Создание строки до выбора файла. Если добавить строку в ТЧ до вызова диалога, а пользователь нажмет «Отмена», в документе останется пустая «мусорная» строка.
  4. Использование устаревших методов. Метод НачатьПомещениеФайла признан устаревшим начиная с версии 8.3.15.
  5. Передача нестабильного контекста. Передача Элементы.Документы.ТекущиеДанные в ОписаниеОповещения может привести к ошибке, если фокус интерфейса не успел переключиться.

Правильный алгоритм действий (Диалог -> Данные)

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

  1. Вызываем диалог выбора файла.
  2. Проверяем результат: если файл не выбран, прерываем выполнение.
  3. Если файл успешно помещен во временное хранилище, программно добавляем новую строку через метод Добавить().
  4. Заполняем реквизиты добавленной строки (имя файла, адрес в хранилище).
  5. Переводим фокус на новую строку с помощью метода ПолучитьИдентификатор().

Пример правильного решения

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


&НаКлиенте
Процедура Документы_ЗагрузитьФайл(Команда)
    
    ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
    ДиалогОткрытияФайла.Заголовок = "Выберите файл";
    
    // Подготавливаем оповещение для возврата после выбора файла
    ПроцедураОбработки = Новый ОписаниеОповещения("ВыполнитьЗагрузкуЗавершение", ЭтаФорма);
    
    // Используем современный метод помещения файла на сервер
    НачатьПомещениеФайлаНаСервер(ПроцедураОбработки, , ДиалогОткрытияФайла, УникальныйИдентификатор);

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

&НаКлиенте
Процедура ВыполнитьЗагрузкуЗавершение(ОписаниеПомещенногоФайла, ДополнительныеПараметры) Экспорт
    
    // Если пользователь отменил выбор файла, прерываем процедуру
    Если ОписаниеПомещенногоФайла = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Файл успешно помещен - только теперь создаем новую строку
    НоваяСтрока = Объект.Документы.Добавить();
    
    // Заполняем данные строки
    Файл = Новый Файл(ОписаниеПомещенногоФайла.Имя);
    НоваяСтрока.ИмяФайла = Файл.Имя;
    
    // Вызываем серверную функцию для сохранения файла (если требуется)
    НоваяСтрока.ИмяФайлаВХранилище = Служебный.ЗагрузитьФайлНаСервере(ОписаниеПомещенногоФайла.Адрес, Файл.Расширение);
    
    Если НоваяСтрока.ИмяФайлаВХранилище <> "" Тогда
        НоваяСтрока.ЕстьДокумент = Истина;
    КонецЕсли;
    
    // КРИТИЧЕСКИ ВАЖНО: Устанавливаем текущую строку через её Идентификатор!
    Элементы.Документы.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
    
КонецПроцедуры

Использование современных обещаний (Promises)

В самых свежих версиях платформы 1С мы можем отказаться от экспортных процедур оповещений и написать код линейно, используя асинхронные методы с оператором Ждать. Посмотрим на современный вариант решения этой же задачи:


&НаКлиенте
Асинх Процедура Документы_ЗагрузитьФайлАсинх(Команда)
    
    ДиалогОткрытия = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДиалогОткрытия.Заголовок = "Выберите файл";
    
    // Ждем, пока пользователь выберет файл и он загрузится на сервер
    Результат = Ждать ПоместитьФайлНаСерверАсинх( , , ДиалогОткрытия, УникальныйИдентификатор);
    
    // Если пользователь закрыл диалог без выбора
    Если Результат = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Строку добавляем только после успешного получения файла
    НоваяСтрока = Объект.Документы.Добавить();
    
    Файл = Новый Файл(Результат.Имя);
    НоваяСтрока.ИмяФайла = Файл.Имя;
    НоваяСтрока.ИмяФайлаВХранилище = Служебный.ЗагрузитьФайлНаСервере(Результат.Адрес, Файл.Расширение);
    НоваяСтрока.ЕстьДокумент = Истина;
    
    // Делаем добавленную строку текущей
    Элементы.Документы.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
    
КонецПроцедуры

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

← На главную