← Назад к вопросам

Поиск ошибок в коде

2.0 Middle🔥 181 комментариев
#Стандарты разработки

Условие

Просмотрите код и найдите все ошибки:

&НаКлиенте
Процедура ЗаполнитьТовары()
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ Номенклатура.Наименование ИЗ Справочник.Номенклатура";
    Результат = Запрос.Выполнить();
    
    Для Каждого Строка Из Результат Цикл
        НоваяСтрока = Объект.Товары.Добавить();
        НоваяСтрока.Номенклатура = Строка.Номенклатура;
    КонецЦикла;
КонецПроцедуры

Задание

  1. Найдите все ошибки в коде
  2. Объясните, почему это ошибки
  3. Предложите исправленный вариант

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Поиск ошибок в коде

Обнаруженные ошибки

Ошибка 1: Неправильный контекст выполнения запроса

&НаКлиенте  // ← ОШИБКА: запрос выполняется на клиенте
Процедура ЗаполнитьТовары()
    Запрос = Новый Запрос;  // ← Это выполняется на клиенте

Почему это ошибка:

  • Запросы в 1С выполняются только НА СЕРВЕРЕ (&НаСервере)
  • На клиенте объект Запрос не содержит данных из БД
  • Код упадёт с ошибкой: "Невозможно выполнить запрос в контексте клиента"

Исправление:

&НаСервере
Процедура ЗаполнитьТовары()

Ошибка 2: Неправильное использование результата запроса

Результат = Запрос.Выполнить();

Для Каждого Строка Из Результат Цикл  // ← ОШИБКА: неправильная итерация

Почему это ошибка:

  • Запрос.Выполнить() возвращает объект типа РезультатЗапроса
  • Итерировать через цикл Для Каждого нельзя напрямую
  • Нужно получить выборку (итератор) через .Выбрать()

Исправление:

Выборка = Запрос.Выполнить().Выбрать();  // ← Правильно

Пока Выборка.Следующий() Цикл
    // итерирование
КонецЦикла;

ИЛИ

Таблица = Запрос.Выполнить().Выгрузить();  // ← Для работы с таблицей

Для Каждого Строка Из Таблица Цикл
    // итерирование
КонецЦикла;

Ошибка 3: Неправильное обращение к полю результата

НоваяСтрока.Номенклатура = Строка.Номенклатура;  // ← ОШИБКА

Почему это ошибка:

  • В запросе мы выбираем только Номенклатура.Наименование
  • Поле Номенклатура (сама справка) не выбирается в запросе
  • В переменной Строка будет только поле Наименование
  • Попытка обращения к Строка.Номенклатура вернёт Неопределено

Исправление:

// Вариант 1: если нужна только наименование
НоваяСтрока.Наименование = Строка.Наименование;

// Вариант 2: если нужна ссылка на номенклатуру
Запрос.Текст = "ВЫБРАТЬ Номенклатура.Ссылка, Номенклатура.Наименование ИЗ Справочник.Номенклатура";
НоваяСтрока.Номенклатура = Строка.Ссылка;

Ошибка 4: Отсутствие защиты от ошибок

Проблема:

  • Код не содержит обработки ошибок
  • Если объект не инициализирован, произойдёт ошибка

Исправление:

Попытка
    // Код
Исключение
    ЗаписьЖурнала("ОшибкаЗаполнения", ТипСобытияЖурналаРегистрации.Ошибка);
    ВызватьИсключение();
КонецПопытки;

Исправленный вариант 1: Простой вариант

&НаСервере
Процедура ЗаполнитьТовары()
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    Номенклатура.Ссылка КАК НоменклатураСсылка,
    |    Номенклатура.Наименование КАК Наименование
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура";
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        НоваяСтрока = Объект.Товары.Добавить();
        НоваяСтрока.Номенклатура = Выборка.НоменклатураСсылка;
    КонецЦикла;
    
КонецПроцедуры

Исправленный вариант 2: С использованием Выгрузить()

&НаСервере
Процедура ЗаполнитьТовары()
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |    Номенклатура КАК Номенклатура
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура";
    
    ТаблицаДанных = Запрос.Выполнить().Выгрузить();
    
    Для Каждого Строка Из ТаблицаДанных Цикл
        НоваяСтрока = Объект.Товары.Добавить();
        НоваяСтрока.Номенклатура = Строка.Номенклатура;
    КонецЦикла;
    
КонецПроцедуры

Исправленный вариант 3: С обработкой ошибок

&НаСервере
Процедура ЗаполнитьТовары()
    
    Попытка
        Запрос = Новый Запрос;
        Запрос.Текст = 
        "ВЫБРАТЬ
        |    Номенклатура
        |ИЗ
        |    Справочник.Номенклатура
        |ГДЕ
        |    НЕ ПометаУдаления";
        
        Выборка = Запрос.Выполнить().Выбрать();
        
        Пока Выборка.Следующий() Цикл
            НоваяСтрока = Объект.Товары.Добавить();
            НоваяСтрока.Номенклатура = Выборка.Номенклатура;
        КонецЦикла;
        
        ЗаписьЖурнала("ЗаполнениеТоваров", ТипСобытияЖурналаРегистрации.Информация, , , 
                      "Товары успешно заполнены");
        
    Исключение
        ЗаписьЖурнала("ЗаполнениеТоваров", ТипСобытияЖурналаРегистрации.Ошибка, , , 
                      ОписаниеОшибки());
        ВызватьИсключение();
    КонецПопытки;
    
КонецПроцедуры

Краткая таблица ошибок

ОшибкаПричинаИсправление
&НаКлиентеЗапрос работает только на сервереИспользовать &НаСервере
Для каждого Из РезультатРезультатЗапроса не итерируется такИспользовать .Выбрать() или .Выгрузить()
Строка.НоменклатураЭто поле не выбрано в запросеДобавить в SELECT или исправить имя поля
Отсутствие обработки ошибокНеопределённое поведениеДобавить Попытка/Исключение

Итог

Основные ошибки в коде:

  1. Контекст выполнения — запрос должен быть на сервере
  2. Итерирование результата — нужно использовать .Выбрать() или .Выгрузить()
  3. Доступ к полям — только к выбранным в запросе полям
  4. Отсутствие обработки ошибок — всегда добавляй Попытка/Исключение
Поиск ошибок в коде | PrepBro