# Единицы измерения и кратность: цены, остатки, упаковки

URL: https://dmeshcheryakov.ru/blog/bitrix-measure-ratio-packs/
Раздел: 1С-Битрикс
Теги: 1С-Битрикс, Каталог, Цены, Интеграции
Опубликовано: 2026-10-26
Обновлено: 2026-10-26
Автор: Дмитрий Мещеряков (https://dmeshcheryakov.ru)

> Почему покупатель кладёт в корзину одну коробку, а платит как за штуку: разбор связки MEASURE, MEASURE_RATIO и коэффициента из 1С.

Товар продаётся коробками по двенадцать штук. В карточке — 120 рублей. Покупатель нажимает «в корзину», получает двенадцать штук и сумму 1440. Менеджер говорит, что коробка стоит 1200, и просит «убрать наценку».

Наценки нет. Есть три числа — цена, единица измерения и кратность, — которые приехали из 1С по разным маршрутам и не сошлись. Разбираться в этой связке приходится редко, зато каждый раз в режиме «клиенты платят не ту сумму».

## Что такое кратность и единица измерения

Кратность — это шаг, которым покупатель меняет количество товара в корзине: при кратности 12
товар добавляется по двенадцать единиц, и кнопки «плюс» и «минус» двигают количество на двенадцать.
Единица измерения — это то, в чём товар считается: штуки, метры, килограммы, литры. В Битриксе она
хранится ссылкой на справочник, где у каждой единицы есть код по классификатору ОКЕИ: 796 — штука,
006 — метр, 166 — килограмм.

Два поля отвечают на два разных вопроса — «какими порциями продаём» и «в чём считаем», — и путаница
между ними даёт большинство ошибок в этой области.

Эти вопросы независимы. Товар может измеряться в штуках и продаваться коробками по двенадцать: единица — штука, кратность — 12.

| Товар | Единица | Кратность | Что видит покупатель |
|---|---|---:|---|
| Смеситель | шт | 1 | Кнопки меняют количество по 1 |
| Плитка | м² | 1,44 | Количество кратно площади одной коробки |
| Саморезы | шт | 100 | Добавляется упаковками по 100 |
| Кабель | м | 1 | Любое число метров |

**Цена всегда хранится за базовую единицу.** Это главное, что нужно запомнить: кратность не меняет цену, она меняет количество. Товар с ценой 120 за штуку и кратностью 12 даёт в корзине 12 штук за 1440 — и это правильное поведение Битрикса, а не ошибка. Если бизнес считает, что коробка стоит 1200, значит, в 1С цена задана за упаковку, и чинить надо выгрузку.

## Как это приезжает из 1С

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

Базовая единица — в товаре, в `import.xml`:

```xml
<Товар>
  <Ид>f4e2c1a9-...</Ид>
  <Наименование>Саморез универсальный 3.5×25</Наименование>
  <БазоваяЕдиница Код="796" НаименованиеПолное="Штука">шт</БазоваяЕдиница>
</Товар>
```

Единица и коэффициент цены — в предложении, в `offers.xml`:

```xml
<Предложение>
  <Ид>f4e2c1a9-...</Ид>
  <Цены>
    <Цена>
      <ИдТипаЦены>b2d4...</ИдТипаЦены>
      <ЦенаЗаЕдиницу>1.20</ЦенаЗаЕдиницу>
      <Валюта>RUB</Валюта>
      <Единица>шт</Единица>
      <Коэффициент>100</Коэффициент>
    </Цена>
  </Цены>
  <Количество>4800</Количество>
</Предложение>
```

Прочитаем эту выгрузку буквально: саморез стоит 1,20 рубля за штуку, продаётся упаковками по 100, на складе 4800 штук. Всё согласовано.

А теперь типичная поломка: в 1С менеджер поставил цену 120 — за упаковку, «так удобнее». Коэффициент остался 100. Битрикс честно посчитает 100 × 120 = 12 000 рублей за упаковку самореза.

**Битрикс не проверяет согласованность цены и коэффициента, и не может её проверить.** Из чисел «цена 120, коэффициент 100» невозможно вывести, что имелось в виду. Обе трактовки арифметически корректны, разница в сто раз, и обнаруживается она только тогда, когда кто-то посмотрит на итог в корзине. Никакой настройки, которая бы это ловила, не существует — контроль возможен только на стороне 1С или отдельной проверкой на сайте.

## Что лежит в базе

Проверка занимает один запрос через [D7-ORM](/blog/bitrix-orm):

```php
<?php
use Bitrix\Catalog\ProductTable;
use Bitrix\Catalog\MeasureTable;
use Bitrix\Main\Loader;

Loader::includeModule('catalog');

// Справочник единиц измерения: что вообще заведено
$measures = MeasureTable::getList([
    'select' => ['ID', 'CODE', 'MEASURE_TITLE', 'SYMBOL_RUS', 'IS_DEFAULT'],
])->fetchAll();

foreach ($measures as $m) {
    printf(
        "%3d  ОКЕИ %-5s %-16s %s\n",
        $m['ID'],
        $m['CODE'],
        $m['MEASURE_TITLE'],
        $m['IS_DEFAULT'] === 'Y' ? '(по умолчанию)' : ''
    );
}
```

```php
<?php
// Товары с подозрительной кратностью — то, что стоит смотреть после каждого обмена
$rows = ProductTable::getList([
    'select' => ['ID', 'QUANTITY', 'MEASURE', 'MEASURE_RATIO'],
    'filter' => [
        'LOGIC' => 'OR',
        ['=MEASURE_RATIO' => 0],
        ['=MEASURE_RATIO' => null],
        ['>MEASURE_RATIO' => 1000],
    ],
    'limit' => 50,
])->fetchAll();

printf("Товаров с некорректной кратностью: %d\n", count($rows));
```

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

## Три сценария, которые ломаются

### Цена за упаковку вместо цены за единицу

Разобран выше. Симптом — сумма в корзине кратно больше ожидаемой, ровно во столько раз, какова кратность.

Проверка на конкретном товаре:

```bash
# Что приехало из 1С
grep -A 15 "f4e2c1a9" /home/site/www/upload/1c_catalog/offers.xml
```

Сверяем `ЦенаЗаЕдиницу` с ценой в базе и `Коэффициент` с `MEASURE_RATIO`. Совпало — вопрос к тому, что имелось в виду в 1С. Не совпало — вопрос к сопоставлению типов цен, разобранному в статье про [цены из 1С](/blog/bitrix-1c-prices-types-currencies).

### Дробная кратность

Плитка продаётся коробками по 1,44 м². Кратность дробная, и на этом ломаются округления: покупатель набирает 10 коробок, получает 14,4 м², а витрина показывает 14 — или 14,40, или 14,4000 в зависимости от настроек вывода.

Дробная кратность работает, но требует внимания к точности во всех трёх местах: в корзине, в заказе и в документах для 1С. Расхождение в сотых долях на большом заказе даёт разницу в деньгах, которую бухгалтерия заметит.

### Кратность ноль

Появляется из выгрузок, где коэффициент не заполнен. Поведение корзины при нулевой кратности непредсказуемо: товар либо не добавляется вовсе, либо добавляется по одной штуке в обход настройки.

Это то, что стоит проверять регулярно — запрос выше находит такие товары за секунду. Заведите его в чек-лист после обмена, потому что появляются они внезапно: один товар в 1С завели без коэффициента, и он один ведёт себя не так, как все.

## Как встроить проверку в обмен

Ручная сверка не масштабируется. Разумнее повесить контроль на завершение импорта — там, где положено делать всё тяжёлое, как разобрано в статье про [производительность импорта](/blog/bitrix-catalog-import-performance):

```php
<?php
use Bitrix\Catalog\ProductTable;
use Bitrix\Main\Loader;

/**
 * Проверка после обмена: ищем товары, у которых кратность выглядит
 * несогласованной с ценой. Пороги подбираются под свой ассортимент —
 * универсальных здесь нет.
 */
function auditMeasureRatio(int $iblockId): array
{
    Loader::includeModule('catalog');

    $suspicious = [];

    $rows = ProductTable::getList([
        'select' => ['ID', 'MEASURE_RATIO'],
        'filter' => [
            'LOGIC' => 'OR',
            ['=MEASURE_RATIO' => 0],
            ['=MEASURE_RATIO' => null],
        ],
    ]);

    while ($row = $rows->fetch()) {
        $suspicious[] = (int)$row['ID'];
    }

    return $suspicious;
}
```

Дальше список уходит письмом или в мессенджер. Смысл не в автоматическом исправлении — исправлять нужно в 1С, — а в том, чтобы узнать о проблеме раньше покупателя.

## Что показывать покупателю

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

Работающий минимум:

- подпись у поля количества: «упаковка 12 шт»;
- цена за единицу и цена за упаковку рядом, а не одна вместо другой;
- в корзине — и количество упаковок, и суммарное количество единиц.

Отсутствие этих подписей даёт стабильный поток обращений «почему я не могу купить одну штуку» и брошенные корзины у тех, кто не стал спрашивать.

## Итоги

**Единица измерения и кратность — разные поля, отвечающие на разные вопросы.** «В чём считаем» и «какими порциями продаём». Их путают чаще всего.

**Цена хранится за базовую единицу, всегда.** Умножение на кратность — правильное поведение. Если бизнес ждёт другого, менять надо выгрузку в 1С.

**Из 1С приезжают два независимых значения,** и Битрикс не может проверить их согласованность: обе трактовки арифметически корректны.

**Нулевая кратность — регулярно появляющийся мусор.** Ищется одним запросом, проверять стоит после каждого обмена.

**Дробная кратность работает, но требует контроля округлений** во всех местах, где число превращается в деньги.

И наблюдение, которое экономит время в разговоре с бизнесом: жалоба «сайт считает неправильно» в этой области почти никогда не про сайт. Сайт считает ровно то, что ему передали. Разговор стоит начинать не с кода, а с вопроса «за что именно поставлена цена в 1С — за штуку или за упаковку», и в половине случаев на этом он и заканчивается.