Мина замедленного действия в методе 1С8 «НайтиСтроки», и ... разминирование.

В этой статье рассматривается небезопасная фича метода НайтиСтроки в 1с8 и описывается способ, позволяющий сделать вызов этого метода надежным.

 

Немногие знают, что метод НайтиСтроки в 1С работает не всегда ожидаемым образом.

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

Поэтому рекомендую добавить в глобальный модуль две функции НайтиСтроки и ПослеНайтиСтроки и вызывать вместо  М = ТЗ.НайтиСтроки(Структура) метод М = НайтиСтроки(ТЗ, Структура). Или последовательность: М= ТЗ.НайтиСтроки(Структура);  ПослеНайтиСтроки, ТЗ);

Параметр ТЗ во второй метод передается для совместимости с 1с80, где нет функции Владелец() у строки табличной части.

 

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

Если вы предложите более быстрый способ упорядочивания массива найденных строк, буду благодарен.

 

Функция НайтиСтроки(ТЗ, Структура) Экспорт

       М = ТЗ.НайтиСтроки(Структура);

       ПослеНайтиСтроки(М, ТЗ);

КонецФункции

 

Процедура ПослеНайтиСтроки(М, ТЗ = Неопределено) Экспорт

       Если М.Количество() = 0 Тогда

             Возврат;

       КонецЕсли;

       //Для совместимости с 1с80

       Если ТЗ = Неопределено Тогда

             ТЗ = М[0].Владелец();

       КонецЕсли;

      

       ТЗ2 = Новый ТаблицаЗначений();

       ТЗ2.Колонки.Добавить("Индекс");

       ТЗ2.Колонки.Добавить("Строка");

      

       Для Каждого Эл ИЗ М Цикл

             НСтр = ТЗ2.Добавить();

             НСтр.Индекс = ТЗ.Индекс(Эл);

             НСтр.Строка = Эл;

       КонецЦикла;

      

       ТЗ2.Сортировать("Индекс");

       М.Очистить();

       Для Каждого Стр2 ИЗ ТЗ2 Цикл

             М.Добавить(Стр2.Строка);

       КонецЦикла;

КонецПроцедуры

 

В приложенной обработке формируется массив строк, потом случайным образом перетасовывается, что эмулирует фичу метода НайтиСтроки, после чего порядок восстанавливается вызовом ПослеНайтиСтроки.

 

 

Скачать