Сообщение «Переменная не определена (Имя)»: как найти строку кода и убрать сбой
Содержание
Ошибка Переменная не определена (Сумма) в 1С значит одно: в этой строке кода встречается имя, которое компилятор не видит в текущем контексте. Чинить надо не базу и не права, а код: найти модуль и строку из текста ошибки и понять, почему имя в скобках там недоступно. Имя в скобках — главная подсказка, по нему причина находится за пару минут.
Частое заблуждение — считать, что переменную «удалили из базы» или «сломался справочник». Данные тут ни при чём. Чаще всего виновата опечатка, переменная из соседней процедуры, неверная директива компиляции в управляемой форме или внешняя обработка, написанная под другую версию конфигурации.
Что означает сообщение и где в нём адрес ошибки
Полный текст ошибки выглядит примерно так:
{ВнешняяОбработка.ЗагрузкаЦен.Форма.Форма.Форма(42,15)}: Переменная не определена (ПутьКФайлу)
Разберите его по частям:
- 📍 В фигурных скобках — адрес: объект, модуль и номер строки (у новых платформ ещё и позиция в строке).
- 🔤 В круглых скобках в конце — имя, которое не удалось найти. Это не обязательно переменная в бытовом смысле: так же 1С сообщает о неизвестном имени общего модуля, менеджера (
Справочники,Документы) или реквизита формы. - 🧭 Когда появилась — при открытии формы, при нажатии кнопки, при запуске программы. От этого зависит, где искать.
Если пользователь видит только короткое окно, нажмите в нём кнопку «Подробно» или откройте журнал регистрации: там записан полный текст с адресом модуля.
Похожие сообщения означают другое — не путайте их:
| Сообщение | Что не найдено | Где искать |
|---|---|---|
Переменная не определена (Имя) | Имя переменной, модуля, свойства глобального контекста | Область видимости, директивы, опечатки |
Процедура или функция с указанным именем не определена (Имя) | Процедура или функция | Нет метода, не стоит Экспорт, недоступен в контексте |
Тип не определен (Имя) | Тип в конструкторе Новый | Объект недоступен на клиенте или в этой версии платформы |
Поле объекта не обнаружено (Имя) | Реквизит у конкретного объекта | Реквизит переименован или удалён |
Область видимости: почему переменная не определена в процедуре
Встроенный язык 1С разделяет переменные по месту объявления. Переменная, которой присвоили значение внутри процедуры, живёт только в этой процедуре. В соседней процедуре того же модуля её уже нет.
Процедура Рассчитать()
Сумма = 100;
КонецПроцедуры
Процедура Показать()
Сообщить(Сумма); // Переменная не определена (Сумма)
КонецПроцедуры
Три способа исправить, от простого к сложному:
- Передать значение параметром.
Процедура Показать(Сумма)и вызовПоказать(Сумма)изРассчитать(). Самый чистый вариант. - Сделать функцию.
Функция Рассчитать()возвращаетСумма, аПоказать()вызывает её. - Объявить переменную модуля. В начале модуля, до первой процедуры, пишут
Перем Сумма;. Тогда она видна во всех процедурах этого модуля.
Переменная модуля с ключевым словом Экспорт (Перем Сумма Экспорт;) видна снаружи как свойство объекта: например, Обработка.Сумма. В общих модулях переменные модуля объявлять нельзя — там данные передают через параметры функций.
Опечатки, которые не видно глазами
- 🔡 Латиница вместо кириллицы. Код скопировали из мессенджера или PDF, и в имени
Суммапервая буква оказалась латинской «С». Для 1С это два разных имени. Проверка: поставьте курсор на имя и нажмитеCtrl+F— поиск найдёт объявление только при полном совпадении символов. - ✂️ Пропущенная буква —
КонтрагнетвместоКонтрагент. - 🔠 Регистр букв не виноват. Язык 1С регистр не различает:
суммаиСУММА— одна переменная.
Клиент и сервер: директивы компиляции в управляемых формах
В модуле управляемой формы каждая процедура помечена директивой. От неё зависит, какие имена доступны. Это главный источник ошибки у тех, кто переносит код из обычных форм.
Объект и Элементы в &НаСервереБезКонтекста
Процедура с директивой &НаСервереБезКонтекста не получает данных формы. Обращение к реквизитам формы там невозможно:
&НаСервереБезКонтекста
Процедура ЗаполнитьНаСервере()
Объект.Комментарий = "Проверено"; // Переменная не определена (Объект)
КонецПроцедуры
Исправление: поменять директиву на &НаСервере или передать нужные значения параметрами и вернуть результат функцией. Второй вариант быстрее: на сервер не уходят данные всей формы.
Менеджеры и параметры сеанса на клиенте
В процедуре &НаКлиенте тонкий и веб-клиент не видят серверных объектов:
&НаКлиенте
Процедура НайтиКонтрагента(Команда)
Ссылка = Справочники.Контрагенты.НайтиПоКоду("000000001"); // Переменная не определена (Справочники)
КонецПроцедуры
То же будет с Документы, РегистрыСведений, ПараметрыСеанса и прочими серверными менеджерами. Решение — вынести обращение в серверную функцию:
&НаКлиенте
Процедура НайтиКонтрагента(Команда)
Ссылка = НайтиКонтрагентаНаСервере("000000001");
КонецПроцедуры
&НаСервереБезКонтекста
Функция НайтиКонтрагентаНаСервере(Код)
Возврат Справочники.Контрагенты.НайтиПоКоду(Код);
КонецФункции
Общий модуль, недоступный на клиенте
Если общий модуль собран только для сервера, его имя на клиенте неизвестно — отсюда Переменная не определена (РаботаСФайламиСервер) или похожее. Проверьте свойства модуля в Конфигураторе: флажки Клиент (управляемое приложение), Сервер, Вызов сервера. Для вызова серверной функции с клиента нужен флажок Вызов сервера и Экспорт у функции.
Реквизиты объекта по имени
В обычных формах реквизиты объекта можно было писать просто по имени: Контрагент. В управляемой форме это Объект.Контрагент. Перенесённый без правки код даёт ошибку с именем реквизита в скобках.
Выполнить(), Вычислить() и тексты запросов
Код внутри строки, переданной в Выполнить() или Вычислить(), компилируется только в момент выполнения. Синтаксический контроль модуля его не проверяет, поэтому ошибка проявляется у пользователя, а не у разработчика.
Формула = "Цена * Количество * 1.2";
Результат = Вычислить(Формула); // Переменная не определена (Цена), если в процедуре нет переменной Цена
Что проверить:
- Все имена из строки должны существовать в процедуре, откуда вызывается
Вычислить(), в момент вызова. - Формулу хранят в справочнике или настройках? Выведите её через
Сообщить(Формула)перед вызовом — так видно, какое имя пришло на самом деле. - Строку собирают конкатенацией? Проверьте пробелы и кавычки:
"Результат = " + ИмяПолядаст ошибку, если вИмяПоляпришла пустая строка или лишний символ.
Не подставляйте в Выполнить() текст, который ввёл пользователь или пришёл из файла обмена. Помимо ошибок, это дыра в безопасности: строка выполнится с правами текущего сеанса.
Запросы и СКД
Внутри текста запроса ошибка звучит иначе: Поле не найдено или Не установлено значение параметра. «Переменная не определена» рядом с запросом обычно значит, что ошибка в коде вокруг него. Типичные случаи:
- 🧩 значение параметра берут из переменной, которой нет:
Запрос.УстановитьПараметр("Дата", ДатаОтчета)при отсутствующейДатаОтчета; - 🧩 текст запроса собирают из кусков, и в одну из частей попало имя переменной без кавычек;
- 🧩 в вычисляемом поле схемы компоновки вызывают функцию общего модуля, которого нет в этой конфигурации.
Права, режим запуска и ошибка только у одного пользователя
Нехватка прав в 1С сообщается отдельным текстом — Недостаточно прав для…. Сама по себе роль не превращает существующую переменную в неопределённую. Если ошибка есть у одного сотрудника и нет у другого, причина обычно в разном пути выполнения кода.
| Отличие пользователей | Почему ломается | Как проверить |
|---|---|---|
| Разные клиенты: тонкий, толстый, веб | Толстый клиент в режиме обычного приложения видит серверные объекты, тонкий — нет | Запустите базу под проблемным пользователем тем же клиентом |
| Режим запуска «Обычное приложение» и «Управляемое приложение» | Код обычных форм и управляемых компилируется по-разному | В Конфигураторе: свойства пользователя, поле основного режима запуска |
| Ветка кода по роли | Условие Если РольДоступна(...) ведёт в код, где ошибка | Найдите РольДоступна в модуле из адреса ошибки |
| Внешняя обработка в безопасном режиме | Часть возможностей недоступна, обработка падает в другом месте | Проверьте, как подключена обработка и кто её запускает |
Правильный порядок: воспроизвести ошибку под учётной записью этого пользователя на копии базы, а уже потом искать строку в отладчике.
Отладчик и журнал регистрации: как найти неопределённую переменную
Синтаксический контроль
Первая и самая дешёвая проверка — до запуска:
- В Конфигураторе откройте модуль из адреса ошибки.
- Нажмите
Ctrl+F7— синтаксический контроль модуля. Ошибки появятся в окне сообщений, двойной щелчок переносит к строке. - Для всей конфигурации:
Конфигурация → Проверка конфигурации. Отметьте режимыТонкий клиент,Веб-клиент,Сервер,Толстый клиент (управляемое приложение)— ошибка контекста часто видна только в одном режиме.
💡 Синтаксический контроль не видит строки внутри Выполнить() и Вычислить(). Если проверка чистая, а ошибка есть — ищите динамический код.
Отладчик
- Запустите отладку из Конфигуратора (
F5). - Включите
Отладка → Остановка по ошибке. Отладчик встанет ровно на строке, где возникла ошибка. - Откройте табло (
Shift+F9вычисляет выражение) и проверьте значения переменных до проблемной строки.
Для серверного кода в клиент-серверной базе сервер 1С должен быть запущен в режиме отладки. Включение этого режима требует перезапуска службы агента сервера.
Перезапуск службы сервера 1С обрывает все сеансы пользователей — делайте это в нерабочее время или на тестовом сервере.
Журнал регистрации
Если ошибку видит пользователь, а у вас она не повторяется, откройте журнал:
- в пользовательском режиме БП 3.0, ЗУП 3.1, УТ 11:
Администрирование → Поддержка и обслуживание → Журнал регистрации; - в Конфигураторе:
Администрирование → Журнал регистрации.
Отберите записи по уровню «Ошибка», пользователю и времени. В комментарии события будет полный текст с модулем и номером строки.
Обновление конфигурации, расширения и внешние обработки
Типовые конфигурации построены на Библиотеке стандартных подсистем. При обновлении в ней переименовывают и удаляют общие модули и экспортные методы. Код, который на них опирался, начинает выдавать ошибку.
Где искать после обновления:
- Расширения. В БП 3.0 и ЗУП 3.1 список открывается через
Администрирование → Печатные формы, отчеты и обработки → Расширения. Снимите флажок активности у подозрительного расширения, перезапустите сеанс и проверьте. Ушла ошибка — расширение нужно адаптировать к новому релизу. - Внешние обработки и отчёты. Если обработку писали под старый релиз, она обращается к модулям, которых больше нет. Нужна версия обработки под ваш релиз или правка кода.
- Незавершённое обновление. Если обновляли через Конфигуратор и не применили изменения к базе, конфигурация базы данных отличается от основной. Выполните
Конфигурация → Обновить конфигурацию базы данных. Для этого нужен монопольный доступ: попросите всех выйти из базы. - Режим совместимости. Свойство конфигурации «Режим совместимости» ограничивает возможности языка уровнем старой платформы. Код, написанный под новые версии, в таком режиме может не компилироваться. Менять режим совместимости в типовой конфигурации на поддержке самостоятельно не стоит — это делает поставщик в новом релизе.
Перед правкой конфигурации или обновлением сделайте резервную копию базы: выгрузку в .dt через Администрирование → Выгрузить информационную базу в Конфигураторе или копию каталога файловой базы.
Как не допускать ошибку в своём коде
- ✅ Синтаксический контроль перед сохранением —
Ctrl+F7после каждой правки модуля и полная проверка конфигурации перед выпуском обработки. - ✅ Явные параметры вместо переменных модуля. Чем меньше общих переменных, тем меньше шансов обратиться к ним не там.
- ✅ Директивы у каждой процедуры формы. Процедура без директивы в модуле управляемой формы компилируется на сервере — это легко забыть.
- ✅ Свои изменения — в расширениях. Так типовой код обновляется спокойно, а вашу доработку проверяют отдельно.
- ✅ Минимум
Выполнить(). Если без него не обойтись, проверяйте строку перед выполнением и ловите исключение вПопытка … Исключение, записывая текст в журнал регистрации. - ✅ Проверка на копии базы после каждого обновления: откройте внешние обработки и отчёты, которыми пользуется бухгалтерия.
Частые промахи при исправлении
- ❌ Объявить
Перем Имя;в начале модуля, чтобы «ошибка ушла». Ошибка уйдёт, но переменная будет пустой —Неопределено, и дальше код сломается в другом месте. - ❌ Сменить все директивы на
&НаСервере. Форма начнёт гонять данные на сервер при каждом действии и заметно замедлится. - ❌ Править типовой модуль на поддержке без расширения. После следующего обновления правка потеряется или вызовет конфликт при сравнении.