При работе в 1С:Предприятии 7.7 в связке с MS SQL Server (особенно версий 2008, 2012 и выше) разработчики и бухгалтеры иногда сталкиваются с неприятной ситуацией: оборотно-сальдовая ведомость (ОСВ) показывает корректные обороты и конечное сальдо, а в карточке счета или карточке субконто итоговые суммы отличаются. Разберем по шагам, почему возникает такое расхождение и как восстановить правильную работу отчетов.
Проанализируем типичный фрагмент программного кода формирования карточки счета:
Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ВыполнитьЗапрос(НачДата, КонДата, Счет, , , , "Проводка");
Ит.ВыбратьПериоды();
Пока Ит.ПолучитьПериод() = 1 Цикл
Опер = Ит.Операция;
// обработка движений и вывод строк
КонецЦикла;
Симптом ошибки заключается в том, что метод ПолучитьПериод() при итерации по проводкам доходит до определенной даты или документа и преждевременно прерывает цикл (возвращает 0), несмотря на то, что в базе есть последующие проводки. В результате отчет не учитывает часть оборотов и выводит неверное конечное сальдо.
Рассмотрим внутреннее устройство хранения и выборки данных в 1С 7.7:
_1SBKTTL и _1SBKTTLC), где хранятся свернутые остатки и обороты на начало расчетных периодов. Карточка счета с периодичностью "Проводка" обращается непосредственно к таблице проводок _1SENTRY и операциям _1SOPER._1SENTRY может некорректно обрабатывать сортировку по составному индексу DATE_TIME_DOCID, что приводит к внезапному закрытию курсора выборки.Первый шаг при обнаружении проблемы — восстановление целостности итогов и индексов средствами платформы:
Если проблема повторяется систематически, выполним процедуру полной перегрузки базы: выгрузим данные через конфигуратор (Администрирование > Выгрузка данных), создадим чистую базу данных в MS SQL Server и выполним загрузку данных в новую БД.
Чтобы исключить сбои курсоров из-за фрагментации данных, настроим в среде SQL Server Management Studio (SSMS) регулярное обслуживание таблиц базы данных:
_1SENTRY, _1SOPER, _1SJOURN, _1SBKTTL, _1SBKTTLC.UPDATE STATISTICS WITH FULLSCAN). Свежая статистика позволяет оптимизатору SQL корректно поддерживать открытые динамические курсоры 1С.Если специфика базы или интенсивный обмен в УРБД приводят к регулярным сбоям метода БухгалтерскиеИтоги с детализацией до проводки, изменим алгоритм выборки данных в отчете.
Вместо обхода периодов через объект БухгалтерскиеИтоги получим им только начальное сальдо, а детальные движения выберем стандартным методом ВыбратьПроводки():
// Получаем начальные остатки
Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ИспользоватьСубконто(ВидыСубконто.Контрагенты, ВыбКонтрагент, 2);
Ит.ВыполнитьЗапрос(НачДата, КонДата, ВыбСчет);
// Обходим проводки напрямую через объект Проводка/Операция
Пр = СоздатьОбъект("Проводка");
Пр.ВыбратьПроводки(НачДата, КонДата, ВыбСчет);
Пока Пр.ПолучитьПроводку() = 1 Цикл
// Проверяем соответствие условиям и выводим строку карточки
Док = Пр.Документ;
СуммаПроводки = Пр.Сумма;
КонецЦикла;
Также эффективным решением для высоконагруженных баз является перевод тяжелых аналитических отчетов (карточек счетов и субконто) на прямые SQL-запросы к таблицам _1SENTRY и _1SOPER с явной сортировкой ORDER BY DATE_TIME_DOCID. Это полностью исключает ошибки платформенных курсоров и в разы ускоряет построение отчетов.