При разработке и подключении печатных форм во внешних обработках разработчики 1С часто сталкиваются с ошибкой: «Ошибка при вызове метода контекста (ЧислоПрописью)... по причине: Несоответствие типов (параметр номер '1')». Проанализируем причину возникновения этой проблемы и разберем варианты её решения.
Встроенная функция платформы 1С ЧислоПрописью() имеет жесткое ограничение: первый параметр обязательно должен иметь числовой тип данных. Если передать значение типа Неопределено, NULL, Строка или Булево, платформа сгенерирует исключение о несоответствии типов.
Рассмотрим распространенную ситуацию в коде печатной формы:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ЧасоваяСтавкаПоКлиенту.СтавкаРуб
|ИЗ
| РегистрСведений.ЧасоваяСтавкаПоКлиенту КАК ЧасоваяСтавкаПоКлиенту
|ГДЕ
| ЧасоваяСтавкаПоКлиенту.Партнер = &Партнер";
Запрос.УстановитьПараметр("Партнер", Договоры.Партнер);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
ЧислоПрописью = ЧислоПрописью(Выборка.СтавкаРуб, "Л=ru_RU;ДП=Истина;");
На первый взгляд кажется, что из реквизита СтавкаРуб выбирается число. Однако, если условие в ГДЕ не находит совпадений (например, параметр &Партнер передан некорректно или записей в регистре для данного клиента нет), запрос возвращает пустой результат. В этом случае вызов Выборка.Следующий() не позиционируется на записи, а обращение Выборка.СтавкаРуб возвращает значение Неопределено.
Для диагностики типа передаваемого значения в отладчике или с помощью функции Сообщить() используем функцию ТипЗнч(). Важно устанавливать отладочный вывод строго до вызова функции ЧислоПрописью(), так как до строки после ошибки выполнение кода просто не дойдет:
Сообщить(ТипЗнч(Выборка.СтавкаРуб)); // Выведет "Неопределено"
ЧислоПрописью = ЧислоПрописью(Выборка.СтавкаРуб, "Л=ru_RU;ДП=Истина;");
Разберем по шагам несколько способов гарантированного предотвращения данной ошибки при формировании печатных форм.
Всегда проверяйте результат выполнения метода Выборка.Следующий() с помощью условного оператора Если ... Тогда:
Если Выборка.Следующий() Тогда
Ставка = Выборка.СтавкаРуб;
Иначе
Ставка = 0;
КонецЕсли;
ЧислоПрописью = ЧислоПрописью(Ставка, "Л=ru_RU;ДП=Истина;");
Чтобы убедиться, что переменная содержит именно числовое значение, выполним явную проверку типа с помощью функции ТипЗнч():
Если ТипЗнч(Выборка.СтавкаРуб) = Тип("Число") Тогда
Ставка = Выборка.СтавкаРуб;
Иначе
Ставка = 0;
КонецЕсли;
ЧислоПрописью = ЧислоПрописью(Ставка, "Л=ru_RU;ДП=Истина;");
При использовании левых соединений или группировок значение в выборке может принимать значение NULL. На уровне текста запроса рекомендуется оборачивать выбираемые числовые поля в функцию ЕСТЬNULL():
ВЫБРАТЬ
ЕСТЬNULL(ЧасоваяСтавкаПоКлиенту.СтавкаРуб, 0) КАК СтавкаРуб
ИЗ
РегистрСведений.ЧасоваяСтавкаПоКлиенту КАК ЧасоваяСтавкаПоКлиенту
ГДЕ
ЧасоваяСтавкаПоКлиенту.Партнер = &Партнер
Эти проверки гарантируют корректную работу печатных форм и предотвращают аварийное завершение программы при отсутствии данных в информационной базе.