При переходе с платформы «1С:Предприятие 7.7» на версию 8.х разработчики часто сталкиваются с ситуацией, которая кажется мистической: в одной строке кода отладчик показывает, что в ячейке таблицы лежит СправочникСсылка, а на следующей итерации цикла или при использовании в функциях значение внезапно становится Строкой. Разберем подробно, почему так происходит, как работает типизация в 1С 8.х и как правильно обрабатывать данные в коллекциях.
В отличие от 7.7, где типизация была менее строгой в одних аспектах и более жесткой в других, Таблица Значений в 1С 8.х — это гибкий объект. Рассмотрим основные правила работы с колонками:
Добавить() был указан конкретный ОписаниеТипов, то платформа будет пытаться привести любое записываемое значение к этому типу.Число, Строка, СправочникСсылка или даже NULL.Проанализируем ситуацию автора: в колонке «Склад» перемешаны типы данных (Склады, Строка, Null). Это ключевой момент. Проблема не в том, что тип «меняется» сам по себе, а в том, как мы к нему обращаемся и что ожидаем увидеть.
Самая частая ошибка начинающего разработчика — путать объект (ссылку) и его текстовое описание. СправочникСсылка — это сложный объект, содержащий уникальный идентификатор (GUID). Однако, когда мы выводим его в Сообщить() или присваиваем заголовку элемента формы, 1С автоматически вызывает получение представления (обычно это наименование справочника).
Рассмотрим пример кода, который часто сбивает с толку:
// В ячейке лежит Ссылка
Значение = ТЗ[0].Склад;
// ТипЗнч(Значение) вернет Тип("СправочникСсылка.Склады")
// Мы передаем ссылку в функцию, которая ожидает текст
ЗаголовокКолонки = Значение;
// Если ЗаголовокКолонки — это реквизит формы с типом Строка,
// произойдет неявное приведение. Тип в ТЗ не изменится,
// но в переменной ЗаголовокКолонки будет текст.
Выясним причину странного поведения, описанного в сообщениях темы. Автор заметил, что при выполнении определенного кода тип в отладчике «скидывается» на строку. Это происходит из-за неявного приведения типов в строковых функциях.
Посмотрим на этот фрагмент:
ИмяКолонки = ЗаменитьСпецСимволы(ТЗ[й][колСклад]);
Функция ЗаменитьСпецСимволы по своей логике работает со строками. Как только вы передаете в нее ссылку, платформа 1С «на лету» преобразует эту ссылку в строку (наименование склада). Если внутри этой функции или сразу после нее происходит запись результата обратно в таблицу (даже если вам кажется, что вы только читаете), тип данных в ячейке будет перезаписан строкой.
Важный нюанс отладчика: В некоторых релизах платформы визуальное отображение в окне «Табло» или «Локальные переменные» может кэшировать строковое представление для скорости. Если вы видите текст вместо «СправочникСсылка», всегда проверяйте тип через ТипЗнч().
В сообщениях 3 и 13 опытные разработчики настоятельно рекомендуют отказаться от обхода таблицы по индексу (Для й=0 по...) в пользу конструкции Для каждого. Разберем по шагам, почему это лучше:
ТЗ[й][колСклад].Для каждого использует итератор, что работает быстрее на больших таблицах.Рассмотрим правильный пример реализации задачи автора:
Для Каждого СтрокаТЗ Из ТЗ Цикл
ТекущееЗначение = СтрокаТЗ[колСклад];
// Проверяем тип перед манипуляциями
Если ТипЗнч(ТекущееЗначение) = Тип("СправочникСсылка.Склады") Тогда
// Работаем как со ссылкой
Сообщить("Найдена ссылка на склад: " + ТекущееЗначение.Наименование);
ИначеЕсли ТипЗнч(ТекущееЗначение) = Тип("Строка") Тогда
// Работаем как со строкой
Сообщить("В ячейке просто текст: " + ТекущееЗначение);
КонецЕсли;
// Безопасное получение строкового представления для заголовка
Заголовок = Строка(ТекущееЗначение);
КонецЦикла;
Автор в сообщении 12 приводит два варианта кода. Разберем, почему один из них вызывает вопросы.
Вариант 1 (Рабочий): Сначала идет проверка типа ТипЗнч(), а потом присваивание. Здесь логика прозрачна: мы сначала убеждаемся, что в ячейке ссылка, совершаем действия, и только потом используем значение для формирования заголовка.
Вариант 2 (Проблемный):
ЗаголовокКолонки = ТЗ[й][колСклад];
// Если ЗаголовокКолонки — строковая переменная,
// здесь может произойти визуальное замещение в отладчике.
Если ТипЗнч(ТЗ[й][колСклад]) = Тип("СправочникСсылка.Склады") Тогда
// Проверка может не сработать, если до этого
// в этой же колонке встретилась строка и сработал
// какой-то побочный эффект преобразования.
КонецЕсли;
Основной вывод: платформа никогда самопроизвольно не меняет тип данных в Таблице Значений. Тип меняется только в двух случаях:
ТЗ[й][колСклад] = "НовоеЗначение";Если вам кажется, что данные «стали строкой», проверьте, не передаете ли вы их в функции обработки текста и не перепутали ли вы саму переменную в ТЗ с переменной-буфером, в которую сохранили результат работы функции Строка() или ЗаменитьСпецСимволы().