How to properly write a query to an information register to get prices in 1C:Trade Management 11?
I need to get a price for an item in Trade Management 11. I’m using the following query:
Запрос.Текст = "ВЫБРАТЬ
| ЦеныНоменклатуры.Номенклатура.Ссылка КАК НоменклатураСсылка,
| ЦеныНоменклатуры.ВидЦены.Ссылка КАК ВидЦеныСсылка,
| ЦеныНоменклатуры.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
|ГДЕ
| ЦеныНоменклатуры.ВидЦены.Ссылка = &ВидЦены
| И ЦеныНоменклатуры.Номенклатура.Ссылка = &Номенклатура
| И ЦеныНоменклатуры.Период МЕЖДУ &ДатаНачало И &ДатаКонец";
Запрос.УстановитьПараметр("Номенклатура", НоваяСтрока.Номенклатура.Ссылка);
Запрос.УстановитьПараметр("ВидЦены", НоваяСтрока.ВидЦены.Ссылка);
Запрос.УстановитьПараметр("ДатаНачало", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКонец", КонецДня(ТекущаяДата()));
The problem is that when I add the period condition, the query doesn’t return any data. Without the period condition, I get prices from old dates. I understand that I need to select a price for a specific item that’s valid for the specified period. What am I doing wrong?
Getting Nomenclature Prices in 1C:Trade Management 11
To get the price for nomenclature in 1C:Trade Management 11 from the “ЦеныНоменклатуры” (Nomenclature Prices) information register, you need to use the correct approach for data selection by period. Your problem is that you’re trying to select prices within a date range, but you need a specific price that was valid on the specified date.
Table of Contents
- Main problems in your query
- Structure of the “ЦеныНоменклатуры” register
- Correct query syntax
- Methods for getting a price on a specific date
- Common errors and their solutions
- Advanced scenarios for working with the register
- Conclusions and recommendations
Main problems in your query
Your current query uses the condition BETWEEN &DateStart AND &DateEnd, which leads to selecting all price records within the specified range, rather than getting the specific price that was valid on the desired date.
The problem is that:
- The “ЦеныНоменклатуры” register is periodic, which means each record has a time interval of validity
- When simply filtering by range, you get all prices set during that period
- You need to get the specific price that was valid on a particular date
Structure of the “ЦеныНоменклатуры” register
From research of sources, we can determine that the “ЦеныНоменклатуры” register has the following structure:
Dimensions:
- Nomenclature (reference to the directory)
- PriceType (reference to the directory)
Resources:
- Price (numeric value)
Attributes:
- PriceCurrency (reference to the currency directory)
- Packaging (numeric value)
Periodicity: “Within a second”
Recording mode: “Subordinate to the registrar”
Correct query syntax
To get the price on a specific date, you need to use the following approaches:
Option 1: Using the “SliceLast” virtual table
Query.Text = "SELECT
| NomenclaturePrices.Nomenclature.Ref AS NomenclatureRef,
| NomenclaturePrices.PriceType.Ref AS PriceTypeRef,
| NomenclaturePrices.Price AS Price
|FROM
| InformationRegister.NomenclaturePrices.SliceLast(&SelectionDate,
| Nomenclature = &Nomenclature,
| PriceType = &PriceType) AS NomenclaturePrices";
Query.SetParameter("Nomenclature", NewRow.Nomenclature.Ref);
Query.SetParameter("PriceType", NewRow.PriceType.Ref);
Query.SetParameter("SelectionDate", CurrentDate());
Option 2: Using the standard “Price” function
Query.Text = "SELECT
| NomenclaturePrices.Nomenclature.Ref AS NomenclatureRef,
| NomenclaturePrices.PriceType.Ref AS PriceTypeRef,
| NomenclaturePrices.Price AS Price
|FROM
| InformationRegister.NomenclaturePrices AS NomenclaturePrices
|WHERE
| NomenclaturePrices.Nomenclature.Ref = &Nomenclature
| AND NomenclaturePrices.PriceType.Ref = &PriceType
| AND &SelectionDate BETWEEN NomenclaturePrices.Period.Start
| AND NomenclaturePrices.Period.End";
Query.SetParameter("Nomenclature", NewRow.Nomenclatures.Ref);
Query.SetParameter("PriceType", NewRow.PriceType.Ref);
Query.SetParameter("SelectionDate", CurrentDate());
Methods for getting a price on a specific date
Method 1: “SliceLast” virtual table (recommended)
This method is the most efficient and correct for getting the price on a specific date:
// Getting the price on the specified date
Function GetNomenclaturePrice(Nomenclature, PriceType, SelectionDate) Export
Query = New Query;
Query.Text = "SELECT FIRST 1
| NomenclaturePrices.Price
|FROM
| InformationRegister.NomenclaturePrices AS NomenclaturePrices
|WHERE
| NomenclaturePrices.Nomenclature = &Nomenclature
| AND NomenclaturePrices.PriceType = &PriceType
| AND &SelectionDate BETWEEN NomenclaturePrices.Period.Start
| AND NomenclaturePrices.Period.End";
Query.SetParameter("Nomenclature", Nomenclature);
Query.SetParameter("PriceType", PriceType);
Query.SetParameter("SelectionDate", SelectionDate);
Result = Query.Execute();
Selection = Result.Choose();
If Selection.Next() Then
Return Selection.Price;
EndIf;
Return Undefined;
EndFunction
Method 2: Using built-in 1C functions
// Using the built-in Price function
Price = TradeManagementPricing.Price(Nomenclature, PriceType, SelectionDate);
Common errors and their solutions
Error 1: Incorrect use of period condition
Problem: Your original query used a date range for filtering:
AND NomenclaturePrices.Period BETWEEN &DateStart AND &DateEnd
Solution: You need to check if the desired date falls within the price validity period:
AND &SelectionDate BETWEEN NomenclaturePrices.Period.Start AND NomenclaturePrices.Period.End
Error 2: Missing sorting by date
Problem: If multiple prices can be set on the same day, you need to get the latest one.
Solution: Add sorting by date in descending order:
ORDER BY NomenclaturePrices.Period.End DESC
Error 3: Incorrect handling of empty intervals
Problem: Some prices may have an unlimited validity period.
Solution: Handle cases where EndPeriod = Date(0001, 1, 1):
AND (&SelectionDate >= NomenclaturePrices.Period.Start
AND (NomenclaturePrices.Period.End = DateTime(1, 1, 1)
OR &SelectionDate <= NomenclaturePrices.Period.End))
Advanced scenarios for working with the register
Scenario 1: Getting prices considering nomenclature characteristics
Query.Text = "SELECT
| NomenclaturePrices.Price
|FROM
| InformationRegister.NomenclaturePrices AS NomenclaturePrices
|WHERE
| NomenclaturePrices.Nomenclature = &Nomenclature
| AND NomenclaturePrices.Characteristic = &Characteristic
| AND NomenclaturePrices.PriceType = &PriceType
| AND &SelectionDate BETWEEN NomenclaturePrices.Period.Start
| AND NomenclaturePrices.Period.End
|ORDER BY
| NomenclaturePrices.Period.End DESC";
Scenario 2: Getting price change history
Query.Text = "SELECT
| NomenclaturePrices.Period.Start AS StartDate,
| NomenclaturePrices.Period.End AS EndDate,
| NomenclaturePrices.Price
|FROM
| InformationRegister.NomenclaturePrices AS NomenclaturePrices
|WHERE
| NomenclaturePrices.Nomenclature = &Nomenclature
| AND NomenclaturePrices.PriceType = &PriceType
| AND NomenclaturePrices.Period.Start BETWEEN &DateStart AND &DateEnd
|ORDER BY
| NomenclaturePrices.Period.Start ASC";
Conclusions and recommendations
-
Use the “SliceLast” virtual table to get the price on a specific date - this is the most efficient and correct method.
-
Check the price validity period using the condition
&SelectionDate BETWEEN Period.Start AND Period.End. -
Handle cases with unlimited validity period when Period.End = Date(0001, 1, 1).
-
Always add sorting in descending order by date if multiple prices can be set on the same day.
-
To get price change history use selection by date range with sorting by date in ascending order.
-
For new versions of TM 11 (11.5 and above) use the “NomenclaturePrices25” register, which has extended functionality.
Proper work with the “ЦеныНоменклатуры” register will allow you to get current prices for any date and avoid problems with outdated data.
Sources
- Getting prices on the date of the document in a query
- What’s new in version 11.5.6 :: Information about updates to 1C:Enterprise software products
- Information register NomenclaturePrices25 - how to get prices
- Selection in 1C information register | 1C programmer blog
- Setting prices in Trade Management 11. Arbitrary query to database