Работа с таблицами в 1С:Предприятие — одна из самых частых задач, с которыми сталкиваются разработчики и пользователи. Умение правильно управлять текущей строкой (или "активной строкой") позволяет не только улучшить юзабилити интерфейса, но и автоматизировать обработку данных, избежать ошибок при вводе или редактировании. Однако стандартные механизмы платформы не всегда интуитивно понятны: где-то строка выделяется автоматически, а где-то требует явного указания через код.
В этой статье мы разберём все возможные способы работы с текущей строкой — от базового выделения с помощью свойства ТекущаяСтрока до программного управления через обработчики событий. Особое внимание уделим типичным ошибкам, которые приводят к "потере фокуса" в таблице, и покажем, как их избежать. Материал актуален для 1С 8.3 (включая последние релизы) и 1С 8.2, с учётом особенностей управляемых форм.
Если вы только начинаете осваивать программирование в 1С, начните с первых двух разделов — там описаны простейшие методы, которые покрывают 80% практических задач. Опытным разработчикам будет полезен раздел про динамическое управление строкой через события и асинхронные операции.
1. Базовый способ: свойство ТекущаяСтрока
Самый простой способ установить текущую строку — использовать встроенное свойство ТекущаяСтрока, доступное для большинства табличных элементов. Этот метод работает как для таблиц значений, так и для табличных частей документов или справочников.
Чтобы выделить строку программно, достаточно одной строки кода:
Таблица.ТекущаяСтрока = ИндексСтроки;
где ИндексСтроки — порядковый номер строки (начиная с 0). Например, для выделения второй строки:
Таблица.ТекущаяСтрока = 1;
Важно понимать, что свойство ТекущаяСтрока не только устанавливает визуальное выделение, но и определяет, какая строка будет обрабатываться при нажатии кнопок (например, Удалить или Редактировать). Если не указать текущую строку явно, платформа может автоматически сбросить выделение после обновления данных.
- 📌 Для таблиц значений: свойство доступно напрямую через объект
ТаблицаЗначений. - 📌 Для табличных частей: обращайтесь через элемент формы, например:
ЭлементыФормы.ТабличнаяЧасть.ТекущаяСтрока. - 📌 Для динамических списков: используйте метод
ТекущиеДанные()(подробнее в разделе 4).
Ограничение метода: если строка была удалена или скрыта (например, через фильтр), попытка установить её текущей приведёт к ошибке. Чтобы избежать этого, предварительно проверяйте существование строки:
Если Таблица.КоличествоСтрок() > ИндексСтроки Тогда
Таблица.ТекущаяСтрока = ИндексСтроки;
КонецЕсли;
Если после установки ТекущаяСтрока выделение не появляется, проверьте, не заблокирована ли таблица для редактирования через свойство ТолькоПросмотр или РежимРедактирования.
2. Визуальное выделение без программного кода
Не всегда требуется программно устанавливать текущую строку. В 1С есть встроенные механизмы, которые автоматически выделяют строку при взаимодействии с пользователем:
- 🖱️ Клик мышью: при щелчке по строке она становится текущей (если таблица не заблокирована).
- ↑↓ Клавиши навигации: стрелочки на клавиатуре перемещают выделение вверх/вниз.
- 🔍 Поиск (Ctrl+F): после нахождения значения строка выделяется автоматически.
Однако автоматическое выделение может сбиваться в следующих случаях:
⚠️ Внимание: Если в таблице включён режимМножественныйВыбор, текущей строкой считается последняя выделенная. При этом визуально все выделенные строки подсвечены, но программноТекущаяСтрокавернёт индекс только одной.
Чтобы вернуть стандартное поведение, отключите множественный выбор:
Таблица.МножественныйВыбор = Ложь;
Для динамического управления визуальным выделением (например, подсветкой строки другим цветом) используйте условное оформление. Пример для таблицы значений:
Таблица.УсловноеОформление.ДобавитьУсловие();
Таблица.УсловноеОформление.Условие(0).Видимость = Истина;
Таблица.УсловноеОформление.Условие(0).ЦветФона = RGB(200, 230, 200);
Таблица.УсловноеОформление.Условие(0).Выражение = "Выборка.НомерСтроки = ТекущаяСтрока()";
3. Работа с текущей строкой в табличных частях документов
Табличные части документов и справочников имеют особенности при работе с текущей строкой. Здесь выделение управляется через элемент формы, а не через объект данных. Рассмотрим типичный сценарий:
Допустим, у вас есть документ РеализацияТоваровУслуг с табличной частью Товары. Чтобы установить текущую строку:
ЭлементыФормы.Товары.ТекущаяСтрока = 2; // Третья строка (индексация с 0)
Если строка была добавлена или удалена программно, выделение может сбиваться. Чтобы избежать этого, используйте метод Обновить() после изменения данных:
Документ.Товары.Добавить();
Документ.Товары[Документ.Товары.Количество() - 1].Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Товар 1");
ЭлементыФормы.Товары.Обновить();
ЭлементыФормы.Товары.ТекущаяСтрока = Документ.Товары.Количество() - 1;
| Метод | Описание | Пример использования |
|---|---|---|
ТекущаяСтрока |
Устанавливает или возвращает индекс текущей строки | ТекущаяСтрока = ЭлементыФормы.Товары.ТекущаяСтрока; |
ПолучитьТекущиеДанные() |
Возвращает объект текущей строки (для управляемых форм) | ТекущаяСтрокаДанных = ЭлементыФормы.Товары.ПолучитьТекущиеДанные(); |
УстановитьТекущиеДанные() |
Устанавливает текущую строку по объекту данных | ЭлементыФормы.Товары.УстановитьТекущиеДанные(Документ.Товары[0]); |
Обратите внимание: в управляемых формах для работы с текущей строкой часто удобнее использовать методы Значение // Код работы с текущей строкой КонецЕсли;ПолучитьТекущиеДанные() и УстановитьТекущиеДанные(), так как они работают напрямую с объектами данных, а не с индексами.
Что делать, если ТекущаяСтрока возвращает -1?
-1 означает, что ни одна строка не выделена. Это может происходить, если таблица пустая, все строки удалены или выделение было сброшено программно. Чтобы избежать ошибок, всегда проверяйте:
Если ЭлементыФормы.Товары.ТекущаяСтрока <> Неопределено Тогда
4. Текущая строка в динамических списках
Динамические списки (например, в отчётах или формах выбора) имеют собственную логику работы с текущей строкой. Здесь вместо свойства ТекущаяСтрока используется метод ТекущиеДанные(), который возвращает объект данных (а не индекс).
Пример получения текущей строки в динамическом списке:
ТекущаяСтрокаДанных = ЭлементыФормы.СписокТоваров.ТекущиеДанные();
Если ТекущаяСтрокаДанных <> Неопределено Тогда
Сообщить("Выбран товар: " + ТекущаяСтрокаДанных.Наименование);
КонецЕсли;
Чтобы установить текущую строку программно, используйте метод НайтиСтроку() или УстановитьТекущиеДанные():
// Вариант 1: по индексу
ЭлементыФормы.СписокТоваров.ТекущиеДанные = ЭлементыФормы.СписокТоваров.ПолучитьЭлемент(2);
// Вариант 2: по значению
НайденнаяСтрока = ЭлементыФормы.СписокТоваров.НайтиСтроку(Новый Структура("Наименование", "Товар 1"));
Если НайденнаяСтрока <> Неопределено Тогда
ЭлементыФормы.СписокТоваров.ТекущиеДанные = НайденнаяСтрока;
КонецЕсли;
В динамических списках текущая строка может "сбрасываться" при:
- 🔄 Обновлении списка (например, после применения фильтра).
- 📊 Изменении группировки или сортировки.
- 🚫 Закрытии формы с последующим открытием.
⚠️ Внимание: Если динамический список привязан к данным черезИсточникДанных, попытка установить текущую строку на несуществующий элемент может привести к ошибке "Объект не найден". Всегда проверяйте результатНайтиСтроку().
5. Обработчики событий для автоматического управления строкой
Для сложных сценариев (например, автоматического перемещения по строкам после ввода данных) используйте обработчики событий. Рассмотрим два ключевых события:
1. ПриИзменении — срабатывает после редактирования ячейки. Можно использовать для перехода на следующую строку:
Процедура ТоварыПриИзменении(Элемент, Колонка, Значение)
Если Колонка.Имя = "Количество" Тогда
ТекущаяСтрока = ЭлементыФормы.Товары.ТекущаяСтрока;
Если ТекущаяСтрока < ЭлементыФормы.Товары.Строки.Количество() - 1 Тогда
ЭлементыФормы.Товары.ТекущаяСтрока = ТекущаяСтрока + 1;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
2. ПриАктивизацииСтроки — срабатывает при выделении строки (кликом или клавишами). Полезно для динамической подгрузки данных:
Процедура ТоварыПриАктивизацииСтроки(Элемент, Строка)
ТекущаяСтрокаДанных = ЭлементыФормы.Товары.ПолучитьТекущиеДанные();
ЗаполнитьДополнительнуюИнформацию(ТекущаяСтрокаДанных.Ссылка);
КонецПроцедуры
Для отмены стандартного поведения (например, запрета выделения определённых строк) используйте событие ПередАктивизациейСтроки:
Процедура ТоварыПередАктивизациейСтроки(Элемент, Строка, Отказ)
Если Строка.ПометкаУдаления Тогда
Отказ = Истина;
Сообщить("Нельзя выбрать удалённую строку!");
КонецЕсли;
КонецПроцедуры
Строка существует (индекс не превышает количество строк)|
Таблица не заблокирована (свойство ТолькоПросмотр = Ложь)|
Для динамических списков: данные не пустые (ТекущиеДанные() <> Неопределено)|
Обработчики событий не конфликтуют с стандартной логикой-->
6. Типичные ошибки и их решения
Даже опытные разработчики сталкиваются с проблемами при работе с текущей строкой. Разберём самые распространённые ошибки и способы их исправления:
Ошибка 1: ТекущаяСтрока возвращает Неопределено или -1
- 🔹 Причина: Таблица пустая или выделение было сброшено.
- 🔹 Решение: Проверяйте количество строк перед обращением к
ТекущаяСтрока.
Ошибка 2: Выделение сбивается после обновления данных
- 🔹 Причина: После изменения таблицы (добавление/удаление строк) индексы сдвигаются.
- 🔹 Решение: Сохраняйте ссылку на объект строки (не индекс!) или обновляйте выделение после изменений.
Ошибка 3: В динамическом списке не работает ТекущаяСтрока
- 🔹 Причина: Для динамических списков нужно использовать
ТекущиеДанные(). - 🔹 Решение: Замените
ТекущаяСтрокана методы работы с данными.
Ошибка 4: Множественный выбор мешает работе с текущей строкой
- 🔹 Причина: В режиме
МножественныйВыбортекущей считается последняя выделенная строка. - 🔹 Решение: Отключите множественный выбор или используйте
ПолучитьВыделенныеСтроки().
Критическая особенность: В управляемых формах при асинхронных операциях (например, ожидании ответа от сервера) текущая строка может сброситься. Чтобы этого избежать, сохраняйте индекс или ссылку на строку в переменную до начала длительной операции и восстанавливайте выделение после её завершения.
7. Продвинутые сценарии: асинхронная работа и API
В современных конфигурациях 1С часто требуется работать с текущей строкой в асинхронном режиме (например, при загрузке данных по HTTP или обращении к внешним API). В таких случаях стандартные методы могут не срабатывать из-за особенностей управляемого приложения.
Пример: обновление текущей строки после асинхронного запроса:
Процедура ОбновитьДанныеТоваров()
ТекущийИндекс = ЭлементыФормы.Товары.ТекущаяСтрока; // Сохраняем индекс
Запрос = Новый HTTPЗапрос("https://api.example.com/goods");
Ответ = Новый HTTPСоединение().Получить(Запрос);
// Обработка ответа
Данные = JSON.Прочитать(Ответ.ПолучитьТекст());
ЭлементыФормы.Товары.ОбновитьДанные(Данные);
// Восстанавливаем текущую строку
Если ТекущийИндекс >= 0 И ТекущийИндекс < ЭлементыФормы.Товары.Строки.Количество() Тогда
ЭлементыФормы.Товары.ТекущаяСтрока = ТекущийИндекс;
КонецЕсли;
КонецПроцедуры
Для работы с REST API или веб-сервисами может потребоваться передавать идентификатор текущей строки в запросе. Например:
ТекущаяСтрокаДанных = ЭлементыФормы.Товары.ТекущиеДанные();
Если ТекущаяСтрокаДанных <> Неопределено Тогда
Параметры = Новый Структура("id", ТекущаяСтрокаДанных.УникальныйИдентификатор);
Ответ = ВыполнитьRESTЗапрос("обновить_товар", Параметры);
КонецЕсли;
При работе с мобильным приложением 1С или тонким клиентом учитывайте, что некоторые события (например, ПриИзменении) могут срабатывать с задержкой. В таких случаях используйте флаг ожидания:
Процедура ТоварыПриИзменении(Элемент, Колонка, Значение)
Если НЕ ЗначениеЗаполнено(ФлагОбновления) Тогда
ФлагОбновления = Истина;
ОбновитьЦеныАсинхронно();
ФлагОбновления = Ложь;
КонецЕсли;
КонецПроцедуры
При асинхронных операциях всегда сохраняйте текущее состояние строки (индекс или ссылку) до начала операции и восстанавливайте его после завершения. Это предотвратит потерю фокуса.
FAQ: Частые вопросы по работе с текущей строкой
Как узнать индекс текущей строки в таблице значений?
Используйте свойство ТекущаяСтрока:
Индекс = ТаблицаЗначений.ТекущаяСтрока;
Если строка не выделена, метод вернёт Неопределено или -1 (в зависимости от контекста).
Почему после добавления строки текущая строка сбивается?
При добавлении новой строки индексы существующих строк сдвигаются. Чтобы сохранить выделение, используйте один из способов:
- Сохраняйте ссылку на объект строки (не индекс) перед добавлением.
- Обновляйте выделение после изменения таблицы:
Таблица.Добавить();Таблица.ТекущаяСтрока = Таблица.КоличествоСтрок() - 1;
Как запретить пользователю выделять определённые строки?
Используйте событие ПередАктивизациейСтроки:
Процедура ТаблицаПередАктивизациейСтроки(Элемент, Строка, Отказ)
Если Строка.Статус = "Заблокировано" Тогда
Отказ = Истина;
Сообщить("Эта строка недоступна для редактирования!");
КонецЕсли;
КонецПроцедуры
Можно ли получить текущую строку в отчёте?
В отчётах 1С понятие "текущей строки" зависит от типа вывода:
- 📊 Табличный документ: используйте методы
ПолучитьОбласть()иТекущаяСтрока()для ячеек. - 📋 Динамический список: работайте через
ТекущиеДанные(), как описано в разделе 4.
Пример для табличного документа:
ТекущаяСтрока = ТабличныйДокумент.ТекущаяСтрока();
Как программно прокрутить таблицу к текущей строке?
Для прокрутки используйте метод ПоказатьСтроку():
ЭлементыФормы.Товары.ПоказатьСтроку(ТекущаяСтрока);
Если строка не видна (например, из-за фильтра), предварительно снимите фильтрацию или проверьте видимость:
Если ЭлементыФормы.Товары.Строки[ТекущаяСтрока].Видимость Тогда
ЭлементыФормы.Товары.ПоказатьСтроку(ТекущаяСтрока);
КонецЕсли;