Как устранить блокировки в 1С 7.7 при приходовании товаров сканером?

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

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

Почему возникают блокировки: механизм работы 1С 7.7

Для начала проанализируем ситуацию с точки зрения архитектуры базы данных. В 1С 7.7 (особенно в DBF-версии) блокировки происходят на уровне файлов или страниц. Основным «узким местом» является таблица журнала документов _1SJOURN.

Рассмотрим стандартный процесс: когда пользователь открывает форму документа и начинает сканировать штрихкоды, внешнее событие от сканера попадает в процедуру ОбработкаВнешнегоСобытия. Если код написан неоптимально, то при каждом успешном поиске товара программа может выполнять метод Записать(). В этот момент система инициирует транзакцию записи, которая накладывает исключительную блокировку на общую таблицу журнала. Пока товаровед сканирует сотни позиций подряд, другие пользователи не могут провести свои документы, так как они стоят в очереди на доступ к _1SJOURN.

В SQL-версии ситуация схожая, хотя блокировки там могут быть менее жесткими. Однако при длительном удержании транзакции внутри открытой формы документа (если кто-то «талантливо» вставил НачатьТранзакцию() в обработку сканера) работа всей организации парализуется.

Решение 1: Аудит кода обработки внешнего события

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

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

  1. Записать() — документ не должен сохраняться в базу данных после каждого «пика» сканера.
  2. НачатьТранзакцию() — использование явных транзакций при интерактивной работе со сканером категорически запрещено.
  3. Методы, вызывающие обновление всех открытых журналов (например, принудительный пересчет итогов или сложные запросы к базе).

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


Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
    // ОШИБКА: Попытка записи документа при каждом сканировании
    Если Событие = "BarCodeValue" Тогда
        Если НайтиТоварПоШтрихкоду(Данные) = 1 Тогда
            ДобавитьСтроку(ВыбранныйТовар);
            Записать(); // Вот она, причина блокировок!
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

Решение 2: Использование буферной обработки (Метод ТЗ)

Если специфика работы такова, что товаровед принимает огромные накладные часами, а риск потери данных при сбое компьютера велик, рассмотрим более продвинутый метод — рабочее место приемщика.

Суть метода заключается в разделении процесса ввода данных и процесса записи в базу. Мы создаем внешнюю обработку (.ert), в которой:

  1. Используется объект ТаблицаЗначений (ТЗ) для временного хранения отсканированных позиций.
  2. Сканирование идет в эту ТЗ, которая находится исключительно в оперативной памяти пользователя.
  3. Никакие таблицы базы данных (_1SJOURN, _1SSTRLINE) в процессе сканирования не блокируются.
  4. После завершения приемки программа одним быстрым циклом переносит данные из ТЗ в реальный документ и записывает его.

Посмотрим на пример логики переноса данных:


// В обработке накоплены данные в ТаблицеЗначений - тзПриемка
Процедура СоздатьДокументПриход()
    Док = СоздатьОбъект("Документ.ПоступлениеТоваров");
    Док.Новый();
    Док.ДатаДок = ТекущаяДата();
    
    тзПриемка.ВыбратьСтроки();
    Пока тзПриемка.ПолучитьСтроку() = 1 Цикл
        Док.НоваяСтрока();
        Док.Товар = тзПриемка.Товар;
        Док.Количество = тзПриемка.Количество;
        Док.Цена = тзПриемка.Цена;
    КонецЦикла;
    
    Док.Записать(); // Блокировка возникнет только на доли секунды
    Док.Провести();
КонецПроцедуры

Решение 3: Оптимизация интерфейса с помощью FormEx

Для платформы 7.7 существует замечательная внешняя компонента FormEx. Она позволяет реализовать работу со сканером более элегантно. Мы можем перехватывать события нажатия клавиш или внешние события без «мерцания» формы и лишних обращений к ядру 1С. Это снижает нагрузку на систему и делает интерфейс более отзывчивым, что косвенно помогает избежать длительных ожиданий и случайных блокировок при перерисовке списков.

Особенности внедрения онлайн-касс (54-ФЗ) в 7.7

Часто вопрос блокировок всплывает при попытке внедрить онлайн-кассы в старые системы. Разберем важный нюанс: при пробитии чека 1С 7.7 может «зависать», ожидая ответа от драйвера ККТ. Если в этот момент открыта транзакция документа, блокировка становится критичной.

Важные рекомендации по 54-ФЗ в 7.7:

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

Мы выяснили, что основной причиной блокировок в 1С 7.7 при работе со сканером является избыточное обращение к базе данных в момент обработки внешнего события. Для решения проблемы мы рекомендуем:

  1. Проверить код на наличие Записать() и НачатьТранзакцию() внутри циклов сканирования.
  2. Перейти на использование промежуточных Таблиц Значений для накопления данных перед сохранением документа.
  3. В случае работы с онлайн-кассами — выносить фискализацию за пределы основных транзакций записи документа.

Применяя эти подходы, вы сможете обеспечить комфортную работу товароведов и кассиров даже в высоконагруженных системах на базе «старой доброй» семерки.

← На главную