Переименование колонки таблицы значений в коде 1С: свойства, запрос, формы
Содержание
Колонку таблицы значений можно переименовать тремя способами: присвоить новое значение свойству Имя у существующей колонки, пересобрать таблицу с новой колонкой или задать нужное имя сразу в запросе через КАК. Первый способ быстрее всех и сохраняет данные. Второй нужен, когда колонку надо ещё и пересоздать с другим типом. Третий выбирают, если таблица приходит из запроса.
Переименование в 1С 8.3 не меняет ничего в строках: значения остаются на местах, потому что строка обращается к ячейке через колонку, а не через её текстовое имя. Ломается другое: все места кода, где колонка названа по старому имени (Строка.СтароеИмя, Строка["СтароеИмя"], Таблица.Свернуть("СтароеИмя", ...)).
Что такое колонка и чем имя отличается от заголовка
У колонки таблицы значений четыре свойства, которые чаще всего путают:
| Свойство | Для чего | Можно менять |
|---|---|---|
Имя | идентификатор для кода: Строка.Имя | да |
Заголовок | подпись, которую видит пользователь в таблице на форме | да |
ТипЗначения | допустимые типы значений в ячейках | задаётся при создании колонки |
Ширина | ширина колонки в отображении | да |
Если нужно лишь изменить подпись на экране, имя трогать не надо: достаточно Колонка.Заголовок = "Сумма к оплате". Код при этом не сломается, а пользователь увидит новое название. Переименовывать Имя стоит, когда сам идентификатор неудачный: опечатка, транслит, имя конфликтует с другой колонкой после объединения таблиц.
Имя колонки подчиняется тем же правилам, что и имя переменной. Начинается с буквы или подчёркивания, пробелов внутри нет, повторов в одной таблице нет. Нарушите правило, и платформа выдаст ошибку при выполнении, а не при проверке модуля: синтаксический контроль не знает, что лежит в строке.
Переименование через свойство «Имя»
Это основной способ. Колонку находят по старому имени и присваивают новое:
Колонка = ТаблицаЗначений.Колонки.Найти("Контрагент");
Если Колонка <> Неопределено Тогда
Колонка.Имя = "Покупатель";
КонецЕсли;
Метод Найти возвращает Неопределено, если колонки с таким именем нет. Проверка обязательна: без неё присваивание к пустому значению упадёт с ошибкой «Поле объекта не обнаружено» или подобной.
Данные сохраняются целиком. Если в колонке было 500 значений, после переименования их по-прежнему 500, просто обращаться к ним надо по новому имени:
Для Каждого Строка Из ТаблицаЗначений Цикл
Сообщить(Строка.Покупатель); // раньше было Строка.Контрагент
КонецЦикла;
Для нескольких колонок сразу удобно завести соответствие «старое имя → новое» и пройти по нему циклом:
Переименования = Новый Соответствие;
Переименования.Вставить("Контрагент", "Покупатель");
Переименования.Вставить("Сумма", "СуммаДокумента");
Для Каждого Пара Из Переименования Цикл
Колонка = ТаблицаЗначений.Колонки.Найти(Пара.Ключ);
Если Колонка <> Неопределено Тогда
Колонка.Имя = Пара.Значение;
КонецЕсли;
КонецЦикла;
Меняя имена парами, следите за пересечениями. Если нужно поменять местами А и Б, прямое переименование упрётся в дубль имени. Сначала переименуйте А во временное имя, затем Б в А, потом временное в Б.
Новое имя проверяйте заранее: ТаблицаЗначений.Колонки.Найти(НовоеИмя) = Неопределено. Это дешевле, чем ловить исключение.
Когда нужна пересборка: новая колонка вместо старой
Иногда переименования мало. Например, надо сменить тип значения, а ТипЗначения у готовой колонки не поменять. Тогда добавляют новую колонку, переносят данные и удаляют старую:
НоваяКолонка = ТаблицаЗначений.Колонки.Добавить("Покупатель", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
ТаблицаЗначений.ЗагрузитьКолонку(ТаблицаЗначений.ВыгрузитьКолонку("Контрагент"), "Покупатель");
ТаблицаЗначений.Колонки.Удалить("Контрагент");
Значения, которые не подходят под новый тип, превратятся в пустое значение этого типа. Если в старой колонке лежали строки, а в новой разрешены только ссылки, данные потеряются. Перед удалением старой колонки сравните количество непустых значений в обеих.
Пересборка меняет порядок колонок: новая встанет в конец. Вернуть её на нужное место можно сдвигом.
Порядок колонок: сдвиг после переименования
Порядок колонок влияет на то, как таблица отображается на форме и в какой очерёдности колонки попадут при выгрузке в табличный документ. Положение колонки меняет метод Сдвинуть коллекции колонок:
Позиция = ТаблицаЗначений.Колонки.Индекс(ТаблицаЗначений.Колонки.Покупатель);
ТаблицаЗначений.Колонки.Сдвинуть(Позиция, -(Позиция));
Первый параметр — сдвигаемая колонка (её можно передать объектом, именем или индексом), второй — смещение. Положительное число двигает колонку вправо, отрицательное влево. В примере колонка уходит в начало: смещение на её собственный индекс со знаком минус.
Несколько колонок упорядочивают по заданному списку:
Порядок = Новый Массив;
Порядок.Добавить("Покупатель");
Порядок.Добавить("СуммаДокумента");
Порядок.Добавить("Дата");
Для Индекс = 0 По Порядок.Количество() - 1 Цикл
Позиция = ТаблицаЗначений.Колонки.Индекс(ТаблицаЗначений.Колонки[Порядок[Индекс]]);
ТаблицаЗначений.Колонки.Сдвинуть(Позиция, Индекс - Позиция);
КонецЦикла;
Каждая колонка из списка встаёт на позицию, равную её номеру в списке. Проверка на примере из трёх колонок: если Покупатель стояла третьей (индекс 2), смещение будет 0 - 2 = -2, и она окажется первой.
Таблица значений из запроса: имя задаёт псевдоним
Если таблица получена через Результат.Выгрузить(), имена колонок уже определены текстом запроса. Менять их после выгрузки можно тем же свойством Имя, но проще и надёжнее назвать поле правильно сразу:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Контрагент КАК Покупатель,
| СУММА(Продажи.Сумма) КАК СуммаДокумента
|ИЗ
| РегистрНакопления.Продажи КАК Продажи
|СГРУППИРОВАТЬ ПО
| Продажи.Контрагент";
ТаблицаЗначений = Запрос.Выполнить().Выгрузить();
Колонки получат имена Покупатель и СуммаДокумента. Псевдоним — единственное, на что опирается выгрузка, поэтому он должен быть корректным идентификатором. Пробелы и точки в псевдониме запрос не примет.
С временными таблицами правило то же. В пакетном запросе вы называете поля при создании временной таблицы, а следующие запросы пакета обращаются к ним по этим именам:
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Товар,
| Остатки.КоличествоОстаток КАК Количество
|ПОМЕСТИТЬ ВТОстатки
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
|;
|ВЫБРАТЬ
| ВТОстатки.Товар,
| ВТОстатки.Количество
|ИЗ
| ВТОстатки КАК ВТОстатки";
Если вы передаёте в запрос таблицу значений как параметр временной таблицы (МенеджерВременныхТаблиц или таблица в условии), имена её колонок должны совпадать с теми, что запрос ожидает. После переименования колонки проверьте и текст запроса: он не обновится сам.
Что сломается после переименования и как это найти
Платформа не отслеживает использование имени колонки в тексте. Обращения по имени к колонке — обычные строки и свойства, которые проверяются только при выполнении. Ищите их сами:
- Найдите в модулях все места, где таблица создаётся, передаётся и читается. Начните с поиска по тексту старого имени колонки.
- Проверьте строковые обращения:
Строка["Контрагент"],Таблица.Найти(Значение, "Контрагент"),Таблица.НайтиСтроки(Новый Структура("Контрагент", ...)). - Проверьте методы с перечнем колонок строкой:
Свернуть("Контрагент", "Сумма"),Сортировать("Контрагент"),ВыгрузитьКолонки("Контрагент, Сумма"),Индексы. - Проверьте структуры и соответствия, которые собираются по именам колонок динамически:
Новый Структура("Контрагент, Сумма")иЗаполнитьЗначенияСвойств.
В Конфигураторе для этого есть поиск по всей конфигурации в меню Правка: выберите область «все модули» и введите старое имя. Лучше искать с границами слова, иначе вы получите лишние совпадения: Контрагент встречается в тысяче других мест. Автоматического рефакторинга для колонок таблиц значений в Конфигураторе нет, поэтому проверка — ручная.
Совпадение имени в тексте не доказывает, что это та же колонка. Одинаковые названия бывают у колонок разных таблиц. Правьте только те обращения, где вы точно видите, из какой таблицы они читают.
Если таблица значений привязана к реквизиту формы, а на форме есть таблица, подключённая к этим колонкам, переименование на лету не обновит элементы формы. Колонки реквизита формы типа «Таблица значений» меняют через ИзменитьРеквизиты: старые реквизиты удаляют, новые добавляют, после чего элементы формы привязывают заново. Для таблицы формы, заданной в конструкторе, имена колонок меняют в самом реквизите формы и в привязанных элементах.
Универсальная процедура переименования
Если переименовывать приходится в разных местах, оформите логику в одну функцию. Она проверит старое имя, убедится, что новое свободно, и вернёт результат:
Функция ПереименоватьКолонку(Таблица, СтароеИмя, НовоеИмя) Экспорт
Колонка = Таблица.Колонки.Найти(СтароеИмя);
Если Колонка = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Если Таблица.Колонки.Найти(НовоеИмя) <> Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Колонка.Имя = НовоеИмя;
Возврат Истина;
КонецФункции
Вызывающий код получает Истина или Ложь и решает, что делать дальше: записать в журнал, показать сообщение или прервать обработку. Исключение платформы вы не ловите, потому что причины заранее исключены.
Функция пригодится при объединении таблиц из разных источников. Допустим, одна выгрузка даёт колонку Контрагент, другая Покупатель, а в итоговую таблицу нужны данные под одним именем. Приведите обе к общему имени до загрузки строк, иначе ЗаполнитьЗначенияСвойств пропустит несовпавшие поля без единого предупреждения.
Объединение таблиц с разными именами колонок
Типовая задача: есть две таблицы с одинаковым смыслом колонок, но разными именами. Порядок действий такой:
- Скопируйте вторую таблицу методом
Скопировать(), чтобы не менять исходную: после переименования в оригинале у других функций сломаются обращения. - Переименуйте в копии колонки под имена первой таблицы.
- Переносите строки циклом: для каждой строки копии добавьте строку в первую таблицу и вызовите
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка). - Проверьте, что количество строк в итоге равно сумме строк обеих таблиц. Если нет, часть строк не добавилась.
Копия избавляет от побочного эффекта: таблицу значений передают в функции по ссылке, поэтому переименование внутри процедуры меняет таблицу у вызывающего кода. Это частая причина странных ошибок «поле не найдено» в совершенно другом месте модуля.
Как проверить результат переименования
После правки убедитесь, что колонки теперь называются так, как вы ожидаете. Самый быстрый способ — пройти по коллекции колонок и вывести имена:
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Сообщить(Колонка.Имя + " | " + Колонка.Заголовок + " | " + Колонка.ТипЗначения);
КонецЦикла;
В отладчике то же видно в окне вычисления выражения: введите ТаблицаЗначений.Колонки и раскройте коллекцию. Для таблицы на 20 колонок это быстрее, чем искать нужное имя в тексте запроса.
Отдельная история — колонки с составным типом. Если в колонке лежат значения разных типов (число и строка вперемешку), после загрузки в новую колонку с узким типом часть данных обнулится. Количество значений до и после проверяйте простым подсчётом:
Количество = 0;
Для Каждого Строка Из ТаблицаЗначений Цикл
Если ЗначениеЗаполнено(Строка.Покупатель) Тогда
Количество = Количество + 1;
КонецЕсли;
КонецЦикла;
Если число заполненных значений до переноса и после не совпадает, тип новой колонки уже, чем нужен. Расширьте описание типов и повторите перенос.
Типичные ошибки при переименовании
Список здесь короткий: большинство сбоев сводится к трём причинам.
Колонка с таким именем уже существует— имя занято. ПроверяйтеНайти(НовоеИмя)до присваивания.Поле объекта не обнаруженопри обращенииСтрока.СтароеИмя— код остался на прежнем имени. Исправьте обращение либо пересоберите таблицу с обеими колонками на время перехода.- Некорректное имя — например,
Сумма договорас пробелом. ИспользуйтеСуммаДоговора, а человекочитаемый вариант положите вЗаголовок.
Ещё одна неприятность не даёт ошибки: если запрос выбирает Таблица.Поле без псевдонима, колонка получает имя поля. При смене поля в источнике имя колонки сменится само, и код, ожидающий старое, разойдётся с данными. Поэтому псевдонимы лучше писать всегда, даже когда они совпадают с полем.
Частые вопросы
Можно ли переименовать колонку в готовой таблице, не потеряв данные?
Имя колонки: значения в ячейках остаются на месте.Чем отличаются имя колонки и заголовок?
Строка.Имя. Заголовок — подпись для пользователя в таблице на форме. Подпись можно менять, не трогая код.Как переименовать колонку, если таблица пришла из запроса?
КАК прямо в тексте запроса. Уже выгруженную таблицу можно поправить свойством Имя.Как поменять местами имена двух колонок?
Можно ли изменить тип значения колонки без потери данных?
ВыгрузитьКолонку и ЗагрузитьКолонку, затем удалите старую.