Почему не совпадает количество в табличной части документа и в проводках в 1С 7.7 SQL?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Разберем логику работы формы и программную запись

Одной из самых простых и распространенных причин является человеческий фактор, наложенный на особенности платформы. Рассмотрим сценарий: пользователь открывает уже проведенный документ, меняет количество в строке и просто нажимает кнопку «Записать» (или закрывает документ с сохранением), но не нажимает «ОК» или «Провести». В некоторых конфигурациях это приводит к тому, что значения в табличной части (таблица DT* в SQL) обновляются, а движения (таблицы RG* или проводки) остаются старыми.

Для предотвращения таких ситуаций проанализируем программный код модуля формы документа. Проверьте наличие следующей установки в процедуре ПриОткрытии:


Процедура ПриОткрытии()
    // Устанавливаем режим обязательного перепроведения при сохранении изменения
    ПриЗаписиПерепроводить(1);
КонецПроцедуры

Важный момент: если этот флаг не установлен, пользователь может выйти из формы через клавишу Esc или крестик, подтвердив сохранение изменений, но система не инициирует процедуру ОбработкаПроведения. В результате в базе данных возникает несоответствие.

Проанализируем технические причины на уровне SQL Server

Если программная логика исключена, а проблема повторяется, следует обратить внимание на состояние базы данных на уровне SQL. 1С 7.7 — система достаточно старая, и ее взаимодействие с современными версиями SQL Server (2005, 2008, 2012 и выше) имеет свои особенности.

  1. Состояние индексов и статистики. При высокой интенсивности работы индексы таблиц могут фрагментироваться, а статистика — устаревать. Это приводит к тому, что SQL-сервер при выполнении запроса в момент проведения документа может «прочитать» не актуальные данные из кэша или использовать неверный план выполнения. Выясним причину через регламентные операции: необходимо регулярно выполнять REBUILD INDEX и UPDATE STATISTICS.
  2. Целостность базы данных. Выясним, нет ли физических повреждений таблиц. Для этого в SQL-консоли следует запустить команду проверки:

    DBCC CHECKDB ('Имя_Вашей_Базы') WITH NO_INFOMSGS, ALL_ERRORMSGS;

  3. Проблемы с bkend.dll. Для стабильной работы 1С 7.7 на новых версиях SQL часто используются патчи библиотеки bkend.dll. Ошибки в этих патчах или их несовместимость с текущей ОС могут приводить к сбоям в транзакциях. Разберем ситуацию: транзакция записи в ТЧ проходит успешно, а транзакция записи движений обрывается без вывода ошибки пользователю.

Рассмотрим влияние программного кода и округлений

Иногда корень проблемы кроется в самом алгоритме проведения. Рассмотрим подробнее, как данные попадают из экранной формы в регистры. Часто в коде ОбработкаПроведения выполняются дополнительные расчеты.

Проблема точности (Double Precision): В 1С 7.7 данные типа «Число» могут вести себя по-разному при передаче в SQL-запрос. Если в конфигурации нечетко определена точность переменной, число 33 может превратиться в 32.999999999 или 33.000000001. После округления в коде вы получите верный результат, но при прямой записи через SQL-запросы (если используются прямые запросы) или специфические компоненты может возникнуть разница в единицу младшего разряда.

Проанализируем пример типичной ошибки в процедуре проведения:


// В табличной части Количество = 33
КолВоДляПроводки = ТабличнаяЧасть.Количество * Коэффициент; 
// Если Коэффициент рассчитан неверно или имеет лишние знаки после запятой,
// результат может исказиться.
Регистр.Остатки.Количество = КолВоДляПроводки;

Чтобы избежать этого, всегда используйте явное округление при передаче данных в регистры:

Регистр.Остатки.Количество = Окр(ТабличнаяЧасть.Количество * Коэффициент, 3);

Выясним причину через отладку и тестирование

Если глюк «повторябельный», как в обсуждении на форуме, выполним следующие шаги по шагам:

  1. Изоляция строки: Создадим новый документ и добавим в него только ту позицию номенклатуры, на которой произошел сбой. Проведем. Если количество совпадает — проблема в объеме данных или в других строках документа.
  2. Тест «Туда-Сюда»: Как советовали участники форума, попробуйте изменить количество на заведомо другое (например, с 33 на 34), провести, а затем вернуть исходное значение. Если после этого данные выровнялись — это явный признак того, что в прошлый раз документ был записан без проведения.
  3. Проверка глобальных переменных: Проанализируем модуль документа. Если в ОбработкаПроведения используются переменные, объявленные в глобальном модуле, они могут быть изменены другими открытыми формами в процессе работы, что приведет к записи неверных данных в проводки.

Регламентное обслуживание для профилактики

Чтобы исключить «сюрпризы» в будущем, настроим регулярное обслуживание SQL-базы. Пользователи часто спрашивают: можно ли перестраивать индексы во время работы? Да, можно, но с оговорками. В версиях SQL Server Enterprise поддерживается режим ONLINE = ON, который не блокирует таблицы. В версии Standard могут возникать блокировки (Deadlocks), поэтому такие работы лучше проводить в часы минимальной нагрузки.

Рекомендуемый план обслуживания:

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

Мы выяснили, что расхождение количества — это чаще всего результат либо некорректного закрытия формы (без флага перепроведения), либо сбоев в индексах SQL-сервера. Реже — это ошибки округления в коде 1С. Для исправления ситуации достаточно один раз перепровести документ вручную, но для системного решения проблемы необходимо внедрить ПриЗаписиПерепроводить(1) и настроить планы обслуживания на стороне SQL Server.

← На главную