Заполнение начальных остатков по взаиморасчетам в документах — одна из самых частых задач при разработке механизмов автоматизации в 1С. В данной статье мы разберем, как получить долг арендатора из регистра бухгалтерии «Хозрасчетный», проанализируем типичные ошибки при работе с виртуальными таблицами и напишем оптимальный код для решения этой задачи.
В процессе разработки программисты часто сталкиваются с рядом проблем, которые мешают корректному выполнению запроса. Рассмотрим основные из них, чтобы понимать, как их избежать:
Неверные параметры в операции сравнения возникает из-за того, что поле Субконто в регистре бухгалтерии имеет составной тип. При сравнении его напрямую со ссылкой на конкретный справочник (например, «Арендаторы»), система выдает ошибку. Необходимо использовать типизацию.Поле не входит в группу. Это происходит, если в секции ВЫБРАТЬ указаны поля, которые не перечислены в СГРУППИРОВАТЬ ПО, и к ним не применены агрегатные функции (СУММА, МАКСИМУМ и др.).Для получения долга (дебиторской задолженности) на начало месяца лучше всего использовать виртуальную таблицу Остатки регистра бухгалтерии. Рассмотрим структуру оптимального запроса. Мы будем использовать конструкцию ВЫРАЗИТЬ, чтобы избежать проблем с типами данных в субконто.
Проанализируем пример кода запроса, который собирает данные по всем арендаторам сразу:
// Создаем массив ссылок арендаторов из табличной части для отбора
МассивАрендаторов = Объект.НачисленияУслуги.ВыгрузитьКолонку("Арендатор");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ХозрасчетныйОстатки.Субконто1 КАК Арендатор,
| ХозрасчетныйОстатки.СуммаОстатокДт КАК ДолгНаНачало
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет = &Счет, &ВидыСубконто, Организация = &Организация) КАК ХозрасчетныйОстатки
|ГДЕ
| ВЫРАЗИТЬ(ХозрасчетныйОстатки.Субконто1 КАК Справочник.Арендаторы) В (&МассивАрендаторов)";
Запрос.УстановитьПараметр("Период", НачалоМесяца(Объект.ПериодРегистрации));
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.РасчетыСПокупателями); // Укажите нужный счет
Запрос.УстановитьПараметр("Организация", Объект.Организация);
Запрос.УстановитьПараметр("МассивАрендаторов", МассивАрендаторов);
// Определение видов субконто для корректной работы виртуальной таблицы
МассивВидовСубконто = Новый Массив;
МассивВидовСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
Запрос.УстановитьПараметр("ВидыСубконто", МассивВидовСубконто);
РезультатЗапроса = Запрос.Выполнить();
После получения результата запроса нам необходимо эффективно перенести данные в табличную часть документа. Для этого удобно использовать промежуточное хранение данных в Таблице Значений или соответствие (Map).
Рассмотрим пошагово процесс заполнения:
Найти или НайтиСтроки для сопоставления данных из регистра со строками документа.Пример реализации процедуры на сервере:
&НаСервере
Процедура ЗаполнитьДолгиНаСервере()
// 1. Собираем список арендаторов
СписокАрендаторов = Объект.НачисленияУслуги.ВыгрузитьКолонку("Арендатор");
// 2. Настраиваем запрос (используем таблицу Остатки)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ХозрасчетныйОстатки.Субконто1 КАК Арендатор,
| ХозрасчетныйОстатки.СуммаОстатокДт КАК Долг
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(&ДатаОстатков, Счет = &Счет, , Организация = &Организация) КАК ХозрасчетныйОстатки
|ГДЕ
| ХозрасчетныйОстатки.Субконто1 В(&СписокАрендаторов)";
Запрос.УстановитьПараметр("ДатаОстатков", НачалоМесяца(Объект.ПериодРегистрации));
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.СчетаКПолучениюЗаАренды);
Запрос.УстановитьПараметр("Организация", Объект.Организация);
Запрос.УстановитьПараметр("СписокАрендаторов", СписокАрендаторов);
ТаблицаДолгов = Запрос.Выполнить().Выгрузить();
ТаблицаДолгов.Индексы.Добавить("Арендатор"); // Индексируем для быстрого поиска
// 3. Заполняем данные в табличной части
Для Каждого СтрокаТЧ Из Объект.НачисленияУслуги Цикл
ПараметрыПоиска = Новый Структура("Арендатор", СтрокаТЧ.Арендатор);
НайденныеСтроки = ТаблицаДолгов.НайтиСтроки(ПараметрыПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаТЧ.Долг = НайденныеСтроки[0].Долг;
Иначе
СтрокаТЧ.Долг = 0;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Выясним причину, почему иногда остатки могут не совпадать с ОСВ (Оборотно-сальдовой ведомостью). При получении остатков на НачалоМесяца(Дата), 1С возвращает итоги на 00:00:00 первого числа месяца, не включая движения, сделанные в эту секунду. Если вы хотите получить остатки на конкретный документ, используйте объект Граница.
Пример использования границы:
МоментОстатков = Новый Граница(НачалоМесяца(Объект.ПериодРегистрации), ВидГраницы.Исключая);
Запрос.УстановитьПараметр("ДатаОстатков", МоментОстатков);
Резюмируем: для корректного заполнения сальдо в документе необходимо использовать виртуальную таблицу Остатки, передавать в параметры запроса список контрагентов для отбора и обязательно учитывать специфику работы с субконто через типизацию ВЫРАЗИТЬ. Это обеспечит высокую скорость работы системы и отсутствие ошибок при сравнении типов данных.