Импорт данных из Excel — это стандартная задача для разработчика 1С, однако работа с датами часто преподносит сюрпризы. Бывает так, что текстовые поля и числа загружаются без проблем, а даты либо остаются пустыми, либо вызывают ошибки преобразования типов. В этой статье мы подробно разберем, почему так происходит, и рассмотрим несколько эффективных способов корректного импорта дат, а также обработку для простого импорта данных.
Самая распространенная ошибка заключается в попытке прочитать дату как текст. Когда мы используем свойство Текст, 1С получает строковое представление, которое зависит от настроек форматирования ячейки в Excel. Чтобы избежать этого, нам необходимо прочитать файл в режиме получения значений. Рассмотрим, как это реализовать программно, используя шаблон простой обработки загрузки из excel.
Для начала проанализируем ситуацию: если мы читаем ТабличныйДокумент без указания способа чтения (кстати, пригодится этот шаблон для 1С8 по Excel), он может интерпретировать все данные как строки. Правильный подход — использовать СпособЧтенияЗначенийТабличногоДокумента.Значение.
ТабДок = Новый ТабличныйДокумент;
// Читаем файл, указывая, что нам нужны именно значения (типизированные данные)
ТабДок.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Для НомерСтроки = 2 По ТабДок.ВысотаТаблицы Цикл
// Обращаемся к области напрямую по номеру строки и колонки
ЗначениеИзЯчейки = ТабДок.Область(НомерСтроки, 7).Значение;
Если ТипЗнч(ЗначениеИзЯчейки) = Тип("Дата") Тогда
ЭлементЗаявка.ДатаОплаты = ЗначениеИзЯчейки;
Иначе
// Если в ячейке не дата, можно попробовать преобразовать текст
ТекстЯчейки = ТабДок.Область(НомерСтроки, 7).Текст;
// Здесь можно вызвать функцию парсинга
КонецЕсли;
КонецЦикла;
При таком подходе 1С сама попытается распознать формат даты Excel и конвертировать его во внутренний тип Дата. Подобные механизмы реализованы в загрузке данных из табличного документа.
Если метод чтения значений не помог (например, в Excel даты записаны «криво» или в разных форматах), нам придется разбирать строку вручную. Выясним причину ошибки: функция Дата() в 1С ожидает строку в строго определенном формате ГГГГММДДччммсс или ДД.ММ.ГГГГ (в зависимости от версии платформы и контекста).
Рассмотрим вариант ручного разбора строки, если дата приходит в формате "25.12.2023":
Функция ПреобразоватьСтрокуВДату(ДатаСтрокой)
// Очищаем строку от лишних пробелов
ДатаСтрокой = СокрЛП(ДатаСтрокой);
// Используем разделение строки по точкам
МассивЧастей = СтрРазделить(ДатаСтрокой, ".");
Если МассивЧастей.Количество() = 3 Тогда
// Собираем строку в формате, который понимает конструктор Дата(Год, Месяц, День)
Попытка
Возврат Дата(МассивЧастей[2], МассивЧастей[1], МассивЧастей[0]);
Исключение
Возврат '00010101'; // Пустая дата в случае ошибки
КонецПопытки;
КонецЕсли;
Возврат '00010101';
КонецФункции
Важный момент: если вы используете конструктор Дата("20231225"), помните, что он крайне чувствителен к количеству символов. Если время не указано, 1С может выдать ошибку, поэтому иногда стоит добавлять " 00:00:00" к строке.
Вы могли заметить, что если в Excel изменить формат ячейки с даты на «Общий», дата превращается в число (например, 45150). Это так называемый Serial Date — количество дней, прошедших с 30 декабря 1899 года. Если при импорте вы получаете именно такое число, его нужно преобразовать в дату 1С по специальной формуле.
Разберем, как это сделать:
ЧислоИзExcel = 45150; // Пример значения из файла
ДатаНачала = '18991230'; // Базовая дата Excel
КоличествоСекундВСутках = 86400;
Результат = ДатаНачала + (ЧислоИзExcel * КоличествоСекундВСутках);
// Результат будет соответствовать реальной дате из Excel
Этот способ выручает, когда файл Excel сформирован сторонней системой и стандартные средства ТабличногоДокумента не справляются с определением типов.
Если файл Excel имеет простую табличную структуру (первая строка — заголовки, далее — данные), мы можем воспользоваться ПостроителемЗапроса. Этот метод позволяет быстро выгрузить данные из файла в ТаблицуЗначений, где типы колонок будут определены автоматически.
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
Построитель.Выполнить();
ТаблицаДанных = Построитель.Результат.Выгрузить();
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
// Теперь мы работаем с колонками Таблицы Значений
НоваяДата = СтрокаДанных.Дата_Оплаты; // Имя колонки берется из заголовка Excel
КонецЦикла;
ПустаяСтрока() или сравнением с Неопределено.Область().Значение. Часто там оказывается Число или Строка с невидимыми символами.СокрЛП() ко всем строковым значениям перед их конвертацией в дату.Проанализировав все способы, можно сделать вывод: универсального решения «одной кнопкой» не существует, так как файлы Excel могут быть подготовлены очень по-разному. Однако комбинация метода Прочитать(..., Значение) и ручного парсинга через СтрРазделить покрывает 99% всех задач по импорту дат в 1С.