Почему удваиваются количество и сумма при выгрузке итогов в 1С 7.7?

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

При разработке механизмов партионного учета или реализации контроля остатков в платформе 1С 7.7 программисты часто сталкиваются с загадочным поведением системы: программно полученные остатки по регистру ровно в два раза превышают реальные данные. Особенно часто это проявляется в типовых конфигурациях вроде «Торговля и Склад 9.2». Рассмотрим подробно, почему это происходит, как работает механизм временных расчетов и как правильно настроить фильтрацию, чтобы получать корректные цифры.

Причина №1: Специфика измерения «Фирма» и консолидированный учет

Разберем ситуацию, которая является наиболее вероятной причиной удвоения. В типовых конфигурациях 1С 7.7 регистры остатков (например, ПартииНаличие или ОстаткиТМЦ) спроектированы так, чтобы поддерживать учет как по каждой отдельной фирме (юридическому лицу), так и по «Компании» в целом.

Проанализируем механику записи в регистр: при проведении документа система часто делает два движения. Одно движение записывается с указанием конкретного значения измерения Фирма, а второе — с пустым значением этого измерения. Пустое значение интерпретируется системой как «движение по компании». Это сделано для того, чтобы отчеты по всей компании строились максимально быстро без необходимости суммирования данных по всем юридическим лицам.

Если в коде при использовании метода ВыгрузитьИтоги вы устанавливаете фильтр только по номенклатуре, но игнорируете измерение Фирма, система выгрузит в таблицу значений обе строки: и ту, что закреплена за фирмой, и ту, что относится к компании в целом. В результате при визуальном просмотре итогов вы увидите удвоенную сумму.

Решение: Всегда устанавливайте фильтр по конкретной фирме, если ваш учет предполагает разделение по юрлицам. Добавьте в ваш код следующую строку:


РегПар.УстановитьЗначениеФильтра("Фирма", ТекущаяФирма, 1); 
// Где 1 - это тип фильтра (равно)

Причина №2: Некорректное использование временного расчета

В 1С 7.7 работа с регистрами «задним числом» или из модуля проведения требует включения режима временного расчета. Метод ВременныйРасчет() сообщает системе, что мы планируем получать остатки не на текущую Точку Актуальности (ТА), а на произвольный момент времени.

Посмотрим на типичную ошибку в логике расчета. Если документ еще не проведен или перепроводится, важно понимать, на какой момент мы хотим получить итоги. Метод РассчитатьРегистрыНа(ТекущийДокумент()) рассчитывает остатки на момент времени непосредственно ПЕРЕД текущим документом.

Проанализируем фрагмент кода, используемый для получения итогов:


общРег = создатьОбъект("Регистры");
регПар = общРег.ПартииНаличие;
регПар.УстановитьЗначениеФильтра("Номенклатура", списФильтра, 2);

Если ТекущаяДата() < ПолучитьДатуТА() Тогда 
    РегПар.ВременныйРасчет();
    общРег.РассчитатьРегистрыНа(ТекущийДокумент());
КонецЕсли;

таблПровНалич = создатьОбъект("ТаблицаЗначений");
регПар.выгрузитьИтоги(таблПровНалич, 1, 1);

Здесь важно помнить: если вы используете УстановитьЗначениеФильтра, то при типе фильтра 2 (по списку значений) необходимо быть уверенным, что в списке списФильтра нет дублирующихся элементов. Если одна и та же номенклатура попадет в список дважды, метод ВыгрузитьИтоги может вернуть избыточные строки.

Причина №3: Состояние Точки Актуальности и индексов

Выясним причину, связанную с техническим состоянием базы данных. В практике работы с 1С 7.7 (особенно на DBF-версиях) бывает ситуация, когда таблицы итогов (файлы RG*.dbf) начинают содержать некорректные или дублирующиеся данные из-за сбоев, некорректных выключений или ошибок транзакций.

Как показывает опыт, перенос Точки Актуальности (ТА) на несколько дней вперед или назад с последующим возвратом часто «лечит» подобные симптомы. Это происходит потому, что при штатном перемещении ТА система инициирует пересчет итогов и физическую перезапись таблиц остатков, что устраняет «фантомные» дубли.

Рекомендация: Если код выглядит верным, а данные все равно двоятся, попробуйте выполнить процедуру «Пересчет итогов» в монопольном режиме через конфигуратор или программно переместите ТА.

Альтернативный подход: Использование запросов

Рассмотрим, почему профессиональные разработчики 1С 7.7 часто предпочитают объект Запрос прямому обращению к регистрам через ВыгрузитьИтоги. Механизм запросов в 7.7 более интеллектуален в плане агрегации данных.

  1. Автоматическое суммирование: Запрос автоматически схлопывает записи по измерениям, если они не указаны в группировках.
  2. Гибкость границ: В запросе легко установить границу расчета (например, По ТекущийДокумент).
  3. Производительность: На SQL-версиях запросы работают значительно эффективнее временных расчетов в цикле.

Пример реализации получения остатков через запрос:


ТекстЗапроса = "
|Период с (ТекущийДокумент) по (ТекущийДокумент);
|Номенклатура = Регистр.ПартииНаличие.Номенклатура;
|Количество = Регистр.ПартииНаличие.Количество;
|Сумма = Регистр.ПартииНаличие.СуммаУпр;
|Функция ОстКол = КонОст(Количество);
|Функция ОстСум = КонОст(Сумма);
|Группировка Номенклатура без групп;
|Условие (Номенклатура в списФильтра);
|";

Запрос = СоздатьОбъект("Запрос");
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
    Пока Запрос.Группировка(1) = 1 Цикл
        // Здесь мы гарантированно получим корректные остатки
        Сообщить(Запрос.Номенклатура.Наименование + " : " + Запрос.ОстКол);
    КонецЦикла;
КонецЕсли;

Подведем итоги

Если вы столкнулись с удвоением данных при выгрузке итогов регистра ПартииНаличие, выполните следующие шаги:

  1. Проверьте фильтр по Фирме. Это самая частая причина. В 7.7 итоги часто хранятся в двух разрезах (по фирме и без нее), и без явного указания фильтра ВыгрузитьИтоги выдаст оба разреза.
  2. Проверьте список фильтрации. Убедитесь, что в СписокЗначений, который вы передаете в фильтр, объекты не дублируются.
  3. Анализируйте временной расчет. Убедитесь, что ВременныйРасчет() вызывается до обращения к итогам и что расчет производится на нужную позицию (документ).
  4. Рассмотрите возможность использования Запроса. Это избавит вас от необходимости вручную обрабатывать технические особенности хранения итогов в таблицах 1С 7.7.

Соблюдение этих правил позволит вам создавать надежные механизмы контроля себестоимости и остатков, избегая досадных ошибок в расчетах.

← На главную