К статье
Практический материал

Разработка и Конфигурация · 11 мин

Переменные в 1С: зачем они нужны и как их использовать

Зачем нужны переменные в 1С: виды переменных, область видимости, типичные ошибки и практические примеры использования в конфигураторе и на языке 1С.

Переменная в 1С — это именованная область памяти, в которой программа хранит данные во время выполнения кода: числа, строки, даты, ссылки на документы, таблицы значений и другие объекты. Без переменных невозможно написать ни одну процедуру: любое вычисление, сравнение или обработка данных требует временного хранения промежуточных результатов.

Типичный пример — расчёт суммы документа. Программа обходит табличную часть «Товары», и на каждой строке прибавляет произведение цены на количество к переменной «ИтогоСумма». После цикла значение этой переменной записывается в реквизит документа. Без переменной пришлось бы на каждой итерации обращаться к базе данных, что было бы медленно и неудобно.

Понимание того, как работают переменные, критично и для чтения чужого кода. Когда вы открываете модуль обработки или документа, почти каждая строка опирается на переменные: локальные параметры процедур, переменные модуля, экспортные переменные. Умение быстро определить, где объявлена переменная и как долго она живёт, — базовый навык разработчика и администратора, вносящего доработки.

Что такое переменная и чем она отличается от реквизита

Главная путаница у начинающих — разница между переменной и реквизитом объекта. Реквизит документа или справочника хранится в базе данных и сохраняется между сеансами работы. Переменная существует только в оперативной памяти сервера или клиента, пока выполняется код. После завершения процедуры или закрытия формы значение переменной теряется безвозвратно.

Это различие определяет типичную схему работы: данные читаются из базы в переменные, обрабатываются, а результат при необходимости записывается обратно в реквизиты. Например, запрос возвращает выборку, её строки поочерёдно помещаются в переменную «Выборка», поля строки копируются в локальные переменные, и только итоговые значения записываются в документ.

Важное свойство языка 1С — слабая типизация. Одна и та же переменная может сначала хранить строку, а затем число: тип определяется текущим значением. Это удобно, но требует аккуратности: если в переменной внезапно оказался не тот тип, ошибка проявится только в момент выполнения операции, а не при объявлении.

Как объявляются переменные и где они видны

Объявление выполняется ключевым словом «Перем» с указанием имени. Явное объявление не обязательно: переменная создаётся при первом присваивании значения. Однако неявное объявление — частый источник ошибок: опечатка в имени создаёт новую пустую переменную вместо обращения к существующей, и программа работает неправильно без видимой ошибки.

Область видимости определяет, откуда к переменной можно обратиться. В 1С есть три уровня: локальные переменные процедуры или функции, переменные модуля (объявлены в разделе описания переменных модуля) и глобальные переменные модуля управляемого приложения. Чем шире область видимости, тем дольше живёт значение и тем выше риск непреднамеренного изменения.

bsl
Перем Счетчик; // переменная модуля

Процедура РассчитатьИтог(ТабличнаяЧасть)
    Перем ИтогоСумма; // локальная переменная
    ИтогоСумма = 0;
    Для Каждого Строка Из ТабличнаяЧасть Цикл
        ИтогоСумма = ИтогоСумма + Строка.Цена * Строка.Количество;
    КонецЦикла;
    Счетчик = Счетчик + 1;
КонецПроцедуры

Ключевое слово «Экспорт» после имени переменной модуля делает её доступной из других модулей через объект. Экспортные переменные стоит использовать редко: они создают скрытые зависимости между модулями, и отладка такого кода заметно усложняется. В большинстве случаев передачу данных лучше организовать через параметры процедур и функций.

Типы значений, которые хранят переменные

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

Для коллекций данных чаще всего применяются массив (упорядоченный список с доступом по индексу), структура (набор именованных полей, удобна для передачи пакета значений между процедурами) и соответствие (пары «ключ — значение» для быстрого поиска). Таблица значений используется, когда нужны строки и колонки с сортировкой, поиском и итогами.

Какую коллекцию выбрать

Массив

Подходит для упорядоченного списка однотипных значений и обхода в цикле. Неудобен для поиска по имени поля.

Структура

Удобна для передачи набора именованных параметров между процедурами. Ключи — только строки, порядок не гарантирован.

Соответствие

Быстрый поиск значения по ключу, например кэш ссылок по коду. Занимает больше памяти, чем массив.

Таблица значений

Нужна для табличных данных с колонками, сортировкой, свёрткой и итогами. Тяжелее остальных коллекций.

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

Типичные сценарии использования переменных

Накопление результата в цикле

Самый частый сценарий — переменная-аккумулятор. Перед циклом ей присваивается начальное значение (ноль, пустая строка, пустая таблица), внутри цикла значение дополняется, после цикла результат используется. Забытая инициализация — классическая ошибка: переменная содержит «Неопределено», и первая же операция сложения вызывает ошибку выполнения.

Передача данных через параметры

Параметры процедур и функций — тоже переменные, локальные для вызова. По умолчанию параметры передаются по ссылке: изменения внутри процедуры видны вызывающему коду. Ключевое слово «Знач» перед параметром передаёт копию, защищая исходное значение от изменений. Это важно для объектов вроде структур и таблиц значений, где неявное изменение часто становится источником трудноуловимых дефектов.

Хранение промежуточных результатов запроса

Результат запроса, выборка, временная таблица — всё это помещается в переменные. Правильная практика — сразу проверять результат на пустоту методом «Пустой()» до начала обхода выборки. Обход пустой выборки не вызовет ошибку, но логика, рассчитанная на наличие данных, молча не выполнится, и дефект обнаружится только по неверным итогам.

Как безопасно работать с переменной в цикле
  1. 1
    Объявите переменную и сразу присвойте начальное значение до цикла
  2. 2
    Внутри цикла изменяйте только эту переменную, не создавая лишних промежуточных
  3. 3
    После цикла проверьте результат на ожидаемый тип и диапазон значений
  4. 4
    Убедитесь в отладчике, что значение на каждой итерации меняется как задумано

Область видимости и время жизни: где чаще всего ошибаются

Локальная переменная создаётся при входе в процедуру и уничтожается при выходе. Если значение нужно между вызовами, его поднимают на уровень модуля — но это решение имеет цену: переменная модуля формы сохраняется, пока открыта форма, и при больших объёмах данных (например, кэшированная таблица значений) расходует память сеанса пользователя.

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

Ещё одна ловушка — повторное использование одной переменной для разных целей внутри длинной процедуры. Код «работает», но при чтении непонятно, что хранится в переменной на каждом участке. Правило простое: одна переменная — одна смысловая роль, имя должно отражать содержимое (ИтогоСумма, ТекущийДоговор, ТаблицаОстатков).

Как проверить работу с переменными в отладчике

Отладчик конфигуратора — основной инструмент проверки. Точка останова останавливает выполнение, после чего в табло или через «Вычислить выражение» можно посмотреть текущее значение любой переменной, её тип и содержимое коллекций. Для таблиц значений и массивов доступен просмотр всех элементов.

Полезный приём — проверка типа значения функцией «ТипЗнч()» в сочетании с «Тип()». Это помогает, когда переменная должна содержать ссылку определённого вида, но из-за логической ошибки получает значение другого типа. Сравнение типов до выполнения операций предотвращает падение кода в рабочей базе.

Контрольные точки

Как проверить результат

Значение переменной в отладчике
Норма

Тип и значение соответствуют ожиданиям на каждой итерации

Тревожный признак

Неопределено, неожиданный тип или значение не меняется в цикле

Итог после цикла
Норма

Совпадает с контрольным расчётом вручную на тестовом примере

Тревожный признак

Расхождение с ручным расчётом или нулевой итог при наличии данных

Поведение при пустых данных
Норма

Код корректно отрабатывает пустую выборку без ошибок

Тревожный признак

Ошибка выполнения или запись некорректных значений в документ

Типичные ошибки и ограничения

Кроме уже упомянутых опечаток и неинициализированных переменных, частые проблемы — обращение к локальной переменной вне её процедуры, конфликт имён переменной модуля и локальной переменной (локальная «затеняет» модульную), а также попытка сохранить служебные данные между сеансами в переменных вместо регистров сведений или констант.

Ограничение, о котором стоит помнить: переменные не переживают перезапуск сеанса, обрыв соединения и завершение фонового задания. Если данные должны сохраняться, их нужно записывать в базу. Если значение нужно только в рамках одного вызова — переменной достаточно, и создавать ради этого реквизит объекта будет избыточно.

Типичные ошибки
01
Опечатка в имени создаёт новую пустую переменную — код молча работает с неверными данными
02
Использование переменной до присвоения значения — ошибка выполнения или непредсказуемый результат
03
Хранение больших таблиц в переменных модуля — рост потребления памяти сеанса
04
Изменение параметра, переданного без «Знач», — неожиданное изменение данных в вызывающем коде
05
Попытка использовать переменную модуля управляемой формы между серверными вызовами — значение теряется
Итог

Что важно запомнить

Переменные хранят данные только во время выполнения кода в оперативной памяти и не сохраняются в базе. Объявляйте их явно, инициализируйте до использования, выбирайте минимально необходимую область видимости и давайте говорящие имена. Для постоянного хранения используйте реквизиты, константы и регистры, а правильность работы с переменными проверяйте в отладчике.

Частые вопросы о переменных в 1С

Обязательно ли объявлять переменную через «Перем»?

Нет, переменная создаётся при первом присваивании. Но явное объявление в начале процедуры считается хорошей практикой: сразу видно, какие данные используются, и проще отловить опечатки в именах.

Чем переменная отличается от константы в 1С?

Константа — объект конфигурации, значение которого хранится в базе данных и сохраняется между сеансами (например, наименование организации). Переменная живёт только в памяти во время выполнения кода. Для данных, нужных после завершения сеанса, переменные не подходят.

Почему переменная модуля формы «обнуляется»?

В управляемых формах переменные модуля существуют только в рамках одного вызова между клиентом и сервером. Для данных, которые должны сохраняться, пока открыта форма, используйте реквизиты формы — они передаются между вызовами автоматически.

Как узнать тип значения в переменной?

Функцией ТипЗнч(Переменная) — она возвращает тип текущего значения. Результат сравнивают с Тип("СправочникСсылка.Номенклатура") и подобными. В отладчике тип виден сразу в табло рядом со значением.

Когда использовать «Знач» при передаче параметра?

Когда процедура не должна изменять переданное значение: для структур, таблиц значений и других объектов, чьё изменение внутри вызвано бы побочный эффект в вызывающем коде. Для простых чтений параметра «Знач» не обязательно.

Можно ли обойтись без переменных в простом коде?

В тривиальных выражениях — да, но любая обработка с циклом, условиями или запросом требует переменных для промежуточных данных. Попытка обойтись без них приводит к дублированию обращений к базе и замедляет работу.