Как исправить ошибку «Несоответствие типов» при проверке заполнения реквизитов формы?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Разбор основной причины ошибки

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


Сообщение1 = Новый СообщениеПользователю;
Сообщение1.Текст = "Неправильно заполнено";
Сообщение1.Поле = Сумма; // Ошибка здесь
Сообщение1.Сообщить();

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

В приведенном примере, если в переменной Сумма находится число (например, 100), система пытается присвоить число строковому свойству, что и вызывает «Несоответствие типов». Правильный подход выглядит так:

Сообщение1.Поле = "Сумма";

Аналогично для реквизита Период: вместо передачи объекта периода, нужно передать строку с его названием: Сообщение2.Поле = "Период";.

Особенности проверки типа «СтандартныйПериод»

Проанализируем вторую важную деталь. Если ваш реквизит Период имеет тип СтандартныйПериод, стандартная функция ЗначениеЗаполнено() может работать не так, как ожидается. Объект этого типа инициализируется сразу, поэтому он формально всегда «заполнен», даже если пользователь не выбрал конкретные даты начала и окончания.

Чтобы корректно проверить, указал ли пользователь временной интервал, необходимо обращаться к конкретным свойствам этого объекта:

  1. Проверка даты начала: ЗначениеЗаполнено(Период.ДатаНачала)
  2. Проверка даты окончания: ЗначениеЗаполнено(Период.ДатаОкончания)

Если вы хотите привязать сообщение об ошибке непосредственно к одному из полей ввода дат внутри стандартного периода, путь к данным в свойстве Поле должен выглядеть так: "Период.ДатаНачала".

Оптимизация логики условий

Посмотрим на логические условия в исходном коде автора. Конструкция вида Не Сумма > 99999 может быть интерпретирована системой неоднозначно из-за приоритетов операторов. В 1С оператор Не имеет очень высокий приоритет.

Рекомендуется использовать скобки для явного указания порядка действий или применять обратные операторы сравнения. Сравним два варианта:


// Вариант 1: Использование скобок
Если Не (Сумма > 99999) Тогда
    // логика ошибки
КонецЕсли;

// Вариант 2: Использование обратного условия (более читаемо)
Если Сумма <= 99999 Тогда
    // логика ошибки
КонецЕсли;

Использование стандартного механизма проверки заполнения

Вместо ручного написания функции ПроверкаЗаполнения с множеством условий Если...ИначеЕсли, платформа 1С предлагает встроенный и более надежный механизм. Рассмотрим, как его использовать:

  1. Настройка реквизитов: Установите у нужных реквизитов формы свойство «Проверка заполнения» в значение Выдавать ошибку.
  2. Вызов проверки: В коде команды (например, перед отправкой письма) вызовите метод ПроверитьЗаполнение().

&НаКлиенте
Процедура ОтправитьПисьмо(Команда)
    
    // Этот метод автоматически проверит все реквизиты с пометкой "Выдавать ошибку"
    // и выведет стандартные сообщения пользователю
    Если Не ЭтотОбъект.ПроверитьЗаполнение() Тогда
        Возврат;
    КонецЕсли;
    
    ОтправитьПисьмоНаСервере();
    
КонецПроцедуры

Если же логика проверки сложная (например, проверка суммы в зависимости от периода), следует использовать серверный обработчик ОбработкаПроверкиЗаполнения в модуле формы. В нем можно гибко управлять массивом ПроверяемыеРеквизиты, добавляя или удаляя их в зависимости от условий.

Итоговый исправленный пример кода

С учетом всех разобранных ошибок, приведем пример корректной функции для ручной проверки:


&НаКлиенте
Функция ПроверкаЗаполненияДанных()
    
    Успешно = Истина;
    
    // Проверка суммы
    Если Сумма <= 99999 Тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Сумма должна быть более 99 999";
        Сообщение.Поле = "Сумма"; // Указываем имя реквизита строкой
        Сообщение.Сообщить();
        Успешно = Ложь;
    КонецЕсли;
    
    // Проверка периода (если это СтандартныйПериод)
    Если Не ЗначениеЗаполнено(Период.ДатаНачала) Или Не ЗначениеЗаполнено(Период.ДатаОкончания) Тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Необходимо заполнить период полностью";
        Сообщение.Поле = "Период"; 
        Сообщение.Сообщить();
        Успешно = Ложь;
    КонецЕсли;
    
    Возврат Успешно;
    
КонецФункции

Важный момент: использование переменной Успешно вместо немедленного возврата Ложь позволяет пользователю увидеть сразу все ошибки на форме за один цикл проверки, что значительно повышает удобство работы с программой.

← На главную