Часто в практике разработчика 1С возникает ситуация: данные получены из внешнего источника (например, загружены из файла Excel или MXL) в объект ТаблицаЗначений, и все значения в колонках имеют тип Строка. При попытке преобразовать эти значения в Дата с помощью стандартных функций, программист замечает, что тип данных в ячейках упорно остается строковым. Давайте разберем, почему это происходит и как правильно решить эту задачу.
Проанализируем классическую ошибку. Рассмотрим типичный код, который кажется логичным на первый взгляд:
Для каждого Стр Из ТЗВД Цикл
Стр.Дата = Дата(Стр.Дата);
КонецЦикла;
Несмотря на то, что функция Дата() успешно отрабатывает и возвращает объект типа Дата, после присваивания обратно в Стр.Дата значение снова становится строкой. Причина кроется в строгой типизации колонок таблицы значений.
В платформе «1С:Предприятие» колонка таблицы значений — это не просто набор ячеек, это объект, имеющий свои свойства, главное из которых — ТипЗначения (описывается объектом ОписаниеТипов). Если при создании таблицы или при ее заполнении из внешнего источника (например, методом Выгрузить() из табличного документа) колонке был жестко назначен тип Строка, то платформа будет выполнять неявное приведение типов. Любое значение, которое вы попытаетесь записать в такую колонку, будет автоматически преобразовано в строку согласно правилам платформы.
Поскольку изменить тип уже существующей и типизированной колонки «на лету» невозможно, мы воспользуемся проверенным алгоритмом обхода этого ограничения. Разберем его по шагам.
Шаг 1. Создание новой типизированной колонки
Сначала нам нужно добавить в существующую таблицу значений новую колонку, которая будет изначально настроена на хранение дат. Для этого мы используем объект ОписаниеТипов.
// Определяем тип колонки как Дата
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Дата"));
КвалификаторыДаты = Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя);
ОписаниеТипаДата = Новый ОписаниеТипов(МассивТипов, , КвалификаторыДаты);
// Добавляем временную колонку в таблицу ТЗВД
ТЗВД.Колонки.Добавить("ДатаВременная", ОписаниеТипаДата);
Шаг 2. Перенос данных с конвертацией
Теперь мы пройдемся по всей таблице в цикле, преобразуем строковые значения из старой колонки в настоящие даты и запишем их в новую колонку.
Для каждого Стр Из ТЗВД Цикл
// Используем попытку, так как строка может содержать некорректную дату
Попытка
Стр.ДатаВременная = Дата(Стр.Дата);
Исключение
Стр.ДатаВременная = '00010101'; // Пустая дата в случае ошибки
КонецПопытки;
КонецЦикла;
Шаг 3. Замена старой колонки на новую
Чтобы сохранить структуру таблицы и не переписывать остальной код, который обращается к колонке по имени Дата, мы удалим старую колонку и переименуем новую.
// Удаляем старую строковую колонку
ТЗВД.Колонки.Удалить("Дата");
// Переименовываем временную колонку в оригинальное имя
ТЗВД.Колонки.ДатаВременная.Имя = "Дата";
ТЗВД.Колонки.Дата.Заголовок = "Дата";
При конвертации данных из строк крайне важно учитывать формат исходной строки. Рассмотрим ситуацию, когда формат даты в строке отличается от стандартного "ГГГГММДДччммсс" или системного формата текущей локализации.
Если строка имеет вид "02.09.2020 19:56:54", стандартная функция Дата() справится успешно. Однако, если в файле-источнике даты записаны нестандартно, рекомендуется использовать ручной разбор строки:
// Пример разбора строки формата "ДД-ММ-ГГГГ"
СтрокаДата = "02-09-2020";
День = Число(Лев(СтрокаДата, 2));
Месяц = Число(Сред(СтрокаДата, 4, 2));
Год = Число(Прав(СтрокаДата, 4));
Результат = Дата(Год, Месяц, День);
Это позволит избежать ошибок выполнения (Runtime errors) в тех случаях, когда формат даты в исходном файле внезапно изменится или будет содержать лишние пробелы.
Если ваша ТаблицаЗначений строится на основе загрузки из ТабличныйДокумент, выясним причину появления строковых типов. Обычно это происходит при использовании метода Текст ячейки вместо свойства Значение.
Рассмотрим рекомендации по правильной загрузке:
ТаблицаЗначений программно, четко определив все колонки и их типы через ОписаниеТипов, а только потом заполнять ее данными из MXL.Значение. Если ячейка в MXL имела формат даты, платформа автоматически передаст в таблицу объект типа Дата, при условии, что колонка таблицы это позволяет.Мы рассмотрели, что основная сложность при смене типа данных в ТаблицаЗначений заключается не в самой функции преобразования, а в архитектуре объекта. Помните: если колонка типизирована, она будет диктовать тип любому значению, которое в нее попадает. Использование временной колонки с правильным ОписаниеТипов — это наиболее надежный и производительный способ решения данной задачи в среде 1С.