Как в запросе получить курсы валют на даты документов?
Доброго дня всем! Есть следующий запрос:
ВЫБРАТЬ
СУММА(ОплатаПоставщику.СуммаДокумента * КурсыВалютСрезПоследних.Курс) КАК СуммаДокумента,
СУММА(ОплатаПоставщику.СуммаЗатрат * КурсыВалютСрезПоследних.Курс) КАК СуммаЗатрат
ИЗ
Документ.ОплатаПоставщику КАК ОплатаПоставщику
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних КАК КурсыВалютСрезПоследних
ПО ОплатаПоставщику.ВалютаДокумента = КурсыВалютСрезПоследних.Валюта
ГДЕ
ОплатаПоставщику.Сделка = &Сделка
Но хотелось бы переводить суммы в рубли не по последнему курсу, а для каждого документа на его дату. Ума не приложу как это сделать и возможно ли? Заранее благодарен за все толковые советы!
да код не причем 100%
но если просишь.
Функция Импорт_Файла_ДБФ(Параметр)
ФайлБД = СоздатьОбъект(«XBase»);
Попытка
ФайлБД.ОткрытьФайл(Путь,,1);
Исключение
Предупреждение(Путь + РазделительСтрок + «Ошибка открытия файла!»);
Возврат 0;
КонецПопытки;
Если ФайлБД.Открыта() = 0 Тогда
Предупреждение(Путь + РазделительСтрок + «Ошибка открытия файла!» + РазделительСтрок + «Возможно, файл используется другим приложением.»);
Возврат 0;
КонецЕсли;
ФайлБД.КодоваяСтраница(2-Кодировка);
ФайлБД.Первая();
Пока (ФайлБД.вКонце() = 0) Цикл
Если ФайлБД.ЗаписьУдалена() = 1 Тогда
ФайлБД.Следующая();
Продолжить;
КонецЕсли;
Состояние(«Обрабатывается строка №» + ФайлБД.НомерЗаписи());
ДатаОплаты = СокрЛП(ФайлБД.DATA);
ДатаОплаты = Дата(Число(Сред(ДатаОплаты,7,4)),Число(Сред(ДатаОплаты,4,2)),Число(Сред(ДатаОплаты,1,2)));
ВЫБРАТЬ
СУММА(таб1.СуммаДокумента * таб2.Курс) КАК СуммаДокумента,
СУММА(таб1.СуммаЗатрат * таб2.Курс) КАК СуммаЗатрат
ИЗ
(ВЫБРАТЬ
ОплатаПоставщику.Ссылка КАК СсылкаДок,
ОплатаПоставщику.СуммаДокумента,
ОплатаПоставщику.СуммаЗатрат,
ОплатаПоставщику.Дата КАК ДатаДок,
ОплатаПоставщику.ВалютаДокумента КАК ВалютаДок,
МАКСИМУМ(Валюты.Период) КАК ПериодДок
ИЗ
Документ.ОплатаПоставщику КАК ОплатаПоставщику
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Валюты
ПО Валюты.Период <= ОплатаПоставщику.Дата И
Валюты.Валюта = ОплатаПоставщику.ВалютаДокумента
СГРУППИРОВАТЬ ПО
ОплатаПоставщику.Ссылка) КАК Таб1
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Таб2
ПО Таб1.ПериодДок = Таб2.Период И Таб1.ВалютаДок = Таб2.Валюта
теперь возми и обдумай всё ето
да код не причем 100%
но если просишь.
Функция Импорт_Файла_ДБФ(Параметр)
ФайлБД = СоздатьОбъект(«XBase»);
Попытка
ФайлБД.ОткрытьФайл(Путь,,1);
Исключение
Предупреждение(Путь + РазделительСтрок + «Ошибка открытия файла!»);
Возврат 0;
КонецПопытки;
Если ФайлБД.Открыта() = 0 Тогда
Предупреждение(Путь + РазделительСтрок + «Ошибка открытия файла!» + РазделительСтрок + «Возможно, файл используется другим приложением.»);
Возврат 0;
КонецЕсли;
ФайлБД.КодоваяСтраница(2-Кодировка);
ФайлБД.Первая();
Пока (ФайлБД.вКонце() = 0) Цикл
Если ФайлБД.ЗаписьУдалена() = 1 Тогда
ФайлБД.Следующая();
Продолжить;
КонецЕсли;
Состояние(«Обрабатывается строка №» + ФайлБД.НомерЗаписи());
ДатаОплаты = СокрЛП(ФайлБД.DATA);
ДатаОплаты = Дата(Число(Сред(ДатаОплаты,7,4)),Число(Сред(ДатаОплаты,4,2)),Число(Сред(ДатаОплаты,1,2)));
Если (ДатаОплаты <> Параметр.Получить(«ДатаДок»)) или (СокрЛП(ФайлБД.KL_CHK) <> РСчет) или (Цел(ФайлБД.CUR_ID) <> 980) Тогда
ФайлБД.Следующая();
Продолжить;
КонецЕсли;
Если ФайлБД.DK = 1 Тогда // расход
Сп = СоздатьОбъект(«СписокЗначений»);
Сп.Установить(«Расход», ФайлБД.S);
Сп.Установить(«Приход», 0);
ИначеЕсли ФайлБД.DK = 0 Тогда // приход
(10) Ваш запрос дал цифры в 33 раза больше 🙂
а запрос
ВЫБРАТЬ
СУММА(ОплатаПоставщику.СуммаДокумента * КурсыВалют.Курс) КАК Оплата,
СУММА(ОплатаПоставщику.СуммаЗатрат * КурсыВалют.Курс) КАК Затраты
ИЗ
РегистрСведений.КурсыВалют КАК КурсыВалют
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОплатаПоставщику КАК ОплатаПоставщику
ПО (ОплатаПоставщику.ВалютаДокумента = КурсыВалют.Валюта)
И (ОплатаПоставщику.Дата = КурсыВалют.Период)
ГДЕ
ОплатаПоставщику.Сделка = &Сделка
Вообще ничего не дал. 🙁
(0) автор, вот тебе поясняющий мануал «на пальцах» /код писать не буду/:
1) выбрать все различные даты документов и валюты из самих документов,
получится табличка
————-
Дата | Валюта
————-
01.01 USD
10.01 USD
15.01 EUR
2) присоединить к этому по валюте регистр сведений курсов, так:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК Валюты
ПО Валюты.Период <= Док.Дата И
Валюты.Валюта = Док.ВалютаДокумента
—————————
Дата | Валюта | ДатаКурса
—————————
01.01 USD 01.01
10.01 USD 01.01
10.01 USD 05.01
10.01 USD 07.01
15.01 EUR 01.01
15.01 EUR 08.01
3) группируем по «валюта, дата» и добавляем ДатаКурса = MAX(Валюты.Период),
получим дату реальной записи в рег. сведений
—————————
Дата | Валюта | ДатаКурса
—————————
01.01 USD 01.01
10.01 USD 07.01
15.01 EUR 08.01
4) присоединяем сам курс из рег. сведений (не срез!) на дату «ДатаКурса».
Готово.
Как собирать разные части — твое дело, хочешь — через временные таблицы, хочешь — оборачивай в подзапросы. Не принципиально.
Как получить значение курса валюты на дату документа?
( дата — это Началопериода(&Период, "ДЕНЬ") ) в СКД,
то ответ есть на любой день.
если пишу в обработке
Плагин курса валюты на определенную дату?
Есть плагин который в определенное место каждого поста (или в сайдбар но для каждого поста своя.
Получить курс валюты на заданную дату используя xml
Всем привет! ЦБР предоставляет возможность получить курс валюты на заданную дату используя xml.
Как правильнее получить дату документа
Друзья! Прошу помощи! Есть документ ПередачаОбъектаВПрокат, который выполняет движения с видом.
Пересчет курса валюты. Как сделать?
Люди,ПОМОГИТЕ. Есть таблица продукта, в поле ‘price’ забита цена. Но цена в евро. Надо, чтоб на.
Срез последних на каждую дату
В базе создан документ «РеализацияТоваровУслуг», в шапке которого есть реквизит «Валюта». Запросом требуется для каждого документа получить актуальный курс валюты из шапки на дату документа. Хранение курсов валют осуществляется в периодическом регистре сведений « КурсыВалют «.
Решением «в лоб» этой задачи мог бы быть запрос в цикле: получение всех документов с их датами и валютой и в выборке обращение к виртуальной таблице среза последних регистра «КурсыВалют». Но т.к. запрос в цикле — это «плохо», попробуем реализовать задачу одним запросом .
Решение
Для решения задачи будем использовать факт, что таблицы в запросе можно соединять не только на равенство полей.
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка,
РеализацияТоваровУслуг.Валюта,
МАКСИМУМ(КурсыВалют.Период) КАК Период
ПОМЕСТИТЬ ВТПериодыУстановкиКурсов
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО РеализацияТоваровУслуг.Валюта = КурсыВалют.Валюта
И РеализацияТоваровУслуг.Дата >= КурсыВалют.Период
СГРУППИРОВАТЬ ПО
РеализацияТоваровУслуг.Ссылка,
РеализацияТоваровУслуг.Валюта
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТПериодыУстановкиКурсов.Ссылка,
ВТПериодыУстановкиКурсов.Валюта,
КурсыВалют.Курс
ИЗ
ВТПериодыУстановкиКурсов КАК ВТПериодыУстановкиКурсов
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО ВТПериодыУстановкиКурсов.Период = КурсыВалют.Период
И ВТПериодыУстановкиКурсов.Валюта = КурсыВалют.Валюта
1с запрос курс валют на дату документа
В базе создан документ «РеализацияТоваровУслуг», в шапке которого есть реквизит «Валюта». Запросом требуется для каждого документа получить актуальный курс валюты из шапки на дату документа. Хранение курсов валют осуществляется в периодическом регистре сведений « КурсыВалют «.
Решением «в лоб» этой задачи мог бы быть запрос в цикле: получение всех документов с их датами и валютой и в выборке обращение к виртуальной таблице среза последних регистра «КурсыВалют». Но т.к. запрос в цикле — это «плохо», попробуем реализовать задачу одним запросом .
Решение
Для решения задачи будем использовать факт, что таблицы в запросе можно соединять не только на равенство полей.
Порядок действий в запросе:
- Получение для каждого документа периода установки курса валюты. Документы соединяются с ФИЗИЧЕСКОЙ таблицей «КурсыВалют». Здесь следует обратить внимание на условия соединения. Валюты должны быть равны, а дата документа >= периоду регистра сведений.
В результате такого соединения для каждого документа будет получено множество строк, удовлетворяющих условию: все записи курсов по валюте документа, установленные не позже даты документа.
Завершающим этапом будет группировка строк с получением максимального периода курса. В результате для каждого документа будет получен требуемый период установки курса для нужной валюты (максимальная дата установки курса валюты, но не больше даты документа). Результат помещается во временную таблицу ВТПериодыУстановкиКурсов. - Получение курса. Временная таблица ВТПериодыУстановкиКурсов соединяется с ФИЗИЧЕСКОЙ таблицей «КурсыВалют». Соединение происходит по Валюте документа и периоду установки курса, определенному во второй временной таблице.
Остались вопросы?
Спросите в комментариях к статье.
Автор: Admin Февраль 21, 2019 1 комментарий
Часто на собеседованиях я задаю программистам вопрос: опишите алгоритм запроса получения курсов валют на даты документов, присутствующих в выборке для нижеуказанной ситуации.
Есть регистр сведений “Курсы валют”:
И список документов на даты которых в одном запросе нужно получить курсы:
Документы зарплата сотрудника
И тут у многих программистов возникают проблемы. Если бы регистр сведений “Курсы валют” имел бы значения на каждую дату, то почти все бы справились с помощью левого соединения. Но “пробелы” в регистре заставляют большую часть соискателей уйти в бесконечные раздумья составления алгоритма.
Что бы у вас не возникало в дальнейшем таких проблем рассмотрим алгоритм запроса по блокам:
- Делаем выборку по нашим документам:
Не в первый раз стакиваюсь с ситуацией, когда в запросе требуется найти остатки не на фиксированную дату (параметр — один на весь отчет), а на произвольную, (когда дата остатков в каждой строке своя). Нашел статью, которая оказалась весьма полезна для меня, жаль что поздно, так как первый вариант пришлось придумать самому.
Примечание apas: Для получения остатков регистра накопления в первом варианте используем реальную таблицу регистра накопления и агрегатную функцию сумма(приход-расход) (требуется условие по виду движения) Второй вариант может быть полезен и в других случаях, когда виртуальная таблица задается только параметром и никак иначе (например виртуальная таблица «критерии отбора») |
Существует несколько способов получить нужные данные.
1.Непосредственно в запросе (через реальную таблицу регистра)
Способ подходит практически для любой ситуации, и поэтому наиболее универсален. Единственный, пожалуй, минус этого способа — если в отчете пользователю не требуется курс, то запрос быдет выбирать избыточные данные.
Вызов СрезПоследних() можно использовать только с передачей в него заранее готового значения даты, на которую требуется получить значения. Поэтому сабж делается через стыковку нескольких запросов —
основной, к нему стыкуется запрос по регистру сведений с условием по дате и поиском записи с маскимальной датой (периодом).
Для общего развития:
Что есть срез последних в платформе?
В зависимости от периодичности регистра (по времени, по позизии регистратора) ВТ разворачивается в следующий запрос:
1. По времени (год, месяц, . секунда)
2. По позиции регистратора
В данном случае нужно еще раз обернуть выборку
Все это можно увидеть посмотрев технологический журнал с включенным режимом протоколирования запросов
2.Система компоновки данных (передача набора значений одной таблицы в параметр виртуальной таблицы)
Данный способ подходит для отчетов. Из очевидных плюсов — если курс (или другие данные) не нужны для построения отчета, то СКД не будет их получать. Однако быстродействие такого отчета может оказаться и несколько ниже, чем в первом способе.
Для примера сделаем отчет — список заказов покупателей.
Для этого создадим набор данных «Документы» — запрос:
Для того, чтобы потом успешно свзать наборы данных, в запрос необходимо включить поля «Дата» и «ВалютаДокумента». Чтобы они не появлялись в списке доступных полей, если это необходимо, их можно убрать, установив флажки ограничений в таблице «Поля» схемы компоновки. В остальном запрос вряд ли требует комментариев.
Для того, чтобы получить информацию о курсах валют, добавим второй набор данных-запрос, «Курсы валют»:
В этом запросе имеются 2 параметра: «Дата» и «Валюта». Эти параметры будут установлены СКД при соединении наборов. Кроме того, параметр «Дата» указан в выбранных полях — это нужно для соединения таблиц.
Для ненужный полей «Дата» и «Валюта» также устанавливаем флажки ограничений, чтобы они не появлялись в доступных полях.
Перейдем к соединению наборов. На странице «Связи наборов данных» добавим 2 связи:
1. Источник связи — набор «Документы», приемник — набор «Курсы валют». Выражение источник — «Дата», выражение приемник — «Дата», Параметр — «Дата»
2. Источник связи — набор «Документы», приемник — набор «Курсы валют». Выражение источник — «ВалютаДокумента», выражение приемник — «Валюта», Параметр — «Валюта»
Главное здесь — параметры связи. При соединении наборов данных, если указан параметр, СКД передает в подчиненный набор (в нашем случае — запрос «Курсы валют») параметры, указанные в соединении. Значениями параметров будут значения соответствующих полей набора-источника.
Перейдем к вычисляемым полям. Добавим вычисляемое поле «СуммаВВалютеУпрУчета». Выражение поля — «СуммаДокумента * Курс / Кратность».
Также укажем поля «СуммаДокумента» и «СуммаВВалютеУпрУчета» как ресурсы
Настроим отчет.
Добавим одну группировку «Детальные записи», в выбранных полях укажем «ЗаказПолкупателя», «Курс» и «Кратность». Добавим ресурсы «СуммаДокумента» и «СуммаВВалютеУпрУчета»