Как получить курс валюты на дату документа в запросе 1с
Перейти к содержимому

Как получить курс валюты на дату документа в запросе 1с

  • автор:

Помощь в автоматизации учета

Обучение по 1С Предприятие 8, UA-Бюджет и т.п. Так же обучение по программированию 1С Предприятие 8 и интересные новости.

Страницы

  • Инструкции по 1С 8.3
  • Инструкции по UA-Бюджет/KBS
  • Хранилище файлов для 1С Предприятие 8
  • Хранилище файлов для UA-Бюджет/KBS
  • Заметки для программиста

Как создать запрос с выборкой курсов валют на каждый день.

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

По этому мы рассмотрим как создать запрос с подобной выборкой (выборка курса валюты на каждый день указанного периода).

  • Для начала выбрившим перечень дат за заданный период:

ВЫБРАТЬ
ДанныеПроизводственногоКалендаря.Дата КАК ДатаПериода
ПОМЕСТИТЬ ВТ_ДатыПериода
ИЗ
РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
ГДЕ
ДанныеПроизводственногоКалендаря.Дата МЕЖДУ &НачалоПериода И &КонецПериода

  • Теперь объединим полученную виртуальную таблицу с записями регистра сведений «Курсы валют», чтобы получить список валют со всеми датами за указанный период:

ВЫБРАТЬ
МАКСИМУМ(КурсыВалют.Период) КАК Период,
КурсыВалют.Валюта,
ВТ_ДатыПериода.ДатаПериода
ПОМЕСТИТЬ ВТ_ПериодыВалюты
ИЗ
ВТ_ДатыПериода КАК ВТ_ДатыПериода
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО ВТ_ДатыПериода.ДатаПериода>= КурсыВалют.Период
ГДЕ
КурсыВалют.Валюта = &Валюта

СГРУППИРОВАТЬ ПО
КурсыВалют.Валюта,
ВТ_ДатыПериода.ДатаПериода

  • И напоследок необходимо соединить таблицу «ВТ_ПериодыВалюты» с курсами валют из регистра сведений «Курсы валют»:

ВЫБРАТЬ
ВТ_ПериодыВалюты.Период,
ВТ_ПериодыВалюты.ДатаПериода,
ВТ_ПериодыВалюты.Валюта,
КурсыВалют.Курс,
КурсыВалют.Кратность
ИЗ
ВТ_ПериодыВалюты КАК ВТ_ПериодыВалюты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО ВТ_ПериодыВалюты.Валюта = КурсыВалют.Валюта
И ВТ_ПериодыВалюты.Период = КурсыВалют.Период

УПОРЯДОЧИТЬ ПО
ДатаПериода

В конечном итоге у нас получается запрос:

ВЫБРАТЬ
ДанныеПроизводственногоКалендаря.Дата КАК ДатаПериода
ПОМЕСТИТЬ ВТ_ДатыПериода
ИЗ
РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
ГДЕ
ДанныеПроизводственногоКалендаря.Дата МЕЖДУ &НачалоПериода И &КонецПериода
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
МАКСИМУМ(КурсыВалют.Период) КАК Период,
КурсыВалют.Валюта КАК Валюта,
ВТ_ДатыПериода.ДатаПериода КАК ДатаПериода
ПОМЕСТИТЬ ВТ_ПериодыВалюты
ИЗ
ВТ_ДатыПериода КАК ВТ_ДатыПериода
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО ВТ_ДатыПериода.ДатаПериода >= КурсыВалют.Период
ГДЕ
КурсыВалют.Валюта = &Валюта

СГРУППИРОВАТЬ ПО
КурсыВалют.Валюта,
ВТ_ДатыПериода.ДатаПериода
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ПериодыВалюты.Период КАК Период,
ВТ_ПериодыВалюты.ДатаПериода КАК ДатаПериода,
ВТ_ПериодыВалюты.Валюта КАК Валюта,
КурсыВалют.Курс КАК Курс,
КурсыВалют.Кратность КАК Кратность
ИЗ
ВТ_ПериодыВалюты КАК ВТ_ПериодыВалюты
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО ВТ_ПериодыВалюты.Валюта = КурсыВалют.Валюта
И ВТ_ПериодыВалюты.Период = КурсыВалют.Период

УПОРЯДОЧИТЬ ПО
ВТ_ПериодыВалюты.ДатаПериода

Данный текст тестировался на конфигурации «BAS Бухгалтерия ред. 2.1» .

Как в запросе получить курсы валют на даты документов?

Доброго дня всем! Есть следующий запрос:
ВЫБРАТЬ
СУММА(ОплатаПоставщику.СуммаДокумента * КурсыВалютСрезПоследних.Курс) КАК СуммаДокумента,
СУММА(ОплатаПоставщику.СуммаЗатрат * КурсыВалютСрезПоследних.Курс) КАК СуммаЗатрат
ИЗ
Документ.ОплатаПоставщику КАК ОплатаПоставщику
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних КАК КурсыВалютСрезПоследних
ПО ОплатаПоставщику.ВалютаДокумента = КурсыВалютСрезПоследних.Валюта
ГДЕ
ОплатаПоставщику.Сделка = &Сделка

Но хотелось бы переводить суммы в рубли не по последнему курсу, а для каждого документа на его дату. Ума не приложу как это сделать и возможно ли? Заранее благодарен за все толковые советы!

да код не причем 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) присоединяем сам курс из рег. сведений (не срез!) на дату «ДатаКурса».
Готово.

Как собирать разные части — твое дело, хочешь — через временные таблицы, хочешь — оборачивай в подзапросы. Не принципиально.

Курсы валют на разные даты в одном запросе. Делаем свой нестандартный срез последних.

Курсы валют на разные даты в одном запросе. Делаем свой нестандартный срез последних.

Часто возникает потребность в этом, например, отложенное формирование проводок (или построение отчета) в валюте регламентировано учета (обычно «руб») для документов (или других данных) введенным в у.е. (например USD или EUR).

Во вложении готовый пример, обработка.

Пример запроса с комментариями:

// Исходные данные передаем в запрос

| &ИсходныеДанные КАК ИсходныеДанные

// Выбираем для каких валют на какие даты надо получить курсы валют

| ИсходныеДанные КАК ИсходныеДанные

// Выбираем ближайшую дату для курса валют

| МАКСИМУМ (КурсыВалют.Период) КАК Период

| ДатаВалюта КАК ДатаВалюта

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют

| ПО ДатаВалюта.Валюта = КурсыВалют.Валюта

| И ДатаВалюта.Дата >= КурсыВалют.Период

// Получаем курсы валют на все даты, которые нужны

| ДатаКурса КАК ДатаКурса

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют

| ПО ДатаКурса.Валюта = КурсыВалют.Валюта

| И ДатаКурса.Период = КурсыВалют.Период

// Объединяем исходные данные с курсами валют

| ИсходныеДанные.Сумма * КурсыВалютСрез.Курс / КурсыВалютСрез.Кратность КАК Итог

| ИсходныеДанные КАК ИсходныеДанные

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ КурсыВалютСрез КАК КурсыВалютСрез

| ПО ИсходныеДанные.Валюта = КурсыВалютСрез.Валюта

| И ИсходныеДанные.Дата = КурсыВалютСрез.Дата»;

Есть вопросы по запросам пишите, постараюсь ответить.

Related Posts

13 Comments

Курсы валют на разные даты в одном запросе. Делаем свой нестандартный срез последних.

Часто возникает потребность в этом, например, отложенное формирование проводок (или построение отчета) в валюте регламентировано учета (обычно «руб») для документов (или других данных) введенным в у.е. (например USD или EUR).

Впечатление дикого дежа-вю. Где я это мог видеть? Впрочем, сейчас набежит местная илита местный бомонд грабить корованы, раскритикует или похвалит.

(1) Поручик, не исключенно, что подобное мог реализовать кто угодно.

Поиск не дал результатов, решил разместить своё.

Примерно так же я решал задачу по РЕПО при сдаче Спеца 1С по Платформе.

(0) То что вы описали — это не есть «Срез последних на каждую дату в запросе»? Если поиском посмотреть — на этом же сайте есть предложенные решения на СКД и в запросе. Вещь полезная.

Оформите публикацию(запрос) нормально

(3) echo77, запрос оформил.

Решение на СКД не нашел, интересно было посмотреть как решили эту проблему там, вдруг что-то интернесное.

(5) echo77, да там аналогичная задача.

Только там, остатки на каждый день * цены номенклатуры на дату остатка.

А у меня документы суммы в УЕ * Курс да дату документа.

Будет новичкам для примера.

Статья оказалась очень полезной, спасибо.

Скажите, для 8,3 есть?

А если курса валюты нет на дату документа? тогда в колонке курс пусто?

Да там получается пусто

(10) Будет курс на какую то ближайшую предыдущую дату до даты документа, на которую есть курс.

Хорошая статья. Достаточно просто и понятно. Конечно можно и самому сделать , но это время. А времени обычно мало, потому что работы много. Использовал идею данной статьи для расчета котировок для оценки стоимости ввода вывода ценных бумаг по документам за период (во завернул фразу!). Там и котировки нужно брать на предыдущий рабочий день нужной биржи, ну и курс валюты сами понимаете… В общем автору спасибо. Сэкономил мне время!

Срез последних на каждую дату

В базе создан документ «РеализацияТоваровУслуг», в шапке которого есть реквизит «Валюта». Запросом требуется для каждого документа получить актуальный курс валюты из шапки на дату документа. Хранение курсов валют осуществляется в периодическом регистре сведений « КурсыВалют «.

Решением «в лоб» этой задачи мог бы быть запрос в цикле: получение всех документов с их датами и валютой и в выборке обращение к виртуальной таблице среза последних регистра «КурсыВалют». Но т.к. запрос в цикле — это «плохо», попробуем реализовать задачу одним запросом .

Решение

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

ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка,
РеализацияТоваровУслуг.Валюта,
МАКСИМУМ(КурсыВалют.Период) КАК Период
ПОМЕСТИТЬ ВТПериодыУстановкиКурсов
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО РеализацияТоваровУслуг.Валюта = КурсыВалют.Валюта
И РеализацияТоваровУслуг.Дата >= КурсыВалют.Период

СГРУППИРОВАТЬ ПО
РеализацияТоваровУслуг.Ссылка,
РеализацияТоваровУслуг.Валюта
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТПериодыУстановкиКурсов.Ссылка,
ВТПериодыУстановкиКурсов.Валюта,
КурсыВалют.Курс
ИЗ
ВТПериодыУстановкиКурсов КАК ВТПериодыУстановкиКурсов
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
ПО ВТПериодыУстановкиКурсов.Период = КурсыВалют.Период
И ВТПериодыУстановкиКурсов.Валюта = КурсыВалют.Валюта

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *