Почему при сканировании штрихкода в 1С возникает ошибка даты SQL и как это исправить?

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

При работе с торговым оборудованием в среде 1С:Предприятие 8 (особенно на обычных формах, таких как в УТ 10.3) программисты часто сталкиваются с загадочной ошибкой: при сканировании штрихкода в форме списка документов система выдает сообщение: «Ошибка в значении типа "Дата", Дата "10.11.0815" не может быть записана в базу MS SQL Server с нулевым смещением дат». При этом точки останова не срабатывают, а замер производительности не показывает проблемных мест в коде.

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

Разберем причину возникновения ошибки

Давайте проанализируем, что происходит в системе в момент нажатия кнопки сканера. Большинство сканеров по умолчанию работают в режиме эмуляции клавиатуры. Это означает, что для операционной системы и для 1С сканер — это просто очень быстрый пользователь, который за доли секунды вводит последовательность цифр и нажимает Enter.

Если в момент сканирования фокус (курсор) в форме списка документов установлен на колонку с типом Дата, платформа 1С интерпретирует входящий поток символов как попытку ручного ввода даты для поиска или фильтрации. Рассмотрим пример штрихкода 4601546.... Платформа берет первые цифры и пытается подставить их в маску даты. В итоге «46» превращается в день, «01» в месяц, а последующие цифры — в год. Если год получается меньше 1753 (минимальная дата для MS SQL Server при нулевом смещении), СУБД отвергает запрос, и мы получаем критическую ошибку еще до того, как управление передается в код 1С.

Важный нюанс: Почему не срабатывает отладка? Ошибка происходит на уровне ядра платформы и взаимодействия с драйвером базы данных при попытке динамического считывания данных (позиционирования в списке). Код 1С в процедуре ОбработкаВнешнегоСобытия просто не успевает инициализироваться.

Решение 1: Правильное подключение торгового оборудования (ТО)

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


Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    // Регистрируем форму как клиента торгового оборудования
    Если ПолучитьСерверТО() <> Неопределено Тогда
        ПолучитьСерверТО().ПодключитьКлиента(ЭтаФорма);
    КонецЕсли;
КонецПроцедуры

Процедура ПриЗакрытии()
    // Не забываем отключать клиента при закрытии
    Если ПолучитьСерверТО() <> Неопределено Тогда
        ПолучитьСерверТО().ОтключитьКлиента(ЭтаФорма);
    КонецЕсли;
КонецПроцедуры

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


Процедура ВнешнееСобытие(Источник, Событие, Данные)
    Если Не ВводДоступен() Тогда
        Возврат;
    КонецЕсли;

    // Передаем данные на сервер ТО для идентификации штрихкода
    Если ПолучитьСерверТО() <> Неопределено Тогда
        СтруктураШтрихкода = ПолучитьСерверТО().ОбработатьВнешнееСобытие(Событие, Данные, ЭтаФорма);
        Если СтруктураШтрихкода.Результат Тогда
            // Здесь пишем логику поиска документа по штрихкоду
            Штрихкод = СтруктураШтрихкода.Штрихкод;
            НайтиИПровестиДокумент(Штрихкод);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Решение 2: Перевод сканера в режим COM-эмуляции

Самый надежный способ избежать «ввода даты» в поля формы — отказаться от клавиатурного режима. Мы рекомендуем перевести сканер в режим Native POS (COM-эмуляция). В этом случае данные от сканера будут поступать напрямую в порт, и 1С будет генерировать ВнешнееСобытие независимо от того, где стоит курсор и какая колонка активна. Это полностью исключает конфликт с типами данных в полях ввода.

Решение 3: Управление фокусом и быстрым поиском

Если перевод в COM-режим невозможен, проанализируем поведение формы. Ошибка возникает только тогда, когда активная колонка имеет тип Дата. Мы можем программно изменить текущую колонку при открытии формы, чтобы «удар» штрихкода приходился на текстовое поле (например, «Номер» или «Комментарий»).

  1. Откройте форму списка документа в конфигураторе.
  2. Найдите элемент ТабличноеПоле.
  3. В процедуре ПриОткрытии установите ЭлементыФормы.Список.ТекущаяКолонка = ЭлементыФормы.Список.Колонки.Номер;.

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

Решение 4: Исправление смещения дат в MS SQL Server

Ситуация с датой 0815 года критична только для баз с нулевым смещением. В 1С существует возможность установить смещение 2000 лет. В этом случае минимальная дата 01.01.0001 хранится в SQL как 01.01.2001. Это делает базу более устойчивой к некорректному вводу дат (любая дата превращается в значение > 2000 года, что допустимо для SQL).

Если ваша база уже создана с нулевым смещением и она имеет большой объем, просто поменять настройку в консоли 1С нельзя — данные станут некорректными. Рассмотрим пример SQL-скрипта, который позволяет массово обновить все даты в таблицах при переходе на смещение 2000 (выполнять только после резервного копирования!):


DECLARE TablesAndFields CURSOR FOR 
SELECT objects.name AS Tablename, columns.name AS columnname 
FROM dbo.sysobjects AS objects 
LEFT JOIN dbo.syscolumns AS columns ON objects.id = columns.id 
WHERE objects.xtype = 'U' AND columns.xtype = 61 -- 61 = datetime

OPEN TablesAndFields
DECLARE @TableName AS VARCHAR(100)
DECLARE @ColumnName AS VARCHAR(100)

FETCH NEXT FROM TablesAndFields INTO @TableName, @ColumnName
WHILE @@FETCH_STATUS = 0
BEGIN
    -- Прибавляем 2000 лет к каждой дате во всех таблицах
    EXEC ('UPDATE ' + @TableName + ' SET ' + @ColumnName + ' = DATEADD(year, 2000, ' + @ColumnName + ')')
    FETCH NEXT FROM TablesAndFields INTO @TableName, @ColumnName
END

CLOSE TablesAndFields
DEALLOCATE TablesAndFields

После выполнения скрипта необходимо в свойствах базы в консоли серверов 1С также изменить параметр Year Offset на 2000.

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

Проанализировав ситуацию, мы выяснили, что ошибка «10.11.0815» — это результат работы быстрого поиска платформы в колонке типа Дата. Для исправления ситуации мы рекомендуем:

Соблюдение этих правил обеспечит стабильную работу сканеров штрихкода в любых типовых и самописных конфигурациях на платформе 1С.

← На главную