1с найти строку в данныеформыколлекция
Управляемая форма 1С 8.2 – работа с таблицей на форме (управление текущей строкой, перемещение и удаление элементов)
Очередная статья посвящена программной работе с таблицей управляемой формы, отображающей реквизит формы типа ДанныеФормыКоллекция. Казалось бы, такая элементарная задача как установка текущей строки, имеет далеко не тривиальное решение.
Задача: реализовать две команды КурсорВверх и КурсорВниз, которые соответственно перемещают ТекущуюСтроку(Курсор) на предыдущую(следующую) строку.
Исходные данные: управляемая форма, ТЗОбъект — реквизит формы типа ТаблицаЗначений(конечно же правильней говорить о типе который моделирует Таблицу значений, а именно ДанныеФормыКоллекция), которая отображается на форме при помощи элемента формы ТЗОбъект типа Таблица(Не путать с одноименным реквизитом формы!). Предполагается, что ДанныеФормыКоллекция содержит некоторые данные, внесенные вручную или программно. Добавляем пару команд и пишем код, реализующей нужные действия, комментарии я дам ниже.
Теперь давайте разберемся что здесь к чему. Во первых следует уяснить, что ДанныеФормыКоллекция и Таблица формы это два совершенно разных объекта. Первый содержит данные, а второй является контейнером для их отображения. Элементы.ТЗОбъект.ТекущиеДанные предоставляет доступ к данным текущей строки и имеет тип ДанныеФормыЭлементКоллекции, он доступен только для чтения. С помощью метода Индекс(Элементы.ТЗОбъект.ТекущиеДанные) мы получаем индекс текущего элемента коллекции, далее осуществляем проверку выхода за границы коллекции. После чего с помощью метода ПолучитьИдентификатор() получаем идентификатор следующего(предыдущего) элемента коллекции и присваиваем его свойству Таблицы формы ТекущаяСтрока, которое как раз и содержит идентификатор текущей строки таблицы(на которую установлен курсор). Вот такая нетривиальная связь между вышеупомянутыми объектами.
Реализуем ещё несколько полезных команд: удаление текущего элемента, перемещение текущего элемента вверх(вниз). Несмотря на то, что эти команды являются стандартными(для объекта Таблица) и поддерживаются на уровне самой платформы, их альтернативная ПРОГРАММНАЯ реализация в некоторых случаях может быть очень полезна.
Если публикация помогла Вам справится с проблемой, решить задачу или расширить свои знания - поддержите автора.
Функция НайтиСтрокиДанныеФормыКоллекции(_Коллекция,Знач _Владелец) Экспорт
М = Новый Массив();
Для каждого Стр из _Коллекция Цикл
Если Стр.Владелец = _Владелец и Стр.Удалено=Ложь тогда
М.Добавить(Стр);
КонецЕсли;
КонецЦикла;
Возврат М;
КонецФункции
бвстрее чем (на клиенте):
Возврат Движения.НайтиСтроки(Новый Структура("Владелец,Удалено",_Владелец,Ложь));
в коллекции несколько сотен элементов.
Стоит ли переносить эту команду явно на сервер, если ДанныеФормыКоллекция представление ТЧ документа?
Стоит ли переносить эту команду явно на сервер, если ДанныеФормыКоллекция представление ТЧ документа?
Я бы исходил из такой логики: если в документах чаще всего много строк, то я бы перенес код обработки строк табличной части явно на сервер.
Если же строк, как правило, не много, тогда оставил бы на клиенте.
Это связано с тем, что в момент открытия формы на клиент передаются не все данные табличной части с сервера.
Если попробуете мышкой прокручивать табличную часть, то внизу (если включено отображение показателей производительности) увидите, что по мере прокрутки табличной части то и дело происходят вызовы сервера.
Т.е. происходит досчитывание данных с сервера.
Это такой механизм оптимизации. Зачем при открытии формы тащить все 1000 строк табличной части на клиента? Не так часто пользователи просматривают всю таблицу. При необходимости данные просто дочитываются в процессе работы пользователя (в процессе прокрутки).
В данном случае своим кодом вы буквально просматриваете всю табличную часть.
Для интереса посмотрите, сколько вызовов сервера происходит при выполнении Вашего кода. Предполагаю, что при первом (после открытия формы) выполнении производится около 10-20 вызовов. При повторном выполнении - ни одного (т.к. все данные уже прочитаны, уже все есть на клиенте).
Возможно, лучше сделать один явный вызов сервера, где обработать все строки.
Теоретически )
Есть проблема с установкой курсора на нужную строку в таблице управляемой формы (ТаблицаФормы - данные находятся в реквизите формы типа ТаблицаЗначений), проблема в том что для изменения некоторых полей(колонок) таблицы в коде прописано :
СтрИсх= ТаблицаФормы.ТекущаяСтрока;
ТаблицаЗначений=ДанныеФормыКоллекция.Выгрузить();
манипуляции с полученной ТаблицейЗначений
ДанныеФормыКоллекция.Загрузить(ТаблицаЗначений);
ТаблицаФормы.ТекущаяСтрока= СтрИсх ;
и курсор естественно перескакивает на 1 запись. (без манипуляций с ТаблицаФормы.ТекущаяСтрока), но к примеру он стоял на 2-й, тогда все не очень хорошо получается . Манипуляции со свойством ТаблицаФормы.ТекущаяСтрока=СтрИсх ни к чему не приводят, в этом случае курсора строки просто нет.
вот фрагмент кода на сервере:
НашаТаблицаЗначений = ГлавнаяТаблицаЗначений [ Элементы . ГлавнаяТаблицаЗначений . ТекущаяСтрока ] . НашаТаблицаЗначений . Выгрузить ( ) ;
СтрокаВсеОрганизации = НашаТаблицаЗначений . Найти ( ПоВсемПредставление ( ) , "Организация" ) ;
Если СтрокаВсеОрганизации < >Неопределено Тогда
Для каждого Колонка Из НашаТаблицаЗначений . Колонки Цикл
Если ТипЗнч ( СтрокаВсеОрганизации [ Колонка . Имя ] ) = Тип ( "Булево" ) и СтрокаВсеОрганизации [ Колонка . Имя ] Тогда
НашаТаблицаЗначений . ЗаполнитьЗначения ( Ложь , Колонка . Имя ) ;
СтрокаВсеОрганизации [ Колонка . Имя ] = Истина ;
КонецЕсли ;
КонецЦикла ;
КонецЕсли ;
поз = Элементы . НашаТаблицаЗначений . ТекущаяСтрока ;
ГлавнаяТаблицаЗначений [ Элементы . ГлавнаяТаблицаЗначений . ТекущаяСтрока ] . НашаТаблицаЗначений . Загрузить ( НашаТаблицаЗначений ) ;
Элементы . НашаТаблицаЗначений . ТекущаяСтрока = поз ;
Дело в том, что таблица, которая в форме, элемент формы, и таблица, которая в реквизите (ДанныеФормыКоллекция) - это разные таблицы. Это две разные коллекции.
Они, конечно, однозначно связаны между собой. То есть зная строку одной таблицы можно получить соответствующую ей строку другой таблицы.
Но эта связь не такая, как вы ее себе представляете:
ТекущаяСтрока у таблицы в форме это не индекс таблицы в реквизите.
Эти две таблицы связаны через Идентификатор.
У таблицы в форме идентификатор можно получить как раз через текущую строку:
У таблицы в реквизите (ДанныеФормыКоллекция) есть метод НайтиПоИдентификатору(Идентификатор), который вернет вам строку, соответствующую текущей строке в таблице формы.
В обратную сторону аналогично. Если вы знаете строку у таблицы в реквизите, вы можете найти (или установить курсор на) строку, соответствующую ей в таблице в форме.
У строки таблицы в реквизите (ДанныеФормыЭлементКоллекции) есть метод ПолучитьИдентификатор():
А у таблицы в форме - известное уже свойство ТекущаяСтрока:
Таким образом перед выполнением манипуляций вам нужно узнать, какая строка в таблице реквизита соответствует текущей строке в таблице формы. Каким-то образом запомнить, что это за строка.
После выполнения манипуляций в таблице реквизита вам нужно найти эту запомненную строку, получить ее идентификатор и таблице в форме сказать, что ее текущая строка должна быть равна этому идентификатору.
Для того чтобы найти строки таблицы значений, в 1с 8 используется два метода: Найти и НайтиСтроки. Первый предназначен для поиска одной строки, содержащей указанное значение. Второй для поиска всех строк, соответствующих указанному отбору. Разберем оба метода подробнее.
Метод Найти
Метод таблицы значений Найти, предназначен для поиска строки таблицы, содержащей указанное значение. Если строк содержащих значение будет несколько, будет найдена только первая из них. Эту особенность надо учитывать. Поиск осуществляется только на «равно». Синтаксис метода:
В первый параметр передаем значение, которое необходимо найти. Во втором можно через запятую указываем список колонок, в которых необходимо проводить поиск. Также можно не заполнять второй параметр, тогда поиск будет учитывать значения во всех колонках таблицы. В случае успешного поиска, метод вернет строку таблицы значений. В противном случае будет получено Неопределено.
Рассмотрим простой пример. У нас есть таблица значений с колонками: Номенклатура, Количество, Цена, Сумма. Найдем строку, содержащую значение 2 в колонке Количество или в колонке Цена.
После поиска, обязательно делаем проверку на Неопределено. Иначе, в случае не найденной строки, можно получить ошибку.
При изменении значений в найденной строке, изменяются и значения в самой таблице. Это логично, так как мы работаем непосредственно со строкой таблицы значений.
Метод НайтиСтроки
Метод НайтиСтроки предназначен для поиска всех строк таблицы значений, соответствующих указанному отбору. Синтаксис метода:
Параметры отбора — это структура, где ключ — имя колонки таблицы, а значение — значение, по которому будет осуществляться поиск в данной колонке. Поиск элементов осуществляется только на «равно». Данный метод возвращает массив найденных строк таблицы, либо пустой массив, если по данным условиям ничего не найдено.
Пример 2. Пусть у нас есть Таблица значений содержащаяся в переменной Таблица, у которой есть колонки Наименование и Код.
Как и в предыдущем методе, изменение значений в найденных строках ведет к изменению значений в таблице. Это не так очевидно, и происходит из-за того, что массив найденных строк содержит ссылки на строки исходной таблицы. Это работает и в обратную сторону. То есть, если вы измените значения в таблице, они изменятся и в найденных строках.
Другие способы найти строки таблицы значений
У рассмотренных методов есть свои недостатки. Основной, поиск только на равенство. Если вам необходимо использовать более сложные конструкции отбора строк, то можно обойти таблицу значений циклом, или передать ее в запрос.
Пример 3. Воспользуемся таблицей из самого первого примера. Обработаем строки, цена в которых находится в интервале от 100 до 1000.
Пример 4. Сделаем тоже самое при помощи запроса.
Стоит заметить, что данные найденные запросом никак не связаны с таблицей значений. Это стоит учитывать, если вам необходимо изменять исходные данные.
Дерево значений представляет из себя некую структуру с иерархией. Каждая строка имеет свойства «Родитель» и «Строки». У каждой строки может быть сколько угодно подчиненных строк. При этом такие операции как поиск, сортировка, подсчет итогов можно проводить с учетом уровня иерархии и подчиненных строк.
Программное создание дерева значений
Как уже упоминалось выше, каждая строка имеет свойство Строки , которое содержит коллекцию дочерних строк. И сам объект ДеревоЗначений имеет свойство Строки , которое содержит коллекцию строк верхнего уровня.
- Добавляет колонку в конец коллекции колонок дерева значений.
- Возвращаемое значение: КолонкаДереваЗначений .
Заполнить табличное поле на форме
Визуальное представление дерева значений на форме обеспечивает элемент Таблица .
Пример программного заполнения дерева значений для управляемых форм:
Результат выполнения запроса очень легко преобразовать в дерево значений, для этого нужно воспользоваться методом Выгрузить() и указать параметр ТипОбхода отличным от того, что стоит по умолчанию, т.е. ПоГруппировкам или ПоГруппировкамСИерархией .
Свернуть и развернуть строки дерева значений
Свернуть и развернуть дочерние строки элемента дерева значений можно с помощью методов Свернуть() и Развернуть() .
- Сворачивает узел в указанной строке дерева.
- ИдектификаторСтроки — идентификатор строки таблицы.
- Разворачивает узел в указанной строке дерева.
- ИдектификаторСтроки — идентификатор строки таблицы.
- СПодчиненными — определяет необходимость раскрытия подчиненных узлов.
- Получает коллекцию элементов дерева верхнего уровня.
- Возвращаемое значение: ДанныеФормыКоллекцияЭлементовДерева .
- Получает коллекцию дочерних элементов.
- Возвращаемое значение: ДанныеФормыКоллекцияЭлементовДерева .
Для представления в форме объектов конфигурации (справочники, документы и т.п.) существуют специальные типы данных:
- ДанныеФормыСтруктура — содержит набор свойств произвольного типа. Свойствами могут быть другие структуры, коллекции или структуры с коллекциями. Таким типом представляется, например, в форме СправочникОбъект .
- ДанныеФормыКоллекция — это список типизированных значений, похожий на массив. Доступ к элементу коллекции осуществляется по индексу или по идентификатору. Доступ по идентификатору может отсутствовать в некоторых случаях. Это обусловлено типом прикладного объекта, который представлен этой коллекцией. Идентификатором может быть любое целое число. Таким типом представляется, например, в форме табличная часть.
- ДанныеФормыСтруктураСКоллекцией — это объект, который представлен в виде структуры и коллекции одновременно. С ним можно обращаться как с любой из этих сущностей. Таким типом представляется, например, в форме набор записей.
- ДанныеФормыДерево — объект предназначен для хранения иерархических данных.
Прикладной объект представлен либо одним, либо несколькими элементами данных формы. Например, документ, содержащий табличную часть, будет представлен объектом типа ДанныеФормыСтруктура (собственно документ), которому подчинен объект типа ДанныеФормыКоллекция (табличная часть документа).
Удалить строку и очистить дерево значений
Поиск в дереве значений
Среди наиболее часто используемых методов стоит отметить метод Найти() коллекции строк дерева значений.
- Значение (обязательный, тип Произвольный ). Искомое значение.
- Колонки (необязательный, тип Строка ). Список имен колонок, в которых будет осуществляться поиск, разделенных запятыми. Если параметр не указан, поиск осуществляется по всем колонкам дерева. Значение по умолчанию — Пустая строка.
- ВключатьПодчиненные (необязательный, тип Булево ). Определяет, будут ли участвовать в поиске строки подчиненных коллекций (если таковые имеются). Если Истина — строки подчиненных коллекций участвуют в поиске. Значение по умолчанию — Ложь .
Метод осуществляет поиск значения в дереве в указанных колонках коллекции строк дерева значений. Возвращает строку (тип СтрокаДереваЗначений ), которая содержит искомое значение. Если значение не найдено, то возвращается значение Неопределено . Предназначен для поиска уникальных значений.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Читайте также: