Работа с ресурсами в 1С:Предприятие — одна из ключевых задач для разработчиков и администраторов. Часто возникает необходимость преобразовать ресурс (например, остаток товара, сумму документа или количество часов) в числовой формат для дальнейших расчетов, отчетов или интеграций. Однако не все знают, что в 1С ресурсы могут храниться в разных типах данных — от простых чисел до сложных объектов, и их корректное преобразование требует понимания механизмов платформы.
Эта статья поможет разобраться, как правильно выразить ресурс 1С числом, избегая типичных ошибок. Мы рассмотрим встроенные функции, методы объектов, особенности работы с виртуальными таблицами и регистрами, а также практические примеры для разных версий платформы. Особое внимание уделим нюансам, которые часто упускают даже опытные специалисты — например, обработке NULL-значений или различиям между Число() и ЗначениеЧисло().
Если вы сталкиваетесь с ошибками при попытке привести ресурс к числу или хотите оптимизировать код для работы с большими данными — здесь вы найдете готовые решения. А для тех, кто только начинает осваивать 1С, мы объясним базовые концепции на простых примерах.
1. Что такое ресурс в 1С и почему его нужно преобразовывать в число
В 1С:Предприятие ресурс — это поле, которое хранит данные в регистрах накопления, бухгалтерских регистрах или виртуальных таблицах. Ресурсы могут иметь разные типы:
- 📊 Числовые (например,
Количество,Сумма) - 🗓️ Дата/время (например,
ДатаОплаты) - 📄 Ссылочные (например,
Номенклатура) - 💰 Денежные (например,
СуммаДокументас привязкой к валюте)
Даже если ресурс визуально выглядит как число (например, 100 в поле Количество), в коде он может быть представлен как объект со своими методами и свойствами.
Преобразование ресурса в число необходимо в следующих случаях:
- 📈 Для математических операций (сложение, умножение, сравнение).
- 📊 Для построения отчетов с агрегацией данных (например, суммирование остатков).
- 🔄 Для интеграции с внешними системами, где требуется передача "чистых" данных.
- ⚡ Для оптимизации производительности (работа с примитивными типами быстрее, чем с объектами).
Пример: если вы получаете остаток товара из регистра накопления, то даже если в базе хранится число 15, в коде это может быть объект типа РегистрНакопленияОстатки.Количество. Попытка сложить его с обычным числом (15 + 5) приведет к ошибке.
Всегда проверяйте тип ресурса с помощью функции ТипЗнч() перед преобразованием. Это поможет избежать ошибок при работе с данными из разных источников.
2. Встроенные функции для преобразования ресурсов в числа
Платформа 1С:Предприятие предоставляет несколько способов преобразования ресурсов в числовой формат. Рассмотрим основные функции и их особенности:
1. Функция Число()
Самый универсальный метод, который пытается преобразовать любое значение в число. Работает с большинством типов ресурсов, но имеет нюансы:
- 🔢 Преобразует строки (например,
"100"→100). - 💰 Преобразует денежные значения, игнорируя валюту (например,
100 USD→100). - ❌ Возвращает
0для нечисловых значений (например,Число(Дата)вернет0).
КоличествоТоваров = Число(Регистр.Остатки.Количество);
2. Функция ЗначениеЧисло()
Более строгий аналог Число(), который выбрасывает исключение, если преобразование невозможно. Полезен для отладки:
СуммаЗаказа = ЗначениеЧисло(Документ.Сумма); // Ошибка, если Сумма не число
3. Метод .Получить() для регистров
При работе с регистрами накопления или бухгалтерии часто используют метод .Получить(), который возвращает числовое значение ресурса:
Остаток = РегистрыНакопления.ОстаткиТоваров.Остатки(
, Номенклатура, Склад
).Итог("Количество").Получить();
4. Приведение типов через ?
В последних версиях платформы (8.3.10+) поддерживается оператор приведения типов:
СуммаКакЧисло = ?(Документ.Сумма, "Число", 0);
Чем отличается Число() от ЗначениеЧисло()?
Функция Число() "прощает" ошибки и возвращает 0 для нечисловых значений, тогда как ЗначениеЧисло() генерирует исключение. Это делает первую функцию удобной для быстрых расчетов, а вторую — для строгой валидации данных.
3. Практические примеры преобразования ресурсов
Рассмотрим реальные сценарии, где требуется преобразование ресурсов в числа. Для каждого примера приведен код и пояснения.
Пример 1: Получение остатка товара из регистра накопления
Допустим, у нас есть регистр накопления ОстаткиТоваров с ресурсом Количество. Нужно получить остаток для конкретного товара и склада:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиТоваровОстатки.Количество КАК Остаток
|ИЗ
| РегистрНакопления.ОстаткиТоваров.Остатки(,
| Номенклатура = &Номенклатура,
| Склад = &Склад
| ) КАК ОстаткиТоваровОстатки";
Запрос.УстановитьПараметр("Номенклатура", СсылкаНаНоменклатуру);
Запрос.УстановитьПараметр("Склад", СсылкаНаСклад);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
ОстатокЧислом = Число(Выборка.Остаток); // Преобразуем в число
Сообщить("Остаток: " + ОстатокЧислом);
Иначе
Сообщить("Товар не найден на складе");
КонецЕсли;
Пример 2: Работа с денежными ресурсами
Если ресурс имеет тип "Денежный" (например, СуммаДокумента), его нужно преобразовать с учетом валют:
СуммаВРублях = Число(Документ.СуммаДокумента); // Простое преобразование (валюта игнорируется)
СуммаСУчетомКурса = Документ.СуммаДокумента.Сумма; // Получаем сумму в валюте документа
Пример 3: Преобразование виртуальных таблиц
При работе с виртуальными таблицами (например, РегистрНакопления.Обороты) ресурсы возвращаются как объекты. Их нужно явным образом преобразовывать:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РегистрНакопления.Продажи.Обороты.Количество КАК Продано
|ИЗ
| РегистрНакопления.Продажи.Обороты(,
| Номенклатура = &Номенклатура,
| Период = &Дата
| ) КАК РегистрНакопления_Продажи_Обороты";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
ОбщееКоличество = 0;
Пока Выборка.Следующий() Цикл
ОбщееКоличество = ОбщееКоличество + Число(Выборка.Продано); // Суммируем числа
КонецЦикла;
☑️ Проверка перед преобразованием ресурса
4. Типичные ошибки и как их избежать
При преобразовании ресурсов в числа разработчики часто сталкиваются с ошибками, которые сложно диагностировать. Вот наиболее распространенные из них:
1. Проблема с NULL-значениями
Если ресурс не заполнен (например, для товара нет остатков), функция Число(NULL) вернет 0. Это может привести к искажению данных в отчетах. Решение — явная проверка:
Остаток = Если(Выборка.Остаток = NULL, 0, Число(Выборка.Остаток));
2. Потеря точности при работе с денежными типами
Если ресурс имеет тип "Денежный" с высокой точностью (например, 4 знака после запятой), простое преобразование через Число() может округлить значение. Используйте свойство .Сумма:
ТочнаяСумма = Документ.СуммаДокумента.Сумма; // Сохраняет точность
3. Ошибки при работе с виртуальными таблицами
Виртуальные таблицы регистров возвращают объекты, а не примитивные типы. Попытка сложить их напрямую приведет к ошибке:
// НЕПРАВИЛЬНО:
СуммаОборотов = Выборка.Оборот1 + Выборка.Оборот2; // Ошибка!
// ПРАВИЛЬНО:
СуммаОборотов = Число(Выборка.Оборот1) + Число(Выборка.Оборот2);
4. Разные типы ресурсов в одном запросе
Если в запросе смешаны ресурсы разных типов (например, Количество и Сумма), их нужно преобразовывать отдельно:
Количество = Число(Выборка.Количество);
Сумма = Число(Выборка.Сумма);
Всегда проверяйте результат преобразования на корректность, особенно если данные поступают из внешних источников или пользовательского ввода.
5. Оптимизация производительности при работе с ресурсами
Преобразование ресурсов в числа может влиять на производительность, особенно при работе с большими объемами данных. Вот несколько советов для оптимизации:
1. Используйте массовое преобразование
Если вам нужно преобразовать много значений (например, в цикле), лучше сделать это за один проход:
МассивЧисел = Новый Массив;
Для Каждого Элемент Из КоллекцияРесурсов Цикл
МассивЧисел.Добавить(Число(Элемент.Значение));
КонецЦикла;
2. Избегайте лишних преобразований
Если ресурс уже является числом (проверьте через ТипЗнч()), не преобразуйте его повторно:
Если ТипЗнч(Ресурс) = Тип("Число") Тогда
Результат = Ресурс;
Иначе
Результат = Число(Ресурс);
КонецЕсли;
3. Используйте временные таблицы
При работе с большими запросами временные таблицы позволяют один раз преобразовать ресурсы и дальше работать с "чистыми" данными:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Число(Ресурс1) КАК Ресурс1Число,
| Число(Ресурс2) КАК Ресурс2Число
|ПОМЕСТИТЬ ВТ_Ресурсы
|ИЗ ......";
4. Кэшируйте результаты преобразований
Если одно и то же значение ресурса используется многократно, сохраните его после первого преобразования:
Если НЕ ЗначениеЗаполнено(КэшРесурсов[ИмяРесурса]) Тогда
КэшРесурсов[ИмяРесурса] = Число(ПолучитьРесурс(ИмяРесурса));
КонецЕсли;
Для критических участков кода используйте профилировщик 1С, чтобы определить, где именно происходят задержки при преобразовании ресурсов.
6. Особенности работы с ресурсами в разных версиях 1С
Механизмы работы с ресурсами могут отличаться в зависимости от версии платформы 1С:Предприятие. Рассмотрим ключевые различия:
| Версия платформы | Особенности работы с ресурсами | Рекомендации |
|---|---|---|
| 1С:Предприятие 8.2 | Отсутствует оператор ? для приведения типов. Функция ЗначениеЧисло() работает медленнее. |
Используйте Число() с явной проверкой типов. |
| 1С:Предприятие 8.3.6–8.3.9 | Появилась поддержка виртуальных таблиц с улучшенной производительностью, но ресурсы все еще возвращаются как объекты. | Преобразуйте ресурсы сразу в запросе через ВЫРАЗИТЬ(...) КАК ЧИСЛО. |
| 1С:Предприятие 8.3.10+ | Добавлен оператор ? для приведения типов. Улучшена работа с NULL-значениями. |
Используйте современный синтаксис: ?(Ресурс, "Число"). |
| 1С:Предприятие 8.3.18+ | Оптимизирована работа с денежными ресурсами. Метод .Сумма работает быстрее. |
Для денежных значений отдавайте предпочтение .Сумма вместо Число(). |
Если вы работаете с устаревшими версиями (например, 1С 7.7), механизмы преобразования будут принципиально другими — там используются функции вроде Используйте глобальный контекст Val() или ЧислоИзСтроки(). Однако в современных проектах такие версии практически не встречаются.
Как узнать версию платформы в коде?
ПлатформаВерсия() или проверьте свойство Константы.ВерсияПлатформы (если оно заполнено).
7. Альтернативные способы работы с ресурсами
Иногда преобразование ресурса в число не является оптимальным решением. Рассмотрим альтернативные подходы:
1. Работа с ресурсами как с объектами
Если ресурс имеет сложную структуру (например, включает валюту, единицы измерения), лучше работать с ним через методы объекта:
// Вместо:
СуммаВРублях = Число(Документ.СуммаДокумента) * КурсВалюты;
// Лучше:
СуммаВРублях = Документ.СуммаДокумента.СуммаВВалюте(ВалютаРуб);
2. Использование агрегирующих функций в запросах
Многие операции (например, суммирование) можно выполнить прямо в запросе, избегая преобразований:
Запрос.Текст =
"ВЫБРАТЬ
| СУММА(Число(Ресурс)) КАК Итого
|ИЗ ...";
3. Работа с наборами записей
При записи данных в регистры используйте наборы записей — они автоматически преобразуют числа в нужный формат:
НаборЗаписей = РегистрыНакопления.ОстаткиТоваров.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Номенклатура.Установить(СсылкаНаНоменклатуру);
НаборЗаписей.Прочитать();
Запись = НаборЗаписей.Добавить();
Запись.Количество = 100; // Здесь можно присвоить число напрямую
НаборЗаписей.Записать();
4. Использование временных таблиц для промежуточных расчетов
Если нужно выполнить сложные расчеты, создайте временную таблицу с уже преобразованными данными:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Число(Ресурс1) КАК Ресурс1Число
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ ...";
Альтернативные способы часто позволяют избежать лишних преобразований и ускорить выполнение кода, особенно в больших системах.
8. Частые вопросы и ответы
Можно ли преобразовать ресурс типа "Ссылка" в число?
Нет, ссылки (например, на номенклатуру или документ) нельзя напрямую преобразовать в число. Однако можно получить числовой идентификатор ссылки через метод .УникальныйИдентификатор():
ИдНоменклатуры = СсылкаНаНоменклатуру.УникальныйИдентификатор();
Это не то же самое, что преобразование в число, но позволяет использовать ссылки в числовых операциях (например, для сравнения).
Почему при преобразовании денежного ресурса теряется валюта?
Функция Число() извлекает только числовое значение, игнорируя привязку к валюте. Если валюта важна, используйте свойства объекта:
Сумма = Документ.СуммаДокумента.Сумма; // Числовое значение
Валюта = Документ.СуммаДокумента.Валюта; // Ссылка на валюту
Как преобразовать ресурс, если он может быть NULL?
Используйте конструкцию с проверкой или функцию ЗначениеЗаполнено():
Остаток = Если(ЗначениеЗаполнено(Ресурс), Число(Ресурс), 0);
В новых версиях платформы можно использовать оператор ?:
Остаток = ?(Ресурс, "Число", 0);
В чем разница между Число() и ЗначениеЧисло()?
Число() пытается преобразовать любое значение, возвращая 0 для нечисловых типов. ЗначениеЧисло() строже — она генерирует исключение, если преобразование невозможно. Пример:
Число("100р") // Вернет 0
ЗначениеЧисло("100р") // Выбросит ошибку
Можно ли преобразовать ресурс типа "Дата" в число?
Да, но результат будет зависеть от контекста. Функция Число() вернет количество дней с 1 января 0001 года:
ДатаКакЧисло = Число(ТекущаяДата()); // Например, 738575 (для 01.01.2023)
Для получения отдельных компонентов даты (год, месяц, день) используйте методы объекта Дата:
Год = ТекущаяДата().Год();
Если вам часто приходится преобразовывать ресурсы, создайте общую функцию-обертку с обработкой всех нюансов (NULL, типы, точность). Это сэкономит время и уменьшит количество ошибок.