При разработке интерфейсов в платформе 1С:Предприятие 7.7 часто возникает задача динамического отображения сопутствующих данных по выбранной позиции (например, показ остатков товара по складам, цен, резервов или истории взаиморасчетов). Однако при попытке прочитать номер активной строки через свойство НомерСтроки разработчики нередко сталкиваются с ситуацией, когда система всегда возвращает номер последней строки документа или значение, равное общему количеству строк.
Разберем детально, почему так происходит и как правильно получать данные текущей активной строки табличной части документа.
Проанализируем механику работы контекста документа в 1С 7.7. Внутренний указатель текущей строки табличной части в контексте формы является общим как для визуального отображения, так и для программного кода модуля формы. К сбиванию фокуса активной строки обычно приводят следующие причины:
ПриОткрытии, в функции пересчета итогов или в формуле любого другого элемента диалога выполняется цикл обхода строк вида ВыбратьСтроки() ... ПолучитьСтроку(), указатель документа смещается. После завершения такого цикла внутренний курсор всегда остается на последней позиции (равной КоличествоСтрок()). Любое дальнейшее обращение к переменным табличной части или НомерСтроки вернет данные последней строки.ТекущаяСтрока(): В отличие от объекта ТаблицаЗначений, встроенная табличная часть объекта Документ в платформе 7.7 не имеет метода ТекущаяСтрока(), поэтому обращаться к ней напрямую таким способом нельзя.Рассмотрим базовый и наиболее надежный штатный механизм платформы 1С 7.7. Для динамического отслеживания строки табличной части разместим на форме документа визуальный элемент диалога типа «Текст» и назначим ему функцию-обработчик.
Разберем по шагам, как это реализовать:
ПоказатьДанныеСтроки().
Функция ПоказатьДанныеСтроки()
Если (КоличествоСтрок() > 0) И (НомерСтроки > 0) Тогда
// Читаем реквизиты текущей активной строки
ТекТовар = Номенклатура;
ТекНомер = НомерСтроки;
// Выполняем требуемые действия, например, расчет остатков
// Возвращаем текст для отображения на форме
Возврат "Строка " + ТекНомер + ": " + Строка(ТекТовар);
КонецЕсли;
Возврат "";
КонецФункции
В момент перерисовки формы и переключения курсора между строками табличной части платформа автоматически позиционирует контекст на текущей выбранной пользователем строке, и прямое обращение к реквизитам шапки и многострочной части возвращает актуальные значения.
Если в форме документа необходимо выполнить служебный перебор строк табличной части (для подсчета сумм, проверки заполнения или выгрузки), важно не сбивать контекст формы. Рассмотрим проверенные варианты решения этой проблемы.
Посмотрим на пример использования независимого объекта. Создаем отдельный экземпляр документа через СоздатьОбъект и выполняем перебор строк в нем. При этом контекст формы остается нетронутым:
Док = СоздатьОбъект("Документ." + Вид());
Если Док.НайтиДокумент(ТекущийДокумент()) = 1 Тогда
Док.ВыбратьСтроки();
Пока Док.ПолучитьСтроку() = 1 Цикл
// Обработка данных строки без влияния на курсор формы
КонецЦикла;
КонецЕсли;
Разберем вариант с предварительной выгрузкой строк. Этот подход не меняет позицию курсора и работает значительно быстрее прямого перебора:
ТЗ = СоздатьОбъект("ТаблицаЗначений");
ВыгрузитьТабличнуюЧасть(ТЗ);
// Далее выполняем любые циклы и расчеты по объекту ТЗ
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
// Расчет данных
КонецЦикла;
Если программный перебор в контексте формы неизбежен, запомним номер активной строки перед циклом и восстановим его после завершения с помощью метода ПолучитьСтрокуПоНомеру():
ТекПозиция = НомерСтроки;
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
// Выполнение необходимых операций
КонецЦикла;
// Восстанавливаем исходный указатель
Если ТекПозиция > 0 Тогда
ПолучитьСтрокуПоНомеру(ТекПозиция);
КонецЕсли;
Важный момент: В платформе 1С 7.7 нет встроенного события «ПриАктивизацииСтроки». Вычисление формулы текстового поля происходит при общей перерисовке диалога. Если требуется принудительно обновить отображение данных на форме после изменения состояния, вызовите метод Форма.Обновить().