Как вывести число прописью в печатной форме 1С и исправить сопутствующие ошибки

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

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

Почему функцию «ЧислоПрописью» нельзя использовать внутри запроса?

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

Язык запросов 1С транслируется платформой в SQL-запросы, которые выполняются непосредственно на сервере СУБД (Microsoft SQL Server, PostgreSQL, IBM DB2 или Oracle). СУБД оперирует только стандартными типами данных (числа, строки, даты, булево) и не содержит встроенных механизмов для сложного морфологического разбора и склонения числительных по правилам русского (или любого другого) языка.

Преобразование числовых значений в текстовые эквиваленты всегда выполняется на более поздних этапах обработки данных:

  1. В коде встроенного языка при обходе выборки результатов запроса и заполнении параметров макета.
  2. В Системе компоновки данных (СКД) на уровне вычисляемых полей или выражений представления с использованием функций встроенного языка.

Давайте подробно рассмотрим, как правильно реализовать первый (классический) вариант в коде формирования печатной формы.

Разбор практического примера и исправление ошибок в коде

Проанализируем исходную задачу. У нас есть документ Salary (Зарплата), содержащий табличную часть со списком сотрудников и начисленной суммой в поле CheckW2. Нам необходимо вывести эти данные в печатную форму чека, преобразовав сумму в текстовый формат.

Рассмотрим структуру кода обхода выборки, где часто совершают ошибки начинающие разработчики:


// НЕКОРРЕКТНЫЙ ФРАГМЕНТ КОДА
Пока ВыборкаSalary.Следующий() Цикл
    ОбластьSalary.Параметры.Заполнить(ВыборкаSalary);
    // Попытка присвоить значение прописи, обращаясь к выборке документа, а не табличной части:
    ОбластьSalary.Параметры.CheckW2 = ЧислоПрописью(Выборка.CheckW2, , ",,,,,,,,2" );
    ТабДок.Вывести(ОбластьSalary, ВыборкаSalary.Уровень());
КонецЦикла;

При запуске такого кода система выдаст ошибку выполнения: Поле объекта не обнаружено (CheckW2). Выясним причину ее возникновения.

В документе присутствует двухэтапный обход данных. Первый цикл (внешний) обходит выборку документов (переменная Выборка). Второй цикл (внутренний) обходит строки табличной части этого документа (переменная ВыборкаSalary). Реквизит CheckW2 принадлежит строке табличной части, а не шапке документа.

Следовательно, обращаться к реквизиту во внутреннем цикле нужно строго через переменную внутренней выборки — ВыборкаSalary.CheckW2. Если обратиться к Выборка.CheckW2, платформа попытается найти это поле в шапке документа, не обнаружит его и завершит работу аварийно.

Также важно избегать случайных опечаток, таких как двойные точки (например, ВыборкаSalary..CheckW2), которые приводят к синтаксической ошибке на этапе компиляции модуля.

Исправленный и полностью работоспособный вариант кода выглядит следующим образом:


Процедура Check(ТабДок, Ссылка) Экспорт
    Макет = Документы.Salary.ПолучитьМакет("Check");
    Запрос = Новый Запрос;
    Запрос.Текст = "
    |ВЫБРАТЬ
    |    Salary.Ссылка КАК Ссылка,
    |    Salary.Номер КАК Номер,
    |    Salary.Дата КАК Дата,
    |    Salary.Salary.(
    |        Ссылка КАК Ссылка,
    |        НомерСтроки КАК НомерСтроки,
    |        Сотрудник КАК Сотрудник,
    |        CheckW2 КАК CheckW2
    |    ) КАК Salary
    |ИЗ
    |    Документ.Salary КАК Salary
    |ГДЕ
    |    Salary.Ссылка В (&Ссылка)";
    
    Запрос.Параметры.Вставить("Ссылка", Ссылка);
    Выборка = Запрос.Выполнить().Выбрать();
    
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    Шапка = Макет.ПолучитьОбласть("Шапка");
    ОбластьSalaryШапка = Макет.ПолучитьОбласть("SalaryШапка");
    ОбластьSalary = Макет.ПолучитьОбласть("Salary");
    
    ТабДок.Очистить();
    ВставлятьРазделительСтраниц = Ложь;
    
    Пока Выборка.Следующий() Цикл
        Если ВставлятьРазделительСтраниц Тогда
            ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;
        
        ТабДок.Вывести(ОбластьЗаголовок);
        Шапка.Параметры.Заполнить(Выборка);
        ТабДок.Вывести(Шапка, Выборка.Уровень());
        
        ТабДок.Вывести(ОбластьSalaryШапка);
        
        ВыборкаSalary = Выборка.Salary.Выбрать();
        Пока ВыборкаSalary.Следующий() Цикл
            // Сначала заполняем параметры стандартным образом
            ОбластьSalary.Параметры.Заполнить(ВыборкаSalary);
            
            // Затем переопределяем параметр суммы его текстовым представлением
            СуммаЧислом = ВыборкаSalary.CheckW2;
            ОбластьSalary.Параметры.CheckW2 = ЧислоПрописью(СуммаЧислом, , ",,,,,,,,2");
            
            ТабДок.Вывести(ОбластьSalary, ВыборкаSalary.Уровень());
        КонецЦикла;
        
        ВставлятьРазделительСтраниц = Истина;
    КонецЦикла;
КонецПроцедуры

Секреты синтаксиса функции «ЧислоПрописью» и лайфхак с запятыми

Рассмотрим синтаксис функции встроенного языка ЧислоПрописью(). Она имеет следующий формат описания:

ЧислоПрописью(Число, ФорматнаяСтрока, ПараметрыПредметаИсчисления)

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

"рубль, рубля, рублей, м, копейка, копейки, копеек, ж, 2"

Где первые четыре параметра описывают целую часть (название в ед. ч., род. падеже ед. ч., род. падеже мн. ч. и род), следующие четыре — дробную часть, а последний символ (цифра 2) задает разрядность округления.

Лайфхак с пустой форматной строкой ",,,,,,,,2":

Если в коде передать строку параметров в виде одних только запятых с двойкой на конце, платформа уберет текстовые названия валют (рубли и копейки), но сохранит правила вывода дробной части. Рассмотрим на примерах:

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

Альтернативный способ: использование форматной строки в макете

Профессиональные разработчики 1С стараются минимизировать объем ручного кода форматирования в модулях программных объектов. Платформа предоставляет мощную альтернативу — использование конструктора форматных строк прямо в ячейках макета.

Проанализируем этот метод пошагово:

  1. Откройте макет печатной формы (табличный документ) в конфигураторе.
  2. Выделите ячейку, в которую выводится сумма (например, ячейка с параметром CheckW2).
  3. Откройте палитру свойств этой ячейки (клавиша F4).
  4. Найдите категорию свойств «Оформление» и найдите в ней свойство «Формат».
  5. Нажмите на кнопку с тремя точками, чтобы открыть интерактивный конструктор форматной строки.
  6. В открывшемся окне перейдите на вкладку «Число» и установите галочку напротив пункта «Прописью» (код формата ЧП) или «Локальная пропись денежных сумм» (код формата ЧПДС).

В результате в свойстве «Формат» будет записано выражение вида ЧП или ЧПДС. При выводе этой области макета программный код упростится до предела:


Пока ВыборкаSalary.Следующий() Цикл
    // Платформа сама преобразует число в пропись на лету по правилам формата ячейки!
    ОбластьSalary.Параметры.Заполнить(ВыборкаSalary);
    ТабДок.Вывести(ОбластьSalary, ВыборкаSalary.Уровень());
КонецЦикла;

Это делает код более чистым, легко читаемым и упрощает последующую поддержку печатной формы, если требования заказчика к визуальному оформлению изменятся.

Использование функций Библиотеки Стандартных Подсистем (БСП)

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

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


// Пример использования механизмов БСП
ВалютаДокумента = Ссылка.Валюта; // Получаем ссылку на справочник "Валюты"
СуммаЧислом = ВыборкаSalary.CheckW2;

// Вызов стандартной функции БСП:
СуммаПрописью = РаботаСКурсамиВалют.СформироватьСуммуПрописью(СуммаЧислом, ВалютаДокумента);

ОбластьSalary.Параметры.CheckW2 = СуммаПрописью;

Преимущества использования БСП:

← На главную