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