Снизу вверх по табличной части. Разбираемся в понятиях Идентификатор-индекс-номер строки управляемых форм

29.07.24

Разработка - Механизмы платформы 1С

Казалось бы, что сложного: в таблице на форме 5 строк. Их номера с первой по пятую. Обратиться к любой из них можно по индексу 0-4. Но строки могут добавляться/удаляться, их порядок может изменяться. Попробуем разобраться, как работать со строками таблицы в общем случае.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Снизу вверх по табличной части
.epf 9,33Kb
2
2 Скачать (1 SM) Купить за 1 850 руб.

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

Стоит признать, что в общем случае правильно спозицинироваться на следующей-предыдущей строке действительно не так просто.

Начнем рассмотрение с того, что разберемся, как табличная часть отображается на форме.

Реквизит формы (располагается в правом окне редактирования формы в конфигураторе) - представляет собой отображение табличной части объекта (например, документа). Тип значения - ДанныеФормыКоллекция. Коллекция содержит элементы коллекции, то есть отображения строк табличной части.

Каждый элемент коллекции кроме реквизитов связанной табличной части содержит Номер строки [диапазон 1..Количество строк]. 

К каждой строке (элементу коллекции) можно обратиться по индексу [диапазон 0..Количество строк -1]. Способы обращения: указать индекс в скобках [<Индекс>] или использовать метод Получить(<Индекс>).

Но у каждой строки есть отдельный параметр, не являющийся свойством, то есть его значение невозможно получить напрямую "через точку" - это идентификатор. Уникальный номер строки (тип число). Данный номер не изменяется ни при каких изменениях в составе строк табличной части. 

Например, очередной строке после ввода был присвоен идентификатор 5. Предыдущие 4 строки могли быть удалены, номер  данной строки изменился на первую. Но идентификатор строки остался без изменений.

Получить значение идентификатора любой из строк можно используя метод ПолучитьИдентификатор()

Например, идентификатор для 3й строки:

ТабличнаяЧасть[2].ПолучитьИдентификатор()

Для реквизитов формы типа ДанныеФормыКоллекция, полученных из табличных частей объектных данных (документов, справочников и т.д.), доступно дополнительное свойство ИсходныйНомерСтроки, позволяющее получить номер соответствующей строки реального объекта. Впрочем свойство доступно всегда, но когда реквизит не связан с реальной табличной частью, свойство ничего не возвращает.

Отдельно отметим, что создание в порядке исследования дополнительного реквизита с именем "ИсходныйНомерСтроки" для реквизита типа ДанныеФормыКоллекция привело к ошибке и последующему принудительному закрытию конфигуратора.

На всякий случай заметим, что реквизит формы типа ДанныеФормыКоллекция  не содержит никаких данных о том, как таблица отображается на форме. Например, невозможно определить, какая строка в настоящей момент является текущей. В том числе реквизит формы будет одинаково функционален даже если таблица вообще не добавлена в элементы формы (никакой из элементов формы не содержит путь к данным этого реквизита).

Элемент формы Таблица, связанный с реквизитом Таблица (Путь к данным = Объект.ТабличнаяЧасть) - левая часть окна редактирования формы.

Здесь практически все наоборот.

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

Но есть возможность получить информацию о текущей(активной) строке - точнее, ее идентификаторе.

Кроме того, можно получить массив идентификаторов выделенных строк при множественном выделении.

Как же правильно связать эти данные, на примере той же задачи со стрелками для изменения текущей строки?

Рассмотрим, например, действия по кнопке "Вниз"

  1. Получаем идентификатор текущей строки из элемента типа таблица
  2. По полученному идентификатору находим строку коллекции (реквизит табличной части) через НайтиПоИдетификатору() и получаем ее номер.
  3. К полученному номеру добавляем единицу, определяя номер следующей строки. Обращаемся к строке по идентификатору. Как не парадоксально, но индекс следующей строки будет равен номеру, полученному на предыдущем этапе, так как индекс = номер строки -1.
  4. Получаем идентификатор строки, рассчитанной как следующая. Именно этот идентификатор присваиваем свойству элемента текущая строка элемента формы таблица.

При этом следует учитывать "переполнение". То есть обрабатывать попытку "спуститься ниже последней строки". Здесь возможно 2 варианта действий:

  1. Ничего не изменять и остаться на последней строке
  2. Переместиться на первую строку.

Рассмотрим пример процедуры модуля формы, отрабатывающей действие команды "Вниз". Исполняется на клиенте. Стратегия поведения при достижении последней строки определяется реквизитом формы (возможно, и переменной) Вокруг.

  

&НаКлиенте
Процедура Вниз(Команда)
	
	ТекущаяСтрока = Элементы.ТабличнаяЧасть.ТекущаяСтрока;
	НомерСтрокиТЧ = Объект.ТабличнаяЧасть.НайтиПоИдентификатору(ТекущаяСтрока).НомерСтроки;
	
	
	Если НомерСтрокиТЧ = Объект.ТабличнаяЧасть.Количество() Тогда
		
		Если Вокруг Тогда //Опция Вокруг - переходим на последнюю строку, если нет - остаемся на первой
			
			Элементы.ТабличнаяЧасть.ТекущаяСтрока = Объект.ТабличнаяЧасть[0].ПолучитьИдентификатор();	
			
		КонецЕсли;
		
    Иначе
		Элементы.ТабличнаяЧасть.ТекущаяСтрока = Объект.ТабличнаяЧасть[НомерСтрокиТЧ].ПолучитьИдентификатор(); 
	КонецЕсли;
КонецПроцедуры


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

 

Форма обработки содержит таблицу, в которой помимо строковых значений дополнительно отображается идентификатор строки.

Команды обработки позволяют:

  1. Добавить новую строку (стандартная команда)
  2. Вставить строку перед или после текущей
  3. Сгенерировать наборы из Н строк, содержащие произвольные уникальные идентификаторы
  4. Удалить текущую строку (стандартная и дополнительная команда). Дополнительная команда демонстрирует пример "правильного" удаления.
  5. Двигаться по строкам вверх-вниз
  6. Сортировать строки по убыванию и возрастанию

Разрабатывалось и тестировалось на 23-м релизе 8.3.23.2157. Поскольку "новые" методы здесь не используются, можно с уверенностью сказать, что обработка будет функционировать под любым релизом платформы на управляемых формах.

Проверено на следующих конфигурациях и релизах:

  • 1С:Библиотека стандартных подсистем, редакция 3.1, релизы 3.1.9.453

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    5762    bayselonarrend    19    

151

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5172    dsdred    16    

79

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

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

24.01.2024    13796    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    10205    dsdred    44    

127

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    22526    SeiOkami    46    

133

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    17155    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    13281    YA_418728146    7    

165
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. shard 281 30.07.24 23:25 Сейчас в теме
Возможно ли использовать идентификатор строк (вдруг я что-то пропустил в новых релизах платформы) в запросах? Если нет, то в чем преимущества описанного метода по сравнению с применяющемся способом в типовых конфигурациях с дополнительным реквизитом КлючСтроки?
Вставить строку перед или после текущей
(а также п.4)
Почему в этом случае нельзя текущую строку использовать?
Сгенерировать наборы из Н строк, содержащие произвольные уникальные идентификаторы

при ситуации когда строки добавляю (а платформа и так добавит их с уникальным индексом), потом удаляю без сохранения объекта, а потом снова добавляю и пытаюсь на вторично добавленные строки получить идентификатор - "Индекс находится за границами массива".
Двигаться по строкам вверх-вниз

Как понимаю, речь про перемещение строки ввехр/вниз, а не перемещение курсора по строкам тч? =)
Сортировать строки по убыванию и возрастанию

в чем может заключаться смысл такой сортировки (для пользователей/программистов)?
2. Sergey1CSpb 245 31.07.24 19:36 Сейчас в теме
(1) Здравствуйте, попробую ответить на вопросы, которые понял.
1. В запросах идентификатора строк нет и не будет, так как запросы строятся для получения данных информационной базы. Исключая, конечно, возможность выгрузки данных в таблицу значений и последующего помещения во временную таблицу. Идентификаторы в данной статье это (дополнительные) атрибуты реквизита формы типа ДанныеФормыКоллекция и элемента формы типа Таблица. Непонятно, что хотите получить в запросе, какая строка у пользователя текущая?
2. Начну с того, что статья не предлагает какой-то оригинальный метод, а лишь поясняет функции платформы по работе с коллекциями, связанными с табличными частями, поскольку там не очень все очевидно. Преимущество в том, что используются типовые документированные методы платформы и не требуется каких-то доработок. КлючСтроки обычно добавляют для создания оригинальной ссылки, которая хранится в ИБ, обычно для перевязки строк нескольких табличных частей. Идентификаторы, как писал выше, не хранятся в ИБ, а существуют лишь пока открыта форма.
3. По вопросу "Индекс находится за границами массива", вероятно где-то неправильно получаете идентификатор. Пришлите пример кода, попробую разобраться.

Поясню, что прилагаемая обработка предназначена не для пользователей, а для (начинающих/всех) программистов, которые хотят детальнее разобраться номерах/индексах/идентификаторах, путем просмотра/доработки кода, в том числе в режиме отладки. Практического смысла не имеет. Доп функции представляют лишь демонстрационное назначение. Ведь не так иллюстративно для этой задачи просто так добавлять строки друг за другом, интересно их "перемешать" и посмотреть изменение номеров строк при постоянности индексов.
4. Перемещение строки вверх-вниз как обычно производится стандартными кнопками-функциями командной панели таблицы. Здесь не требовалось дополнительных доработок. А разработаны демонстрационные функции изменения текущей строки. Поскольку, как писал выше, столкнулся с такими сервисными кнопками, функции которых содержали некорректное обращение по идентификатору, что приводило к различным ошибкам.
3. МимохожийОднако 142 18.08.24 07:29 Сейчас в теме
Было бы неплохо исследовать механизмы, когда пользователь перемещает строки с захватом строки курсором мыши
4. Sergey1CSpb 245 19.08.24 22:07 Сейчас в теме
(3) Имеется в виду перетаскивание? В пределах одной таблицы? А этот процесс мало чем отличается от перемещения строк стандартными стрелками вверх-вниз. Идея та же: идентификаторы не изменяются, меняются индексы и номера строк (элементов коллекции) реквизита.
5. Sergey1CSpb 245 19.08.24 22:09 Сейчас в теме
А вот интересно, как мне представляется, как это все ведет себя в дереве. Исследовал это в новой статье:
https://infostart.ru/1c/articles/2165071/
Оставьте свое сообщение