Почему отчеты не видят обороты по документам, созданным и проведенным программно из Excel?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: несоответствие периодов и чтение дат

Рассмотрим типовой сценарий, в котором создается документ и формируются его проводки:


ТекДок = Документы.ПутевойЛист.СоздатьДокумент();
// Заполнение реквизитов документа из файла
ТекДок.Дата = ДатаИзФайла;
ТекДок.Организация = ВыбраннаяОрганизация;
ТекДок.Записать(РежимЗаписиДокумента.Проведение);

В модуле объекта при этом определена стандартная обработка проведения:


Движения.Износ.Записывать = Истина;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
    Движение = Движения.Износ.Добавить();
    Движение.Период = Дата;
    Движение.СерияНоменклатуры = ВыборкаДетальныеЗаписи.Агрегат;
    Движение.Организация = Организация;
    Движение.ТранспортноеСредство = ВыборкаДетальныеЗаписи.ТС;
    Движение.Пробег = СпидометрВозвращения - СпидометрВыезда;
КонецЦикла;

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

Выясним причину такого поведения. В файле Excel дата часто хранится в кратком формате с двухзначным обозначением года, например 01.06.17. При чтении текстового представления ячейки платформа 1С:Предприятие преобразует такое значение буквально: 17-й год первого века нашей эры (01.06.0017 00:00:00). Визуально в стандартных интерфейсных формах при формате отображения даты без четырех цифр года запись может выглядеть вполне нормально, однако в базе данных период записи равен 0017 году. В отчете же пользователь задает период за 2017 год, куда движения первого века заведомо не попадают.

Разница между реальной таблицей и виртуальной таблицей оборотов

Проанализируем, почему движения видны в списке регистра, но скрыты в отчетах. В платформе 1С:Предприятие для регистров накопления существуют два типа таблиц:

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

Способы корректного считывания и нормализации даты из Excel

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

Способ 1. Использование свойства Value вместо Text при работе через COM-объект

При использовании COM-соединения с Excel (COMОбъект("Excel.Application")) обращение к свойству Ячейка.Text возвращает строку, отформатированную согласно настройкам листа. Вместо этого необходимо считывать свойство Ячейка.Value. Оно возвращает типизированное значение даты (тип OLE Date), которое автоматически транслируется платформой 1С в тип Дата с четырехзначным годом.

Способ 2. Программная нормализация двухзначного года

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


Функция НормализоватьДату(ИсходнаяДата)
    Год = Год(ИсходнаяДата);
    Если Год < 100 Тогда
        // Если год задан двумя цифрами, корректируем его в 2000-е года
        СкорректированныйГод = ?(Год < 50, 2000 + Год, 1900 + Год);
        Возврат Дата(СкорректированныйГод, Месяц(ИсходнаяДата), День(ИсходнаяДата), 
                    Час(ИсходнаяДата), Минута(ИсходнаяДата), Секунда(ИсходнаяДата));
    КонецЕсли;
    Возврат ИсходнаяДата;
КонецФункции

Способ 3. Использование встроенного объекта ТабличныйДокумент

Для прямого чтения файлов XLSX на стороне сервера без использования внешних COM-библиотек рекомендуется применять встроенный механизм платформы:


ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);

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

План экспресс-диагностики при скрытых движениях регистра

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

  1. Проверим полный формат даты: выполним вывод даты документа и периода движения в окне отладки или сообщением пользователю с явным указанием формата четырехзначного года: Формат(ТекДок.Дата, "ДФ=dd.MM.yyyy HH:mm:ss"). Это позволит сразу выявить 0017 год.
  2. Проверим признак активности: убедимся, что свойство Активность в записях регистра равно Истина. Неактивные записи исключаются из подсчета оборотов и остатков.
  3. Проверим типы измерений: при программном заполнении частой ошибкой является передача строки вместо ссылки на справочник. С помощью функции ТипЗнч() проверим, что в измерения записаны именно ссылки СправочникСсылка, а не примитивные строки из файла.
  4. Укажем режим проведения явно: при неоперативной загрузке документов прошлыми датами надежнее явно передавать режим проведения:
    
    ТекДок.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
    

Применение этих правил гарантирует, что созданные программно документы будут корректно регистрировать движения, а отчеты на базе СКД и запросов отразят правильные обороты за нужный расчетный период.

← На главную