Как правильно заполнить сальдо на начало месяца в табличной части документа из регистра бухгалтерии

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

Заполнение начальных остатков по взаиморасчетам в документах — одна из самых частых задач при разработке механизмов автоматизации в 1С. В данной статье мы разберем, как получить долг арендатора из регистра бухгалтерии «Хозрасчетный», проанализируем типичные ошибки при работе с виртуальными таблицами и напишем оптимальный код для решения этой задачи.

Разбор типичных ошибок при получении сальдо

В процессе разработки программисты часто сталкиваются с рядом проблем, которые мешают корректному выполнению запроса. Рассмотрим основные из них, чтобы понимать, как их избежать:

  1. Запросы в цикле. Одной из главных ошибок является выполнение запроса к базе данных внутри цикла обхода строк или элементов справочника. Это приводит к чрезмерной нагрузке на сервер. Правильный подход — получить все данные одним запросом и затем распределить их по строкам.
  2. Неверное сравнение субконто. Ошибка Неверные параметры в операции сравнения возникает из-за того, что поле Субконто в регистре бухгалтерии имеет составной тип. При сравнении его напрямую со ссылкой на конкретный справочник (например, «Арендаторы»), система выдает ошибку. Необходимо использовать типизацию.
  3. Ошибки группировки. При использовании виртуальных таблиц часто возникают ошибки вида Поле не входит в группу. Это происходит, если в секции ВЫБРАТЬ указаны поля, которые не перечислены в СГРУППИРОВАТЬ ПО, и к ним не применены агрегатные функции (СУММА, МАКСИМУМ и др.).

Подготовка запроса для получения остатков

Для получения долга (дебиторской задолженности) на начало месяца лучше всего использовать виртуальную таблицу Остатки регистра бухгалтерии. Рассмотрим структуру оптимального запроса. Мы будем использовать конструкцию ВЫРАЗИТЬ, чтобы избежать проблем с типами данных в субконто.

Проанализируем пример кода запроса, который собирает данные по всем арендаторам сразу:


// Создаем массив ссылок арендаторов из табличной части для отбора
МассивАрендаторов = Объект.НачисленияУслуги.ВыгрузитьКолонку("Арендатор");

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ХозрасчетныйОстатки.Субконто1 КАК Арендатор,
    |	ХозрасчетныйОстатки.СуммаОстатокДт КАК ДолгНаНачало
    |ИЗ
    |	РегистрБухгалтерии.Хозрасчетный.Остатки(&Период, Счет = &Счет, &ВидыСубконто, Организация = &Организация) КАК ХозрасчетныйОстатки
    |ГДЕ
    |	ВЫРАЗИТЬ(ХозрасчетныйОстатки.Субконто1 КАК Справочник.Арендаторы) В (&МассивАрендаторов)";

Запрос.УстановитьПараметр("Период", НачалоМесяца(Объект.ПериодРегистрации));
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Хозрасчетный.РасчетыСПокупателями); // Укажите нужный счет
Запрос.УстановитьПараметр("Организация", Объект.Организация);
Запрос.УстановитьПараметр("МассивАрендаторов", МассивАрендаторов);

// Определение видов субконто для корректной работы виртуальной таблицы
МассивВидовСубконто = Новый Массив;
МассивВидовСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты);
Запрос.УстановитьПараметр("ВидыСубконто", МассивВидовСубконто);

РезультатЗапроса = Запрос.Выполнить();

Алгоритм заполнения табличной части

После получения результата запроса нам необходимо эффективно перенести данные в табличную часть документа. Для этого удобно использовать промежуточное хранение данных в Таблице Значений или соответствие (Map).

Рассмотрим пошагово процесс заполнения:

  1. Очистка или подготовка данных. Если мы заполняем документ «с нуля», очищаем таблицу. Если обновляем только долги — оставляем строки на месте.
  2. Выполнение запроса. Как показано выше, получаем данные по всем нужным контрагентам.
  3. Обход и сопоставление. Используем метод Найти или НайтиСтроки для сопоставления данных из регистра со строками документа.

Пример реализации процедуры на сервере:


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

Важные нюансы работы с периодами и итогами

Выясним причину, почему иногда остатки могут не совпадать с ОСВ (Оборотно-сальдовой ведомостью). При получении остатков на НачалоМесяца(Дата), 1С возвращает итоги на 00:00:00 первого числа месяца, не включая движения, сделанные в эту секунду. Если вы хотите получить остатки на конкретный документ, используйте объект Граница.

Пример использования границы:


МоментОстатков = Новый Граница(НачалоМесяца(Объект.ПериодРегистрации), ВидГраницы.Исключая);
Запрос.УстановитьПараметр("ДатаОстатков", МоментОстатков);

Резюмируем: для корректного заполнения сальдо в документе необходимо использовать виртуальную таблицу Остатки, передавать в параметры запроса список контрагентов для отбора и обязательно учитывать специфику работы с субконто через типизацию ВЫРАЗИТЬ. Это обеспечит высокую скорость работы системы и отсутствие ошибок при сравнении типов данных.

← На главную