Сообщение «Переменная не определена (Имя)»: как найти строку кода и убрать сбой

· 10 мин

Содержание

Ошибка Переменная не определена (Сумма) в 1С значит одно: в этой строке кода встречается имя, которое компилятор не видит в текущем контексте. Чинить надо не базу и не права, а код: найти модуль и строку из текста ошибки и понять, почему имя в скобках там недоступно. Имя в скобках — главная подсказка, по нему причина находится за пару минут.

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

Что означает сообщение и где в нём адрес ошибки

Полный текст ошибки выглядит примерно так:

{ВнешняяОбработка.ЗагрузкаЦен.Форма.Форма.Форма(42,15)}: Переменная не определена (ПутьКФайлу)

Разберите его по частям:

  • 📍 В фигурных скобках — адрес: объект, модуль и номер строки (у новых платформ ещё и позиция в строке).
  • 🔤 В круглых скобках в конце — имя, которое не удалось найти. Это не обязательно переменная в бытовом смысле: так же 1С сообщает о неизвестном имени общего модуля, менеджера (Справочники, Документы) или реквизита формы.
  • 🧭 Когда появилась — при открытии формы, при нажатии кнопки, при запуске программы. От этого зависит, где искать.

Если пользователь видит только короткое окно, нажмите в нём кнопку «Подробно» или откройте журнал регистрации: там записан полный текст с адресом модуля.

Похожие сообщения означают другое — не путайте их:

СообщениеЧто не найденоГде искать
Переменная не определена (Имя)Имя переменной, модуля, свойства глобального контекстаОбласть видимости, директивы, опечатки
Процедура или функция с указанным именем не определена (Имя)Процедура или функцияНет метода, не стоит Экспорт, недоступен в контексте
Тип не определен (Имя)Тип в конструкторе НовыйОбъект недоступен на клиенте или в этой версии платформы
Поле объекта не обнаружено (Имя)Реквизит у конкретного объектаРеквизит переименован или удалён

Область видимости: почему переменная не определена в процедуре

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

Процедура Рассчитать()
	Сумма = 100;
КонецПроцедуры

Процедура Показать()
	Сообщить(Сумма); // Переменная не определена (Сумма)
КонецПроцедуры

Три способа исправить, от простого к сложному:

  1. Передать значение параметром. Процедура Показать(Сумма) и вызов Показать(Сумма) из Рассчитать(). Самый чистый вариант.
  2. Сделать функцию. Функция Рассчитать() возвращает Сумма, а Показать() вызывает её.
  3. Объявить переменную модуля. В начале модуля, до первой процедуры, пишут Перем Сумма;. Тогда она видна во всех процедурах этого модуля.

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

Опечатки, которые не видно глазами

  • 🔡 Латиница вместо кириллицы. Код скопировали из мессенджера или PDF, и в имени Сумма первая буква оказалась латинской «С». Для 1С это два разных имени. Проверка: поставьте курсор на имя и нажмите Ctrl+F — поиск найдёт объявление только при полном совпадении символов.
  • ✂️ Пропущенная буква — Контрагнет вместо Контрагент.
  • 🔠 Регистр букв не виноват. Язык 1С регистр не различает: сумма и СУММА — одна переменная.

Клиент и сервер: директивы компиляции в управляемых формах

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

Объект и Элементы в &НаСервереБезКонтекста

Процедура с директивой &НаСервереБезКонтекста не получает данных формы. Обращение к реквизитам формы там невозможно:

&НаСервереБезКонтекста
Процедура ЗаполнитьНаСервере()
	Объект.Комментарий = "Проверено"; // Переменная не определена (Объект)
КонецПроцедуры

Исправление: поменять директиву на &НаСервере или передать нужные значения параметрами и вернуть результат функцией. Второй вариант быстрее: на сервер не уходят данные всей формы.

Менеджеры и параметры сеанса на клиенте

В процедуре &НаКлиенте тонкий и веб-клиент не видят серверных объектов:

&НаКлиенте
Процедура НайтиКонтрагента(Команда)
	Ссылка = Справочники.Контрагенты.НайтиПоКоду("000000001"); // Переменная не определена (Справочники)
КонецПроцедуры

То же будет с Документы, РегистрыСведений, ПараметрыСеанса и прочими серверными менеджерами. Решение — вынести обращение в серверную функцию:

&НаКлиенте
Процедура НайтиКонтрагента(Команда)
	Ссылка = НайтиКонтрагентаНаСервере("000000001");
КонецПроцедуры

&НаСервереБезКонтекста
Функция НайтиКонтрагентаНаСервере(Код)
	Возврат Справочники.Контрагенты.НайтиПоКоду(Код);
КонецФункции

Общий модуль, недоступный на клиенте

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

Реквизиты объекта по имени

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

Выполнить(), Вычислить() и тексты запросов

Код внутри строки, переданной в Выполнить() или Вычислить(), компилируется только в момент выполнения. Синтаксический контроль модуля его не проверяет, поэтому ошибка проявляется у пользователя, а не у разработчика.

Формула = "Цена * Количество * 1.2";
Результат = Вычислить(Формула); // Переменная не определена (Цена), если в процедуре нет переменной Цена

Что проверить:

  1. Все имена из строки должны существовать в процедуре, откуда вызывается Вычислить(), в момент вызова.
  2. Формулу хранят в справочнике или настройках? Выведите её через Сообщить(Формула) перед вызовом — так видно, какое имя пришло на самом деле.
  3. Строку собирают конкатенацией? Проверьте пробелы и кавычки: "Результат = " + ИмяПоля даст ошибку, если в ИмяПоля пришла пустая строка или лишний символ.

Не подставляйте в Выполнить() текст, который ввёл пользователь или пришёл из файла обмена. Помимо ошибок, это дыра в безопасности: строка выполнится с правами текущего сеанса.

Запросы и СКД

Внутри текста запроса ошибка звучит иначе: Поле не найдено или Не установлено значение параметра. «Переменная не определена» рядом с запросом обычно значит, что ошибка в коде вокруг него. Типичные случаи:

  • 🧩 значение параметра берут из переменной, которой нет: Запрос.УстановитьПараметр("Дата", ДатаОтчета) при отсутствующей ДатаОтчета;
  • 🧩 текст запроса собирают из кусков, и в одну из частей попало имя переменной без кавычек;
  • 🧩 в вычисляемом поле схемы компоновки вызывают функцию общего модуля, которого нет в этой конфигурации.

Права, режим запуска и ошибка только у одного пользователя

Нехватка прав в 1С сообщается отдельным текстом — Недостаточно прав для…. Сама по себе роль не превращает существующую переменную в неопределённую. Если ошибка есть у одного сотрудника и нет у другого, причина обычно в разном пути выполнения кода.

Отличие пользователейПочему ломаетсяКак проверить
Разные клиенты: тонкий, толстый, вебТолстый клиент в режиме обычного приложения видит серверные объекты, тонкий — нетЗапустите базу под проблемным пользователем тем же клиентом
Режим запуска «Обычное приложение» и «Управляемое приложение»Код обычных форм и управляемых компилируется по-разномуВ Конфигураторе: свойства пользователя, поле основного режима запуска
Ветка кода по ролиУсловие Если РольДоступна(...) ведёт в код, где ошибкаНайдите РольДоступна в модуле из адреса ошибки
Внешняя обработка в безопасном режимеЧасть возможностей недоступна, обработка падает в другом местеПроверьте, как подключена обработка и кто её запускает

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

Отладчик и журнал регистрации: как найти неопределённую переменную

Синтаксический контроль

Первая и самая дешёвая проверка — до запуска:

  1. В Конфигураторе откройте модуль из адреса ошибки.
  2. Нажмите Ctrl+F7 — синтаксический контроль модуля. Ошибки появятся в окне сообщений, двойной щелчок переносит к строке.
  3. Для всей конфигурации: Конфигурация → Проверка конфигурации. Отметьте режимы Тонкий клиент, Веб-клиент, Сервер, Толстый клиент (управляемое приложение) — ошибка контекста часто видна только в одном режиме.

💡 Синтаксический контроль не видит строки внутри Выполнить() и Вычислить(). Если проверка чистая, а ошибка есть — ищите динамический код.

Отладчик

  1. Запустите отладку из Конфигуратора (F5).
  2. Включите Отладка → Остановка по ошибке. Отладчик встанет ровно на строке, где возникла ошибка.
  3. Откройте табло (Shift+F9 вычисляет выражение) и проверьте значения переменных до проблемной строки.

Для серверного кода в клиент-серверной базе сервер 1С должен быть запущен в режиме отладки. Включение этого режима требует перезапуска службы агента сервера.

Перезапуск службы сервера 1С обрывает все сеансы пользователей — делайте это в нерабочее время или на тестовом сервере.

Журнал регистрации

Если ошибку видит пользователь, а у вас она не повторяется, откройте журнал:

  • в пользовательском режиме БП 3.0, ЗУП 3.1, УТ 11: Администрирование → Поддержка и обслуживание → Журнал регистрации;
  • в Конфигураторе: Администрирование → Журнал регистрации.

Отберите записи по уровню «Ошибка», пользователю и времени. В комментарии события будет полный текст с модулем и номером строки.

Диагностика: выберите симптом

Обновление конфигурации, расширения и внешние обработки

Типовые конфигурации построены на Библиотеке стандартных подсистем. При обновлении в ней переименовывают и удаляют общие модули и экспортные методы. Код, который на них опирался, начинает выдавать ошибку.

Где искать после обновления:

  1. Расширения. В БП 3.0 и ЗУП 3.1 список открывается через Администрирование → Печатные формы, отчеты и обработки → Расширения. Снимите флажок активности у подозрительного расширения, перезапустите сеанс и проверьте. Ушла ошибка — расширение нужно адаптировать к новому релизу.
  2. Внешние обработки и отчёты. Если обработку писали под старый релиз, она обращается к модулям, которых больше нет. Нужна версия обработки под ваш релиз или правка кода.
  3. Незавершённое обновление. Если обновляли через Конфигуратор и не применили изменения к базе, конфигурация базы данных отличается от основной. Выполните Конфигурация → Обновить конфигурацию базы данных. Для этого нужен монопольный доступ: попросите всех выйти из базы.
  4. Режим совместимости. Свойство конфигурации «Режим совместимости» ограничивает возможности языка уровнем старой платформы. Код, написанный под новые версии, в таком режиме может не компилироваться. Менять режим совместимости в типовой конфигурации на поддержке самостоятельно не стоит — это делает поставщик в новом релизе.

Перед правкой конфигурации или обновлением сделайте резервную копию базы: выгрузку в .dt через Администрирование → Выгрузить информационную базу в Конфигураторе или копию каталога файловой базы.

Как не допускать ошибку в своём коде

  • ✅ Синтаксический контроль перед сохранением — Ctrl+F7 после каждой правки модуля и полная проверка конфигурации перед выпуском обработки.
  • ✅ Явные параметры вместо переменных модуля. Чем меньше общих переменных, тем меньше шансов обратиться к ним не там.
  • ✅ Директивы у каждой процедуры формы. Процедура без директивы в модуле управляемой формы компилируется на сервере — это легко забыть.
  • ✅ Свои изменения — в расширениях. Так типовой код обновляется спокойно, а вашу доработку проверяют отдельно.
  • ✅ Минимум Выполнить(). Если без него не обойтись, проверяйте строку перед выполнением и ловите исключение в Попытка … Исключение, записывая текст в журнал регистрации.
  • ✅ Проверка на копии базы после каждого обновления: откройте внешние обработки и отчёты, которыми пользуется бухгалтерия.

Частые промахи при исправлении

  • ❌ Объявить Перем Имя; в начале модуля, чтобы «ошибка ушла». Ошибка уйдёт, но переменная будет пустой — Неопределено, и дальше код сломается в другом месте.
  • ❌ Сменить все директивы на &НаСервере. Форма начнёт гонять данные на сервер при каждом действии и заметно замедлится.
  • ❌ Править типовой модуль на поддержке без расширения. После следующего обновления правка потеряется или вызовет конфликт при сравнении.

Частые вопросы

Можно ли исправить ошибку без программиста?
Если ошибка во внешней обработке или расширении — да: отключите расширение или запросите у поставщика версию обработки под ваш релиз. Если ошибка в типовом коде после правок — нужен специалист с доступом к Конфигуратору.
Почему ошибка появилась, хотя в коде никто ничего не менял?
Обычно изменилось окружение: обновили конфигурацию, пользователя перевели на тонкий или веб-клиент, подключили новое расширение. Сравните, что изменилось в день появления ошибки.
Переменная объявлена через Перем, а ошибка всё равно есть. Почему?
Проверьте, в каком модуле она объявлена. Переменная модуля формы не видна из модуля объекта и наоборот. Из другого модуля к ней обращаются только через объект и только если стоит Экспорт.
Ошибка в ЗУП или Бухгалтерии без доработок. Что делать?
Проверьте список расширений и подключённые внешние обработки — чаще всего виноваты они. Если доработок нет совсем, проверьте, что конфигурация базы данных обновлена до конца, и сообщите об ошибке поставщику конфигурации с полным текстом из журнала регистрации.
Влияет ли ошибка на данные базы?
Сама ошибка данные не портит: код останавливается на проблемной строке. Если операция шла в транзакции (например, проведение документа), она откатывается целиком. Записи, сделанные до сбоя вне транзакции, сохраняются — после исправления проверьте, не задвоятся ли они при повторном запуске.