При разработке отчетов и печатных форм программисты 1С часто сталкиваются с ситуацией, когда в результирующей таблице строки начинают дублироваться. На первый взгляд код вывода кажется абсолютно корректным, а простое сообщение через Сообщить() может вводить в заблуждение, скрывая повторяющиеся записи. Рассмотрим подробнее, почему возникает такое поведение и как правильно локализовать и устранить проблему.
Проанализируем основные факторы, приводящие к появлению повторяющихся данных:
ЛЕВОЕ СОЕДИНЕНИЕ или ПОЛНОЕ СОЕДИНЕНИЕ ключевому полю левой таблицы соответствует несколько записей в правой таблице, исходная строка размножается ровно столько раз, сколько совпадений найдено в подчиненном источнике.ПО (например, соединение справочников или документов без учета организации, подразделения или периода действия).СрезПоследних() приводит к тому, что в выборку попадает вся история изменений по объекту.Разберем по шагам, как можно модифицировать текст запроса для исключения дублирования строк.
1. Использование ключевого слова РАЗЛИЧНЫЕ
Если дублирование вызвано соединением и все поля строки полностью идентичны, можно применить модификатор РАЗЛИЧНЫЕ:
ВЫБРАТЬ РАЗЛИЧНЫЕ
Сотрудники.Код КАК Дкод,
Сотрудники.Наименование КАК ФИО
ИЗ
Справочник.Сотрудники КАК Сотрудники
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеДанные КАК ДопДанные
ПО Сотрудники.Ссылка = ДопДанные.Сотрудник
2. Группировка данных
Когда требуется исключить дубли по ключевым полям и свернуть числовые показатели, используем конструкцию СГРУППИРОВАТЬ ПО с агрегатными функциями:
ВЫБРАТЬ
Сотрудники.Код КАК Дкод,
Сотрудники.Наименование КАК ФИО,
МАКСИМУМ(ДопДанные.Значение) КАК ЗначениеПараметра
ИЗ
Справочник.Сотрудники КАК Сотрудники
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеДанные КАК ДопДанные
ПО Сотрудники.Ссылка = ДопДанные.Сотрудник
СГРУППИРОВАТЬ ПО
Сотрудники.Код,
Сотрудники.Наименование
3. Предварительная свертка во временных таблицах
Если подчиненная таблица содержит дублирующиеся ключи, правильным решением будет предварительно подготовить и сгруппировать данные во временной таблице до основного соединения:
ВЫБРАТЬ
ДопДанные.Сотрудник КАК Сотрудник,
МАКСИМУМ(ДопДанные.Период) КАК Период
ПОМЕСТИТЬ ВТ_АктуальныеДанные
ИЗ
РегистрСведений.ДополнительныеДанные КАК ДопДанные
СГРУППИРОВАТЬ ПО
ДопДанные.Сотрудник
;
ВЫБРАТЬ
Сотрудники.Код КАК Дкод,
Сотрудники.Наименование КАК ФИО
ИЗ
Справочник.Сотрудники КАК Сотрудники
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_АктуальныеДанные КАК ВТ
ПО Сотрудники.Ссылка = ВТ.Сотрудник
Посмотрим на частую ошибку заполнения параметров области. Вместо универсальной процедуры ЗаполнитьЗначенияСвойств() для объектов табличного документа платформой предусмотрен оптимизированный метод Заполнить() у коллекции параметров.
Разберем правильный алгоритм вывода строк в цикле:
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Инициализируем область заново или заполняем параметры напрямую
ОбластьСтрока.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
Важные рекомендации:
Ссылка), а не строковые или числовые коды (Код), так как коды могут дублироваться между разными группами или элементами.