NeuroAgent

How to get a price in 1C:UT 11 for a specific date

Correct methods for getting prices from the Nomenclature Prices register in 1C:Trade Management 11. Using SliceLast and proper period handling.

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:

1C
Запрос.Текст = "ВЫБРАТЬ
               |   ЦеныНоменклатуры.Номенклатура.Ссылка КАК НоменклатураСсылка,
               |   ЦеныНоменклатуры.ВидЦены.Ссылка КАК ВидЦеныСсылка,
               |   ЦеныНоменклатуры.Цена КАК Цена
               |ИЗ
               |   РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
               |ГДЕ
               |   ЦеныНоменклатуры.ВидЦены.Ссылка = &ВидЦены
               |   И ЦеныНоменклатуры.Номенклатура.Ссылка = &Номенклатура
               |   И ЦеныНоменклатуры.Период МЕЖДУ &ДатаНачало И &ДатаКонец";

Запрос.УстановитьПараметр("Номенклатура", НоваяСтрока.Номенклатура.Ссылка);
Запрос.УстановитьПараметр("ВидЦены", НоваяСтрока.ВидЦены.Ссылка);
Запрос.УстановитьПараметр("ДатаНачало", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКонец", КонецДня(ТекущаяДата()));

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?

NeuroAgent

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

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

1C
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

1C
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:

1C
// 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

1C
// 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:

1C
AND NomenclaturePrices.Period BETWEEN &DateStart AND &DateEnd

Solution: You need to check if the desired date falls within the price validity period:

1C
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:

1C
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):

1C
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

1C
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

1C
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

  1. Use the “SliceLast” virtual table to get the price on a specific date - this is the most efficient and correct method.

  2. Check the price validity period using the condition &SelectionDate BETWEEN Period.Start AND Period.End.

  3. Handle cases with unlimited validity period when Period.End = Date(0001, 1, 1).

  4. Always add sorting in descending order by date if multiple prices can be set on the same day.

  5. To get price change history use selection by date range with sorting by date in ascending order.

  6. 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

  1. Getting prices on the date of the document in a query
  2. What’s new in version 11.5.6 :: Information about updates to 1C:Enterprise software products
  3. Information register NomenclaturePrices25 - how to get prices
  4. Selection in 1C information register | 1C programmer blog
  5. Setting prices in Trade Management 11. Arbitrary query to database