При развитии бизнеса часто возникает ситуация, когда привычный управленческий учет в одной валюте перестает удовлетворять потребности компании. Если раньше в регистре ОборотыТоваров было достаточно измерений Товар и Фирма, то с появлением валютных операций структура данных требует серьезной переработки. Разберем по шагам, как правильно изменить структуру регистра, обеспечить корректность итогов и вывести данные в отчет так, чтобы суммы в разных валютах не превратились в «математическую кашу».
Первый вопрос, который возникает у разработчика: куда добавить валюту — в измерения или в реквизиты регистра оборотов? Проанализируем последствия каждого выбора:
Валюта как измерение, система 1С 7.7 автоматически поддерживает итоги в разрезе каждой валюты. Это идеальный вариант для построения отчетов через объект Запрос. Вы сможете легко группировать данные по валюте и получать корректные суммы по каждой из них.Рекомендация: Для полноценного учета и получения итогов по валютам всегда выбирайте создание нового измерения с типом Справочник.Валюты.
Одной лишь добавленной валюты недостаточно. Рассмотрим ситуацию: у вас есть продажа на 100 рублей и на 100 долларов. Если в регистре всего один ресурс Сумма, система посчитает общий итог как 200. Это логическая ошибка. Чтобы отчет был информативным, проанализируем необходимость внедрения двух ресурсов:
Валюта.Такая структура позволит вам в одном отчете видеть и реальные деньги во взаиморасчетах с покупателем, и общую финансовую картину в едином эквиваленте.
После добавления нового измерения в конфигураторе важно помнить: во всех старых записях регистра поле Валюта окажется пустым. Чтобы отчеты за прошлые периоды не «развалились», необходимо:
Валюта в существующих движениях (обычно это базовая валюта — рубли).Рассмотрим, как должен выглядеть текст запроса, чтобы получить данные с разделением по валютам. В отличие от кода из Сообщения 2, нам нужно убедиться, что функции суммирования работают корректно внутри группировок.
//{{ЗАПРОС(Сформировать)
|Период с ВыбНачПериода по ВыбКонПериода;
|Товар = Регистр.ОборотыТоваров.Товар;
|Валюта = Регистр.ОборотыТоваров.Валюта;
|Количество = Регистр.ОборотыТоваров.Количество;
|СуммаВал = Регистр.ОборотыТоваров.СуммаВал;
|СуммаУпр = Регистр.ОборотыТоваров.СуммаУпр;
|Функция ВсегоКол = Сумма(Количество);
|Функция ВсегоСуммаВал = Сумма(СуммаВал);
|Функция ВсегоСуммаУпр = Сумма(СуммаУпр);
|Группировка Товар без упорядочивания;
|Группировка Валюта;
|"//}}ЗАПРОС
При такой структуре запроса метод Запрос.Группировка(2) позволит нам переходить к итогам по каждой конкретной валюте внутри каждого товара.
Часто требуется вывести валюты не строками вниз, а колонками вправо. Для этого в 1С 7.7 вместо метода ВывестиСекцию() используется метод ПрисоединитьСекцию(). Разберем алгоритм вывода:
ВывестиСекцию("Товар").Валюта.Таб.ПрисоединитьСекцию("Валюта").Проанализируем пример кода для вывода таблицы:
Таб.ВывестиСекцию("Заголовок");
Пока Запрос.Группировка(1) = 1 Цикл // Группировка по Товару
Таб.ВывестиСекцию("Товар"); // Здесь только название товара
Запрос.ВначалоВыборки(2); // Сбрасываем выборку валют для текущего товара
Пока Запрос.Группировка(2) = 1 Цикл // Группировка по Валюте
// Заполняем данные секции: Запрос.ВсегоСуммаВал
Таб.ПрисоединитьСекцию("Валюта");
КонецЦикла;
КонецЦикла;
Важный нюанс: Если у разных товаров разный набор валют, колонки в таблице могут «поехать». Чтобы этого избежать, профессиональные разработчики сначала собирают все уникальные валюты за период в СписокЗначений или ТаблицуЗначений, формируют шапку отчета, а затем при выводе строк ищут соответствие данных конкретной колонке.
Чтобы получить итоги по валюте в конце отчета, нам нужно использовать метод СводныйИтог или повторно обойти запрос, но уже без привязки к товару. Посмотрим, как получить общий итог по конкретной валюте:
В тексте запроса у нас уже есть группировка Валюта. Если мы хотим вывести общие итоги в подвале отчета, мы можем использовать конструкцию:
// В конце процедуры после всех циклов по товарам
Таб.ВывестиСекцию("ПодвалЗаголовок");
Запрос.ВначалоВыборки(0); // Сброс на уровень общих итогов
Пока Запрос.Группировка("Валюта") = 1 Цикл
// Здесь Запрос.ВсегоСуммаВал вернет итог по валюте за весь период по всем товарам
Таб.ВывестиСекцию("ИтогоПоВалюте");
КонецЦикла;
Использование Запрос.ВначалоВыборки(0) позволяет переместить указатель запроса на верхний уровень и эффективно перебрать итоги по валютам, игнорируя иерархию товаров.
Мы выяснили, что для корректного разделения сумм в регистре оборотов 1С 7.7 необходимо использовать измерения для валют и, желательно, два ресурса для разделения валютной и управленческой суммы. При формировании отчета связка методов ВывестиСекцию() и ПрисоединитьСекцию() позволяет реализовать любую сложную структуру таблицы, а правильное использование уровней группировок запроса гарантирует точность итоговых данных.