Реклама на этом месте
Форум 1С
Форум 1С
Программистам. Бухгалтерам. Администраторам. Пользователям
Задай вопрос - получи решение проблемы. Без троллинга и флуда.
26 Сен 2020, 07:17
МультиВход
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?
 
collapse

Автор Тема: Как удалить элементы коллекции?  (Прочитано 10245 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн MuI_I_Ika

  • Гончаров Михаил
  • Администратор
  • *****
  • Сообщений: 7104
  • РЕПУТАЦИЯ: 844
  • КПД: 12%
  • Регистрация: 2012-08-15
    • Skype: MuI_I_Ika
  • Сайт: 
  • Профессия: Программист 1С

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


Первое что приходит обычно в голову - это перебрать коллекцию циклом, и при соблюдении условия удалить элемент методом


Удалить();
Однако, такой подход зачастую сопряжен с определенными трудностями. Ну например, для обхода коллекции вы решили использовать цикл:
Для Каждого Элемент из ТаблицаЗначений Цикл


КонецЦикла;
Что произойдет в том случае если вы в середине выполнения цикла удалите какой-либо элемент из этой же коллекции? Программа просто пропустит элемент, следующий за удаленным. Это произойдет из-за того, что обход осуществляется по индексу элементов. После удаления индекс следующего элемента уменьшится. А программа будет обращаться к индексу следующему за удаленным (тому который был до момента удаления).


Если представить схематически то получаются две картины до удаления и после удаления:


1          1
2          2 (был 3)
3          3 (был 4)
4


Произошло удаление 2-го элемента. Элементы 3 и 4 сместились в позиции 2 и 3. А программа уже обработала 2-ой элемент и будет обращаться к 3-му.


Если же удалить 3-ий элемент, то программа попытается обратиться к 4-му и возникнет ошибка.


Такая же проблема нас ожидает при использовании цикла


Для к = 0 по ТаблицаЗначений.Количество()-1 Цикл


КонецЦикла;
Дело в том, что для оптимизации производительности количество элементов коллекции вычисляется один раз в начале выполнения цикла, и в дальнейшем уже не пересчитывается. Соответственно и получаем проблему такую же как и в первом случае.


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


Вот как будет выглядеть код:


     НайденныеСсылки = НайтиПоСсылкам(МассивСсылок);

//почистим от метаданных исключений
МассивНаУдаление = Новый Массив;


Для каждого Элемент из НайденныеСсылки Цикл

Для каждого ЭлементИсключение из ОбъектыИсключения Цикл
Если Элемент.Метаданные = Метаданные.НайтиПоПолномуИмени(ЭлементИсключение.ТипОбъекта) Тогда
МассивНаУдаление.Добавить(Элемент);
КонецЕсли;
КонецЦикла;

КонецЦикла;

Для каждого Элемент из МассивНаУдаление Цикл

НайденныеСсылки.Удалить(Элемент);

КонецЦикла;


Второй вариант удаления строк по условию - это перебор коллекции (в данном случае таблицы значений) с конца. То есть сначала вы обрабатываете самый последний элемент, а конце самый первый. Таким образом программа не собъется со счету, если вы удалите один из элементов посередине, поскольку она будет переходить к элементам с меньшим индексом.


Пример кода:


	Для Индекс = -ТаблицаЗначений.Количество()+1 По 0 Цикл

Если ТаблицаЗначений[-Индекс].Количество = 0 Тогда
ТаблицаЗначений.Удалить(-Индекс);
КонецЕсли;

КонецЦикла;


Отмечу, что 1С не поддерживает в цикле Для По переход от большего элемента к меньшему, поэтому здесь применена небольшая хитрость - использование отрицательных чисел.


Третий вариант - использование цикла Пока. Пример кода:


Индекс = ТаблицаКонтрагентов.Количество() - 1; 
Пока Индекс >= 0 Цикл
Если ТаблицаКонтрагентов[Индекс].СуммаЗадолженности = 0 Тогда
ТаблицаКонтрагентов.Удалить(Индекс);
КонецЕсли;

Индекс = Индекс - 1;


КонецЦикла;


 

Не удается удалить "Реализацию ТМЗ и услуги" и "Счет фактуру"

Автор TahibРаздел Конфигурирование, программирование в "1С - Предприятие 8"

Ответов: 7
Просмотров: 954
Последний ответ 05 Авг 2019, 07:58
от alexandr_ll
Не активны кнопки "Добавить" и "Удалить" дополнительные строки в отчете по НДС

Автор kiksiРаздел Конфигурирование, программирование в "1С - Предприятие 8"

Ответов: 2
Просмотров: 2080
Последний ответ 25 Янв 2018, 14:50
от kiksi
Как удалить зависшее фоновое задание [фоновые задания] [фоновое задание] [снять зависший сеанс]

Автор MuI_I_IkaРаздел Администрирование 1с

Ответов: 0
Просмотров: 38274
Последний ответ 16 Июл 2014, 19:48
от MuI_I_Ika
Внимание вопрос: Как удалить "выемка ДС из кассы"?

Автор Unknown29rusРаздел Пользователям "1С - Предприятие 8"

Ответов: 5
Просмотров: 8869
Последний ответ 20 Май 2014, 11:24
от 790619540
Удалить запись из справочника "Сотрудники" уволенного

Автор Alex56Раздел Пользователям "1С - Предприятие 8"

Ответов: 1
Просмотров: 4776
Последний ответ 02 Фев 2014, 21:37
от LordWizard

* Живое общение

Не устроил ответ?

Зарегистрируйся и задай свой вопрос. Живое общение приносит результат намного быстрее.


Зарегистрироваться

* Реклама

* Поиск

* Последние задачи на разработку (фриланс)

* Реклама

* Последние вакансии

* Топ 10 авторов за месяц

Геннадий ОбьГЭС Геннадий ОбьГЭС
67 Сообщений
oooo800
39 Сообщений
LexaK
31 Сообщений
Дмитрий Джей Дмитрий Джей
29 Сообщений
IL2016
28 Сообщений
antoneus antoneus
24 Сообщений
DmitriyF DmitriyF
17 Сообщений
Ann_
16 Сообщений
мадам брошкина
13 Сообщений
illiona
10 Сообщений

* Кто онлайн

  • Точка Гостей: 281
  • Точка Скрытых: 0
  • Точка Пользователей: 4
  • Точка Сейчас на форуме:

* Облако тэгов

* Форум 1С с мобильного

* Инструменты

* Дополнительно

Поиск

 
SimplePortal 2.3.5 © 2008-2012, SimplePortal