В процессе работы с современными конфигурациями на базе 1С:Предприятие 8.3 (такими как ERP, Управление торговлей 11 или Комплексная автоматизация) программисты часто сталкиваются с проблемой «фантомных» или пустых строк в контактной информации партнеров. Это проявляется в отчетах, где один и тот же партнер начинает дублироваться, или в консоли запросов, когда при выборке номеров телефонов система выдает множество пустых значений. Рассмотрим детально, почему это происходит, как устроена архитектура хранения этих данных и какими методами можно очистить базу от лишних записей.
Прежде всего, нам необходимо проанализировать, как система хранит данные. В актуальных версиях БСП (Библиотеки стандартных подсистем) контактная информация (КИ) может располагаться либо в табличных частях справочников (например, Справочник.Партнеры.КонтактнаяИнформация), либо в отдельном регистре сведений КонтактнаяИнформация.
Важно понимать, что таблица контактной информации — это «универсальное хранилище». В ней вперемешку лежат строки разных типов: адреса, телефоны, адреса электронной почты и веб-страницы. У каждой строки есть реквизит Тип, который принимает значения из перечисления Перечисление.ТипыКонтактнойИнформации.
Выясним причину появления «пустых» телефонов. Когда мы пишем запрос к табличной части и выбираем поле НомерТелефона, мы получаем данные из всех строк. Но для строки, где хранится Юридический адрес, поле НомерТелефона по определению будет пустым. В результате в выборку попадает одна строка с заполненным телефоном и несколько строк с пустыми значениями (по количеству других видов КИ: адреса, email и т.д.).
Проанализируем типичную ошибку в запросе. Если вы видите дубли в отчетах, скорее всего, в соединении таблиц отсутствует фильтр по типу информации. Рассмотрим правильный подход к построению запроса. Чтобы получить только номера телефонов и избежать пустых строк, необходимо всегда накладывать условие на тип и вид контактной информации.
Пример правильного условия в запросе:
ГДЕ
ПартнерыКонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Телефон)
И ПартнерыКонтактнаяИнформация.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ТелефонПартнера)
Если же вам нужно вывести телефон в общем списке партнеров, используйте Левое соединение, но обязательно с вложенным запросом, в котором уже установлены все фильтры. Это позволит избежать «размножения» строк основного объекта в результате запроса.
Если вы убедились, что в самой базе данных действительно содержатся лишние записи (например, два телефона вместо одного, хотя настройками запрещено добавление нескольких номеров), их нужно удалить программно. Такая ситуация часто возникает при некорректном импорте данных или работе внешних обработок, которые записывают данные в режиме ОбменДанными.Загрузка = Истина, обходя стандартные проверки формы.
Рассмотрим по шагам алгоритм удаления лишних строк из табличной части объекта:
ПолучитьОбъект().КонтактнаяИнформация.Удалить().Посмотрим на пример кода, который решает эту задачу:
// Пример очистки пустых телефонов у партнера
Для Каждого СтрокаКИ Из ОбъектПартнер.КонтактнаяИнформация Цикл
// Если это тип "Телефон", но номер не заполнен и представление пустое
Если СтрокаКИ.Тип = Перечисления.ТипыКонтактнойИнформации.Телефон
И ПустаяСтрока(СтрокаКИ.НомерТелефона)
И ПустаяСтрока(СтрокаКИ.Представление) Тогда
// Индекс строки для удаления
Индекс = ОбъектПартнер.КонтактнаяИнформация.Индекс(СтрокаКИ);
ОбъектПартнер.КонтактнаяInformation.Удалить(Индекс);
Попытка
ОбъектПартнер.Записать();
Сообщить("Пустая запись удалена для: " + ОбъектПартнер.Наименование);
Исключение
Сообщить("Ошибка записи: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Важный нюанс: при удалении строк в цикле "Для каждого" индекс коллекции может сместиться. Безопаснее обходить коллекцию с конца или сначала собрать индексы в массив, а потом произвести удаление.
В современных конфигурациях 1С данные контактной информации хранятся в структурированном виде (XML или JSON) в реквизитах ЗначенияПолей или Значение. Посмотрим на ситуацию подробнее: иногда реквизит Представление может быть пустым, но скрытое XML-поле заполнено данными. При открытии карточки партнера система считывает XML и восстанавливает «пустой» номер в интерфейсе.
Для корректной очистки рекомендуем использовать программный интерфейс БСП. Обратите внимание на модуль УправлениеКонтактнойИнформацией. Проанализируем пример использования этого модуля для корректного удаления или изменения данных:
// Использование встроенных функций БСП для очистки
ВидКИ = Справочники.ВидыКонтактнойИнформации.ТелефонПартнера;
УправлениеКонтактнойИнформацией.УдалитьКонтактнуюИнформацию(ОбъектПартнер, ВидКИ);
ОбъектПартнер.Записать();
Этот метод более безопасен, так как он корректно обрабатывает данные как в табличных частях, так и в регистрах сведений, соблюдая целостность структуры КИ.
Если вы не хотите писать код, разберем способ решения проблемы через стандартные инструменты. В большинстве типовых конфигураций есть обработка Групповое изменение реквизитов. Она позволяет работать с табличными частями.
Пошаговый алгоритм действий:
Контактная информация.Вид (выберите нужный вид телефона).Контактная информация.Внимание: Перед выполнением таких операций обязательно сделайте резервную копию информационной базы, так как групповое удаление строк необратимо.
Мы выяснили, что проблема пустых строк часто является следствием особенностей архитектуры 1С. Основная причина дублей в отчетах — это отсутствие фильтрации по реквизиту Тип или Вид в запросах. Если же дубли реальные, мы рекомендуем использовать методы программной очистки через объектную модель с учетом специфики полей БСП (ЗначенияПолей).
Для предотвращения подобных проблем в будущем, проанализируйте настройки в справочнике Виды контактной информации. Убедитесь, что для вида «Телефон партнера» установлена настройка «Запретить ввод нескольких строк». Если настройка установлена, но дубли появляются — ищите внешние обработки или обмены данными, которые записывают информацию в обход стандартных процедур проверки.