Ответы в темах
-
АвторЗаписи
-
21 октября 2026 в 12:22 в ответ на: Как напечатать конверты из 1С:Моя Бухгалтерия 8 (РБ) с контрагентами? #38881
В «1С:Моя бухгалтерия 8 для Беларуси» печать конвертов обычно удобнее сделать отдельной внешней обработкой. Обработка должна:
1. Получать выбранных контрагентов.
2. Брать из карточки контрагента наименование и почтовый адрес.
3. Подставлять данные в макет конверта.
4. Формировать табличный документ.
5. Отправлять его на печать.Сначала проверьте, нет ли уже готовой команды:
Справочники → Контрагенты → выделить контрагента → Еще
Ищите команды:
— «Печать конвертов»;
— «Почтовые конверты»;
— «Печать адресов»;
— «Печать».Если такой команды нет, можно сделать внешнюю обработку.
## 1. Создание внешней обработки
В конфигураторе создайте:
Файл → Новый → Внешняя обработка
Например, назовите ее:
1С (Код)1ПечатьКонвертовВ обработке создайте управляемую форму и добавьте реквизиты формы:
| Реквизит | Тип |
|—|—|
| СписокКонтрагентов | ТаблицаЗначений |
| ТабличныйДокумент | ТабличныйДокумент |В таблице
СписокКонтрагентовсоздайте колонки:1С (Код)123456789СсылкаНаименованиеАдресИндексГородУлицаДомКорпусКвартираМинимально достаточно колонок:
1С (Код)123СсылкаНаименованиеАдресЕсли обработка будет использоваться только для выбранных контрагентов, в таблицу можно передавать ссылки на них из списка справочника.
## 2. Создание макета конверта
В обработке создайте макет типа Табличный документ с именем:
1С (Код)1КонвертВ макете создайте область с именем:
1С (Код)1КонвертРазместите в области параметры:
1С (Код)1234ПолучательАдресИндексГородНапример, макет можно оформить так:
1С (Код)123456ИндексПолучательАдресГородДля стандартного конверта обычно используется область примерно размером 220 × 110 мм. Точные размеры зависят от типа конверта и принтера.
В параметрах табличного документа можно установить:
— ориентацию страницы;
— размер бумаги;
— поля;
— масштаб;
— отсутствие колонтитулов;
— разрыв страницы после каждого конверта.Для печати одного конверта на одной странице следует использовать отдельную область макета для каждого получателя.
## 3. Процедура формирования печатного документа
В модуль формы обработки можно добавить процедуру:
1С (Код)1234567891011121314151617&НаКлиентеПроцедура ПечатьКонвертов(Команда)Если СписокКонтрагентов.Количество() = 0 ТогдаСообщить("Не выбраны контрагенты для печати.");Возврат;КонецЕсли;ТабДок = СформироватьКонвертыНаСервере(СписокКонтрагентов);Если ТабДок = Неопределено ТогдаВозврат;КонецЕсли;ТабДок.Показать("Печать конвертов");КонецПроцедурыСерверная функция:
1С (Код)1234567891011121314151617181920212223242526272829&НаСервереФункция СформироватьКонвертыНаСервере(СписокКонтрагентов) ЭкспортТабДок = Новый ТабличныйДокумент;Макет = ПолучитьМакет("Конверт");Для каждого СтрокаКонтрагент Из СписокКонтрагентов ЦиклЕсли Не ЗначениеЗаполнено(СтрокаКонтрагент.Ссылка) ТогдаПродолжить;КонецЕсли;Область = Макет.ПолучитьОбласть("Конверт");Область.Параметры.Получатель = СтрокаКонтрагент.Наименование;Область.Параметры.Адрес = СтрокаКонтрагент.Адрес;Область.Параметры.Индекс = СтрокаКонтрагент.Индекс;Область.Параметры.Город = СтрокаКонтрагент.Город;ТабДок.Вывести(Область);КонецЦикла;ТабДок.АвтоМасштаб = Истина;ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;Возврат ТабДок;КонецФункцииЕсли в макете используется только один параметр адреса, можно упростить:
1С (Код)12Область.Параметры.Получатель = СтрокаКонтрагент.Наименование;Область.Параметры.Адрес = СтрокаКонтрагент.Адрес;## 4. Заполнение списка контрагентов
Самый простой вариант, подходящий для первой версии обработки, это добавить в форму обработки таблицу
СписокКонтрагентови кнопку Добавить контрагента.Процедура кнопки:
1С (Код)1234567891011&НаКлиентеПроцедура ДобавитьКонтрагента(Команда)НоваяСтрока = СписокКонтрагентов.Добавить();НоваяСтрока.Ссылка = Неопределено;НоваяСтрока.Наименование = "";НоваяСтрока.Адрес = "";НоваяСтрока.Индекс = "";НоваяСтрока.Город = "";КонецПроцедурыЛучше, чтобы колонка
Ссылкаимела тип:1С (Код)1СправочникСсылка.КонтрагентыПри выборе контрагента можно автоматически заполнять его наименование и адрес.
Например:
1С (Код)12345678910111213141516&НаКлиентеПроцедура СписокКонтрагентовСсылкаПриИзменении(Элемент)ТекущаяСтрока = Элементы.СписокКонтрагентов.ТекущиеДанные;Если ТекущаяСтрока = Неопределено ТогдаВозврат;КонецЕсли;Если Не ЗначениеЗаполнено(ТекущаяСтрока.Ссылка) ТогдаВозврат;КонецЕсли;ЗаполнитьДанныеКонтрагентаНаСервере(ТекущаяСтрока.Ссылка);КонецПроцедурыНо для разных конфигураций реквизиты адреса могут называться по-разному, поэтому процедуру заполнения нужно адаптировать под конкретную базу.
## 5. Получение адреса из карточки контрагента
Это самый важный момент. В разных версиях «Моя бухгалтерия 8 для Беларуси» адрес может храниться:
— в реквизите
Адрес;
— в реквизитеЮридическийАдрес;
— в реквизитеПочтовыйАдрес;
— на вкладке «Адреса и телефоны»;
— в контактной информации;
— в регистре сведений контактной информации.Нельзя заранее гарантировать, что в конфигурации есть реквизит с именем
Адрес.Если адрес хранится непосредственно в реквизите справочника, код будет примерно таким:
1С (Код)123456789101112131415&НаСервереПроцедура ЗаполнитьДанныеКонтрагентаНаСервере(СсылкаКонтрагента) ЭкспортТекущаяСтрока = Элементы.СписокКонтрагентов.ТекущиеДанные;Контрагент = СсылкаКонтрагента.ПолучитьОбъект();ТекущаяСтрока.Наименование = Контрагент.Наименование;// Названия реквизитов необходимо проверить в вашей конфигурацииТекущаяСтрока.Адрес = Контрагент.ПочтовыйАдрес;ТекущаяСтрока.Индекс = Контрагент.ПочтовыйИндекс;ТекущаяСтрока.Город = Контрагент.Город;КонецПроцедурыЕсли у вас адрес хранится одной строкой, достаточно:
1С (Код)1ТекущаяСтрока.Адрес = Контрагент.Адрес;Если адрес хранится в контактной информации, нужно получать его через стандартные механизмы конфигурации. Название общего модуля и процедуры в белорусской конфигурации может отличаться от типовой российской «Бухгалтерии предприятия».
Практически определить правильные реквизиты можно так:
1. Открыть карточку контрагента.
2. В конфигураторе открыть объект Справочник → Контрагенты.
3. Проверить реквизиты объекта.
4. Посмотреть табличные части и контактную информацию.
5. Если в самом справочнике адреса нет, проверить регистр сведений, связанный с контактной информацией.## 6. Более удобный вариант, выбор из списка контрагентов
Если необходимо запускать обработку прямо из списка контрагентов, лучше сделать не обычную внешнюю обработку, а расширение конфигурации.
В расширении:
1. Добавляется команда в форму списка справочника
Контрагенты.
2. Команда появляется в меню Еще.
3. Из списка передаются выбранные ссылки.
4. Открывается форма обработки.
5. Обработка формирует печатный документ.Логика команды будет такой:
1С (Код)123456789101112131415161718192021222324&НаКлиентеПроцедура ПечатьКонвертов(Команда)МассивСсылок = Новый Массив;Для каждого Строка Из Элементы.Список.ВыделенныеСтроки ЦиклМассивСсылок.Добавить(Строка.Ссылка);КонецЦикла;Если МассивСсылок.Количество() = 0 ТогдаСообщить("Выберите хотя бы одного контрагента.");Возврат;КонецЕсли;ПараметрыФормы = Новый Структура;ПараметрыФормы.Вставить("СписокСсылок", МассивСсылок);ОткрытьФорму("ВнешняяОбработка.ПечатьКонвертов.Форма.Форма",ПараметрыФормы,ЭтаФорма);КонецПроцедурыОднако имя элемента списка и способ получения выделенных строк зависят от версии платформы и формы списка. В некоторых конфигурациях выбранные строки передаются в обработчик команды через стандартный параметр
ПараметрКоманды.## 7. Формирование списка из переданных ссылок
В форме обработки можно обработать ссылки при открытии:
1С (Код)1234567891011121314151617181920212223&НаСервереПроцедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)Если Параметры.Свойство("СписокСсылок") ТогдаДля каждого СсылкаКонтрагента Из Параметры.СписокСсылок ЦиклКонтрагент = СсылкаКонтрагента.ПолучитьОбъект();НоваяСтрока = СписокКонтрагентов.Добавить();НоваяСтрока.Ссылка = СсылкаКонтрагента;НоваяСтрока.Наименование = Контрагент.Наименование;// Ниже указать фактические реквизиты вашей базыНоваяСтрока.Адрес = Контрагент.ПочтовыйАдрес;НоваяСтрока.Индекс = Контрагент.ПочтовыйИндекс;НоваяСтрока.Город = Контрагент.Город;КонецЦикла;КонецЕсли;КонецПроцедуры## 8. Если нужно печатать адрес организации
Для организаций обычно требуется печатать не только название, но и почтовый адрес:
1С (Код)123ООО «Ромашка»220030, Республика Беларусь,г. Минск, ул. Советская, д. 10, оф. 25Для физического лица:
1С (Код)123Иванов Иван Иванович220100, г. Минск,ул. Лесная, д. 15, кв. 20Лучше формировать отдельную строку адреса:
1С (Код)123456789101112131415161718192021222324252627282930313233343536373839Функция СформироватьАдрес(Индекс, Город, Улица, Дом, Корпус, Квартира) ЭкспортАдрес = "";Если ЗначениеЗаполнено(Индекс) ТогдаАдрес = Адрес + Индекс;КонецЕсли;Если ЗначениеЗаполнено(Город) ТогдаЕсли ЗначениеЗаполнено(Адрес) ТогдаАдрес = Адрес + ", ";КонецЕсли;Адрес = Адрес + Город;КонецЕсли;Если ЗначениеЗаполнено(Улица) ТогдаЕсли ЗначениеЗаполнено(Адрес) ТогдаАдрес = Адрес + ", ";КонецЕсли;Адрес = Адрес + Улица;КонецЕсли;Если ЗначениеЗаполнено(Дом) ТогдаАдрес = Адрес + ", д. " + Дом;КонецЕсли;Если ЗначениеЗаполнено(Корпус) ТогдаАдрес = Адрес + ", корп. " + Корпус;КонецЕсли;Если ЗначениеЗаполнено(Квартира) ТогдаАдрес = Адрес + ", кв. " + Квартира;КонецЕсли;Возврат Адрес;КонецФункции## 9. Настройка печати
После формирования табличного документа:
1. Нажмите Печать.
2. В настройках принтера выберите фактический формат конверта.
3. Укажите ориентацию.
4. Отключите масштабирование «по размеру страницы».
5. Установите масштаб 100%.
6. Сначала напечатайте на обычном листе.
7. Наложите лист на конверт и проверьте расположение текста.
8. После проверки печатайте на конвертах.Частая ошибка заключается в том, что 1С формирует правильный макет, но драйвер принтера автоматически масштабирует его под формат А4. Поэтому в настройках печати нужно отключить автоматическое масштабирование.
Для вашей конфигурации наиболее надежный вариант такой:
— добавить команду «Печать конвертов» в список контрагентов через расширение;
— передавать в обработку выбранные ссылки;
— в обработке получать почтовый адрес;
— выводить адрес в макет табличного документа;
— печатать по одному конверту на страницу.Названия реквизитов адреса в «Моя бухгалтерия 8 для Беларуси» зависят от релиза и доработок. Поэтому участок с
Контрагент.ПочтовыйАдрес,Контрагент.ПочтовыйИндексиКонтрагент.Городнужно заменить на реальные реквизиты вашей базы.21 октября 2026 в 11:34 в ответ на: Как обновить код 1С для перехода с /v3/posting/fbs на /v4/ в API Ozon? #38879В приведенной процедуре нет ни старого метода:
1С (Код)1/v3/posting/fbs/unfulfilled/listни нового:
1С (Код)1/v4/posting/fbs/unfulfilled/listЭта процедура вообще выполняет другой обмен:
1С (Код)1/v1/product/import/pricesОна:
1. Получает цены из регистра
ЦеныНоменклатуры.
2. Формирует JSON с ключомprices.
3. Отправляет цены на Ozon.
4. Разбирает ответ поСтруктураОтвета.result.
5. Записывает результат в регистрсм_РезультатОбновленияОстатков.Поэтому заменить только URL в этой процедуре нельзя. Метод
/v4/posting/fbs/unfulfilled/listпредназначен для получения неотгруженных отправлений FBS, а не для загрузки цен. У него другой формат запроса и другой формат ответа.## Что именно должно быть изменено для метода
/v4/posting/fbs/unfulfilled/listДля нового метода меняется только блок получения данных:
1С (Код)12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152ССЛ = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows(),Новый СертификатыУдостоверяющихЦентровWindows());Соединение = Новый HTTPСоединение("api-seller.ozon.ru",,,,,,,ССЛ,);ЗаголовкиЗапроса = Новый Соответствие;ЗаголовкиЗапроса.Вставить("Client-Id", ВыборкаКабинетов.КлиентИД);ЗаголовкиЗапроса.Вставить("Api-Key", ВыборкаКабинетов.АпиКей);ЗаголовкиЗапроса.Вставить("Content-Type", "application/json");ДанныеЗапроса = Новый Структура;ДанныеЗапроса.Вставить("dir", "ASC");ДанныеЗапроса.Вставить("filter", Новый Структура);ДанныеЗапроса.Вставить("limit", 100);ДанныеЗапроса.Вставить("offset", 0);Запись = Новый ЗаписьJSON;Запись.УстановитьСтроку();ЗаписатьJSON(Запись, ДанныеЗапроса, Новый НастройкиСериализацииJSON);ТелоЗапроса = Запись.Закрыть();ЗапросHTTP = Новый HTTPЗапрос("/v4/posting/fbs/unfulfilled/list",ЗаголовкиЗапроса);ЗапросHTTP.УстановитьТелоИзСтроки(ТелоЗапроса);Ответ = Соединение.ОтправитьДляОбработки(ЗапросHTTP);Если Ответ.КодСостояния <> 200 ТогдаЗаписьЖурналаРегистрации("Получение неотгруженных отправлений Ozon",УровеньЖурналаРегистрации.Ошибка,,,Ответ.КодСостояния);см_ОбщийМодуль.Пауза(2);Продолжить;КонецЕсли;ЧтениеJSON = Новый ЧтениеJSON;ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());СтруктураОтвета = ПрочитатьJSON(ЧтениеJSON);Однако это уже не является заменой окружения в процедуре
ОбновитьЦены, потому что после получения ответа нужно разбирать отправления, а не элементы с полями:1С (Код)123ТекЭлемент.offer_idТекЭлемент.updatedТекЭлемент.errorsУ метода
/v4/posting/fbs/unfulfilled/listрезультат содержит список отправлений, поэтому логика разбора должна обращаться к массиву отправлений, например:1С (Код)12345Для Каждого Отправление Из СтруктураОтвета.result.postings Цикл// Обработка отправления FBSКонецЦикла;Фактическая структура
resultзависит от версии API и настроек запроса, поэтому перед обращением к полям нужно ориентироваться на полученный JSON.## Минимальное тело запроса
Если нужны все неотгруженные отправления без дополнительных фильтров, тело запроса должно иметь вид:
JavaScript123456{"dir": "ASC","filter": {},"limit": 100,"offset": 0}В 1С это формируется так:
1С (Код)12345ДанныеЗапроса = Новый Структура;ДанныеЗапроса.Вставить("dir", "ASC");ДанныеЗапроса.Вставить("filter", Новый Структура);ДанныеЗапроса.Вставить("limit", 100);ДанныеЗапроса.Вставить("offset", 0);Если требуется отбор по датам или статусу, параметры добавляются внутрь
filter:1С (Код)123456789Фильтр = Новый Структура;Фильтр.Вставить("cutoff_from", "2026-10-20T00:00:00Z");Фильтр.Вставить("cutoff_to", "2026-10-21T23:59:59Z");ДанныеЗапроса = Новый Структура;ДанныеЗапроса.Вставить("dir", "ASC");ДанныеЗапроса.Вставить("filter", Фильтр);ДанныеЗапроса.Вставить("limit", 100);ДанныеЗапроса.Вставить("offset", 0);## Важное ограничение по предоставленному коду
В приведенной процедуре нельзя сохранить одновременно:
— текущую логику обновления цен;
— текущую структуру обработки ответа;
— переход на/v4/posting/fbs/unfulfilled/list.Причина в том, что это разные операции Ozon:
| Текущий код | Новый метод |
|—|—|
| Обновление цен | Получение отправлений FBS |
|POST /v1/product/import/prices|POST /v4/posting/fbs/unfulfilled/list|
| Тело с ключомprices| Тело сdir,filter,limit,offset|
| Ответ с результатами обновления цен | Ответ со списком отправлений |
| Поляoffer_id,updated,errors| Данные отправления, статус, номер отправления, товары и прочее |То есть в предоставленном фрагменте отсутствует участок кода, который нужно переделать. Менять строку:
1С (Код)1Запрос = Новый HTTPЗапрос("/v1/product/import/prices",ЗаголовкиЗапроса);на:
1С (Код)1Запрос = Новый HTTPЗапрос("/v4/posting/fbs/unfulfilled/list",ЗаголовкиЗапроса);нельзя, поскольку вместе с этим придется менять формирование
ТелоЗапросаи разборСтруктураОтвета. Это уже будет изменение логики процедуры, а не только окружения передачи данных.20 октября 2026 в 18:35 в ответ на: Как правильно настроить и переносить лицензии 1С на ВМ Hyper-V? #38877Для клиент-серверных лицензий 1С на ВМ Hyper-V важно разделять:
— серверную лицензию 1С;
— клиентские лицензии 1С;
— способ защиты: программные лицензии или аппаратные ключи HASP;
— технический перенос ВМ;
— лицензионное право запускать Windows Server на другом физическом хосте.## Как работает клиент-серверная лицензия 1С
В типовой схеме:
1С (Код)12345678Клиенты 1С|vСервер 1С:Предприятия|+-- серверная лицензия 1С|+-- клиентские лицензии 1ССерверная лицензия обычно устанавливается на сервере 1С. Клиентские лицензии могут выдаваться:
— сервером 1С;
— отдельным сервером лицензирования;
— аппаратным ключом HASP;
— программным лицензирующим сервером 1С.При переносе ВМ Hyper-V между физическими хостами сама лицензия 1С не «переезжает» отдельно. Перемещается ВМ вместе с установленным программным лицензированием или настройками доступа к ключу.
—
# Наиболее надежная схема для Hyper-V
Для рабочей базы я бы рекомендовал один из двух вариантов.
## Вариант 1. Аппаратный сетевой ключ 1С
Аппаратный ключ HASP устанавливается на отдельный сервер лицензирования, доступный с ВМ 1С по сети.
1С (Код)12345678910111213141516+----------------------+| Сервер лицензирования|| HASP Net |+----------+-----------+|| сеть|+-------------+ +------+------+| Хост Hyper-V| | ВМ с сервером|| № 1 +------------>| 1С |+-------------+ +------+------+или ^+-------------+ || Хост Hyper-V|---------------------+| № 2 |+-------------+ВМ с сервером 1С можно переносить между хостами, потому что лицензия находится не внутри ВМ, а на отдельном сервере или аппаратном ключе.
### Что нужно обеспечить
— сервер лицензирования постоянно доступен по сети;
— сетевой ключ виден с обоих хостов;
— не меняется адрес и имя сервера лицензирования;
— на серверах разрешен необходимый сетевой трафик;
— при аварии одного Hyper-V-хоста ВМ запускается на другом хосте;
— ключ не подключен только к недоступному физическому серверу.Если ключ физически установлен в USB-порт хоста Hyper-V, это менее удобно:
— после падения хоста ключ останется на недоступном сервере;
— потребуется USB-проброс или USB-over-IP;
— автоматическое переподключение может работать нестабильно;
— при миграции ВМ ключ сам по себе не переносится.Для отказоустойчивости лучше размещать ключ на отдельном постоянно доступном сервере лицензирования или использовать поддерживаемую схему USB-over-IP.
—
## Вариант 2. Программные лицензии 1С
Программная клиент-серверная лицензия привязывается к параметрам компьютера, на котором она была получена. В виртуальной среде к этим параметрам относятся, в частности:
— идентификаторы ВМ;
— MAC-адрес сетевой карты;
— параметры виртуального процессора;
— сведения о BIOS и материнской плате;
— виртуальные диски;
— конфигурация виртуального оборудования;
— параметры операционной системы.При корректной миграции Hyper-V большинство параметров сохраняется. Но если при переносе изменится состав виртуального оборудования, лицензия может перестать определяться.
## Что настроить в Hyper-V
### 1. Зафиксировать MAC-адрес
В настройках ВМ откройте:
1С (Код)12345Параметры виртуальной машины→ Сетевой адаптер→ Дополнительные возможности→ MAC-адрес→ СтатическийНе оставляйте MAC-адрес динамическим. При переносе, восстановлении или импорте ВМ Hyper-V может назначить новый адрес.
Проверка через PowerShell:
PowerShell12Get-VMNetworkAdapter -VMName "VM-1C" |Select-Object VMName, MacAddress, DynamicMacAddressEnabledЕсли MAC должен быть задан вручную:
PowerShell123Set-VMNetworkAdapter `-VMName "VM-1C" `-StaticMacAddress "00155D123456"MAC-адрес должен быть уникальным в сети.
### 2. Включить совместимость процессоров
Если хосты имеют разные процессоры, например Intel разных поколений, включите совместимость CPU:
PowerShell123Set-VMProcessor `-VMName "VM-1C" `-CompatibilityForMigrationEnabled $trueПроверить настройку:
PowerShell123Get-VMProcessor `-VMName "VM-1C" |Select-Object VMName, CompatibilityForMigrationEnabledЭто необходимо в первую очередь для самой миграции, но также снижает вероятность изменения набора доступных процессорных инструкций для гостевой ОС и программ лицензирования.
### 3. Сохранить поколение ВМ
Не меняйте:
— Generation 1 на Generation 2;
— Generation 2 на Generation 1;
— BIOS на UEFI;
— контроллеры дисков;
— тип виртуального сетевого адаптера;
— виртуальный TPM;
— настройки Secure Boot.Если ВМ создана как Generation 1, после переноса она должна оставаться Generation 1. Переход на другое поколение выполняется созданием новой ВМ и миграцией данных, а это уже новая виртуальная машина с точки зрения лицензирования.
### 4. Переносить исходную ВМ, а не клон
Для обычного переноса используйте:
— Live Migration;
— экспорт и импорт исходной ВМ;
— перенос дисков и конфигурации с сохранением параметров;
— кластер Hyper-V или Storage Migration.Не используйте для рабочей лицензированной ВМ обычное клонирование. Клон может получить:
— новый MAC-адрес;
— новый идентификатор;
— конфликт имени компьютера;
— конфликт в домене;
— дублирование лицензии;
— одинаковые параметры двух одновременно работающих серверов.—
# Рекомендуемый порядок переноса ВМ с программной лицензией 1С
## До переноса
1. Завершить сеансы пользователей 1С.
2. Остановить службы сервера 1С или корректно завершить работу кластера.
3. Сделать резервную копию информационной базы.
4. Сохранить файл программной лицензии.
5. Зафиксировать:
— MAC-адрес;
— имя ВМ;
— VM ID;
— поколение ВМ;
— количество виртуальных процессоров;
— объем оперативной памяти;
— состав виртуальных дисков;
— имя компьютера;
— IP-адрес.
6. Проверить, что на целевом хосте нет другой копии этой ВМ.
7. Убедиться, что целевой хост имеет право запускать нужное количество Windows Server ВМ.VM ID можно посмотреть так:
PowerShell12Get-VM -Name "VM-1C" |Select-Object Name, VMId, Version## Во время переноса
1. Не изменять конфигурацию виртуального оборудования.
2. Не удалять сетевой адаптер.
3. Не включать автоматическую генерацию нового MAC.
4. Не запускать исходную и перенесенную ВМ одновременно в одной сети.
5. Если используется экспорт/импорт, проверить параметры ВМ после импорта до ее запуска.## После переноса
1. Проверить MAC-адрес.
2. Проверить имя компьютера и IP-адрес.
3. Проверить наличие программной лицензии.
4. Запустить службу сервера 1С.
5. Подключиться тестовым клиентом.
6. Проверить запуск нескольких сеансов.
7. Проверить выдачу клиентских лицензий.
8. После этого разрешить работу пользователей.Проверять состояние лицензирования лучше не только запуском Конфигуратора, но и через журнал регистрации 1С и консоль администрирования кластера.
—
# Что произойдет при изменении аппаратных параметров
Если после переноса сервер 1С запускается, но лицензия не определяется, возможны сообщения вида:
— лицензия не обнаружена;
— не найден ключ защиты;
— превышено количество лицензий;
— программная лицензия не соответствует параметрам компьютера;
— невозможно получить лицензию;
— не найден сервер лицензирования.В этом случае сначала не нужно сразу перевыпускать лицензию. Сначала восстановите прежние параметры ВМ:
1. Верните старый MAC-адрес.
2. Проверьте поколение ВМ.
3. Верните прежнюю модель CPU.
4. Проверьте виртуальные диски.
5. Убедитесь, что не был удален или создан заново сетевой адаптер.
6. Проверьте дату и состояние операционной системы.
7. Перезапустите службы 1С.Если лицензия по-прежнему не определяется, тогда можно выполнять повторное получение программной лицензии с использованием резервного PIN-кода.
Не следует без необходимости удалять старый файл лицензии. Повторная активация может израсходовать один из доступных PIN-кодов.
—
# Можно ли использовать программную серверную лицензию на двух хостах
Технически одна ВМ может переноситься между хостами. В этом случае программная лицензия находится внутри этой ВМ и используется при работе только одной активной копии ВМ.
Нельзя одновременно запускать:
1С (Код)12ВМ 1С на Хосте 1ВМ-клон 1С на Хосте 2если это одна и та же лицензированная система и не выполнены отдельные лицензионные условия. Это приводит не только к конфликту IP и имени компьютера, но и к проблемам с выдачей лицензий.
Если нужна схема с двумя одновременно работающими серверами 1С, для них обычно требуются отдельные серверные лицензии и соответствующая конфигурация клиентских лицензий.
—
# Как организовать кластер Hyper-V
Для двух хостов можно использовать такую схему:
1С (Код)1234567Хост Hyper-V 1 Хост Hyper-V 2//Кластер Hyper-V|vВМ сервера 1СДля программной лицензии желательно:
— одинаковое поколение ВМ;
— одинаковые виртуальные CPU;
— совместимые физические процессоры;
— статический MAC;
— единый кластер Hyper-V;
— перенос именно одной ВМ;
— отсутствие одновременного запуска копий;
— отдельное резервное копирование базы.Если аппаратные процессоры существенно отличаются, например Intel и AMD, перенос может быть технически и лицензионно проблемным. Для критичной системы лучше использовать хосты с совместимыми процессорами одного производителя и близкого поколения.
—
# Что лучше выбрать
## Для одной ВМ без автоматической миграции
Подойдет программная серверная лицензия, если:
— ВМ переносится редко;
— сохраняется MAC-адрес;
— не меняется виртуальное оборудование;
— есть резервные PIN-коды;
— имеется резервная копия базы.## Для регулярной миграции между хостами
Лучше использовать:
— аппаратный сетевой ключ HASP;
— отдельный сервер лицензирования;
— стабильную сетевую схему;
— кластер Hyper-V;
— фиксированный MAC-адрес ВМ;
— совместимые CPU хостов.## Для автоматического переключения при аварии
Наиболее практично:
1С (Код)1234567ВМ 1С|+-- доступ к сетевому HASP или отдельному серверу лицензирования|+-- Hyper-V Failover Cluster|+-- два совместимых физических хостаПри этом аппаратная лицензия остается доступной независимо от того, на каком хосте сейчас запущена ВМ 1С.
—
# Важное отличие от лицензии Windows Server
Перенос ВМ 1С между хостами не означает автоматически, что лицензирование Windows Server на целевом хосте выполнено.
На каждом физическом хосте должны быть соблюдены права на запуск соответствующих Windows Server ВМ. Для редакции Windows Server Standard количество разрешенных виртуальных экземпляров зависит от того, сколько физических ядер хоста лицензировано и сколько лицензий назначено хосту. Для большого количества ВМ обычно рассматривают Datacenter.
То есть нужно отдельно проверить:
1. лицензию 1С;
2. Windows Server;
3. SQL Server, если он используется;
4. лицензии терминального доступа, если пользователи работают через RDP;
5. лицензии сторонних программ внутри ВМ.20 октября 2026 в 18:28 в ответ на: Как перенести лицензию 1С на ВМ между разными аппаратными хостами? #38875При переносе виртуальной машины между аппаратно разными хостами нужно разделять две разные проблемы:
1. Лицензия 1С, установленная программным способом.
2. Лицензия Windows Server, если сама виртуальная машина работает под Windows Server.## 1. Если речь о лицензии 1С
Программная лицензия 1С может быть привязана к параметрам компьютера. В виртуальной машине в качестве таких параметров используются не только данные самой ВМ, но и виртуальные аппаратные идентификаторы:
— MAC-адрес сетевой карты;
— UUID виртуальной машины;
— идентификатор BIOS;
— параметры виртуального процессора;
— серийные номера виртуальных дисков;
— идентификаторы материнской платы и системного оборудования;
— иногда параметры гипервизора.При переносе ВМ на другой физический сервер часть этих данных может измениться. В результате 1С начинает считать, что программа запущена на другом компьютере, и лицензия перестает определяться.
### Что желательно сделать заранее
Перед переносом виртуальной машины:
1. Сделать резервную копию информационной базы.
2. Зафиксировать текущий MAC-адрес виртуальной сетевой карты.
3. Зафиксировать UUID и настройки виртуальной машины.
4. Отключить автоматическую генерацию нового MAC-адреса.
5. Включить режим совместимости процессоров.
6. Не менять тип контроллера диска, тип BIOS и модель виртуального оборудования.
7. Не удалять и не создавать заново сетевой адаптер.
8. Не запускать одновременно старую и новую копию ВМ в одной сети.Самая частая ошибка при восстановлении или клонировании ВМ заключается в том, что гипервизор назначает ей новый MAC-адрес. Это может повлиять не только на 1С, но и на лицензирование Windows, активацию программ, настройки сетевых служб и регистрацию сервера в домене.
—
## 2. Если используется Hyper-V
Для ВМ Hyper-V желательно сохранить следующие параметры:
PowerShell12Get-VM -Name "ИмяВМ" | Select-Object Name, VMId, VersionGet-VMNetworkAdapter -VMName "ИмяВМ" | Select-Object VMName, MacAddress, DynamicMacAddressEnabledПеред переносом можно задать статический MAC-адрес:
PowerShell123Set-VMNetworkAdapter `-VMName "ИмяВМ" `-StaticMacAddress "00155D123456"Проверьте, что MAC-адрес не используется другой виртуальной машиной.
Для совместимости процессоров:
PowerShell123Set-VMProcessor `-VMName "ИмяВМ" `-CompatibilityForMigrationEnabled $trueДля переноса работающей ВМ между разными процессорами это особенно важно. Без режима совместимости миграция может завершиться ошибкой из-за различий в наборах инструкций CPU.
При переносе не следует менять:
— поколение виртуальной машины;
— тип виртуального BIOS или UEFI;
— контроллеры дисков;
— порядок загрузки;
— сетевой адаптер;
— MAC-адрес;
— виртуальный TPM, если он используется;
— настройки Secure Boot.При этом даже сохранение MAC-адреса не гарантирует сохранение лицензии 1С, если сама лицензия была привязана к другим параметрам виртуального оборудования.
—
## 3. Если используется Proxmox
При переносе через резервную копию проверьте MAC-адрес:
Shell1qm config 100В конфигурации должна быть строка примерно такого вида:
1С (Код)1net0: virtio=AA:BB:CC:11:22:33,bridge=vmbr0После восстановления на новом сервере MAC-адрес необходимо оставить прежним. Если он изменился, задайте его вручную:
Shell1qm set 100 --net0 virtio=AA:BB:CC:11:22:33,bridge=vmbr0Также желательно сохранить:
— тип BIOS:
seabiosилиovmf;
— тип машины;
— модель сетевого адаптера;
— тип дискового контроллера;
— UUID ВМ;
— параметры CPU;
— наличие или отсутствие TPM;
— порядок подключения дисков.Если перенос выполняется через
vzdumpиqmrestore, после восстановления не запускайте обе копии одновременно. Сначала отключите исходную ВМ от сети или полностью остановите ее.—
## 4. Наиболее надежный вариант для 1С
Если 1С используется на постоянной основе, программную лицензию лучше не привязывать к каждой мигрирующей ВМ.
Практически применяются следующие варианты.
### Вариант 1. Аппаратный ключ 1С
Аппаратный USB-ключ HASP размещается:
— на физическом сервере;
— на отдельной стабильной виртуальной машине через USB-проброс;
— на USB-over-IP сервере;
— на сервере лицензирования, доступном по сети.Плюс такого варианта в том, что перенос самой ВМ не меняет аппаратный ключ. ВМ переезжает между хостами, а ключ остается доступным по сети.
Нужно учитывать:
— USB-ключ не должен одновременно использоваться несколькими серверами без соответствующей схемы лицензирования;
— при размещении ключа на физическом хосте нужно обеспечить его доступность после отказа хоста;
— USB-over-IP должен поддерживать стабильное подключение и автоматическое переподключение;
— сетевой доступ к серверу лицензирования не должен блокироваться межсетевым экраном.### Вариант 2. Отдельный сервер лицензирования
Можно вынести лицензирование 1С на отдельную ВМ или физический сервер, который не участвует в частых миграциях.
Рабочая схема:
1С (Код)1234567Пользователи 1С|vСервер 1С|vОтдельный сервер лицензирования 1СВ этом случае сервер 1С можно переносить между хостами, а лицензирующая ВМ остается на заранее подготовленном узле.
Однако сам сервер лицензирования тоже не следует часто клонировать и переносить без сохранения его виртуальных идентификаторов.
### Вариант 3. Перевыпуск программной лицензии
Если лицензия уже перестала определяться после переноса, обычно выполняют повторное получение программной лицензии через помощник лицензирования 1С.
Общий порядок:
1. Запустить базу 1С в режиме «Конфигуратор» или через соответствующий помощник лицензирования.
2. Открыть раздел получения программной лицензии.
3. Выбрать восстановление или повторное получение лицензии.
4. Указать регистрационный номер и PIN-код.
5. Использовать резервный PIN-код, если основной уже был активирован.
6. Получить новую лицензию для текущей конфигурации виртуального оборудования.Важно: повторная активация может потребовать свободного PIN-кода из комплекта лицензии. Количество повторных получений и возможность восстановления зависят от типа поставки и использованного комплекта PIN-кодов.
Перед такими действиями нужно сохранить:
— регистрационный номер;
— комплект PIN-кодов;
— данные владельца лицензии;
— предыдущую лицензию;
— сведения о текущей конфигурации ВМ.Не стоит без необходимости удалять файл лицензии и многократно запускать процедуру получения новой лицензии. Можно израсходовать доступные резервные активации.
—
## 5. Live Migration и перенос с остановкой
Для лицензии 1С предпочтительнее следующая последовательность:
1. Остановить службы 1С:Предприятия.
2. Завершить сеансы пользователей.
3. Проверить резервную копию информационной базы.
4. Остановить ВМ.
5. Выполнить перенос ВМ.
6. На новом хосте проверить MAC-адрес и виртуальное оборудование.
7. Запустить ВМ без подключения к рабочей сети.
8. Проверить наличие лицензии 1С.
9. Проверить запуск сервера 1С и подключение тестового пользователя.
10. Только после проверки подключить ВМ к рабочей сети.Для переноса лицензированной ВМ лучше использовать не клонирование, а штатную миграцию или перенос исходной ВМ. При клонировании появляются дополнительные проблемы:
— одинаковые MAC-адреса;
— одинаковые UUID;
— дублирование имени компьютера;
— повторная регистрация в домене;
— конфликт лицензий;
— одновременный доступ к одной и той же базе.—
## 6. Если лицензия 1С привязана к виртуальному CPU
Иногда лицензия ломается не из-за MAC-адреса, а из-за изменения процессора. Например:
— на одном хосте Intel, на другом AMD;
— разное поколение Intel;
— изменилось количество виртуальных ядер;
— изменился режим представления CPU;
— на одном хосте доступны дополнительные инструкции, а на другом нет;
— изменился тип виртуального процессора.В этом случае нужно:
— задать одинаковое количество виртуальных ядер;
— включить CPU compatibility mode;
— использовать максимально совместимую модель CPU;
— не менять количество сокетов без необходимости;
— не использовать проброс физического CPU или нестандартные CPU flags.Для критичной ВМ обычно выбирают единый кластер хостов с совместимыми процессорами. Перенос между Intel и AMD для ВМ с лицензией, привязанной к аппаратным параметрам, может быть проблемным даже при сохранении MAC-адреса.
—
## 7. Если под «лицензией» имеется в виду Windows Server
Здесь есть два разных вопроса.
### Техническая активация Windows
При переносе ВМ Windows может потребовать повторную активацию, если изменилась конфигурация виртуального оборудования. Чтобы снизить вероятность этого:
— сохраняйте VM ID;
— не меняйте виртуальный диск и контроллер;
— сохраняйте MAC-адрес;
— не меняйте поколение ВМ;
— используйте одинаковую конфигурацию ВМ;
— не удаляйте виртуальный TPM;
— для доменных серверов не восстанавливайте одновременно старую и новую копию.Проверить состояние активации можно так:
1С (Код)12slmgr.vbs /dlvslmgr.vbs /xpr### Лицензионные права Windows Server
Важен не только факт активации, но и право запуска Windows Server на целевом физическом хосте.
Если лицензии Windows Server назначены физическому серверу, то при переносе ВМ на другой хост на нем также должны быть лицензированы физические ядра, если это требуется выбранной моделью лицензирования.
Для Windows Server Standard обычно лицензируются все физические ядра хоста, после чего лицензия дает право на определенное количество виртуальных экземпляров. Если на хосте размещается больше ВМ, лицензирование физического хоста может потребоваться выполнить повторно.
Windows Server Datacenter обычно выбирают, когда на физическом сервере должно работать много Windows Server ВМ.
При использовании лицензий с Software Assurance или подписочных правами могут действовать дополнительные права на перемещение виртуальных машин между серверами. Если таких прав нет, свободный перенос ВМ между разными физическими серверами может быть ограничен условиями лицензии, даже если технически миграция выполняется без проблем.
Рекомендую отдельно проверить условия именно вашей лицензии: OEM, Retail, CSP, Open, SPLA, Software Assurance или подписка. У этих вариантов права на перенос отличаются.
—
## 8. Практическая схема для отказоустойчивой 1С
Для двух аппаратно разных хостов лучше организовать так:
1С (Код)123456Хост 1 Хост 2------ ------ВМ 1С ---------------------> перенос ВМ 1С//Сервер лицензированияПри этом:
1. У ВМ фиксированный MAC-адрес.
2. CPU настроен в режиме совместимости.
3. На обоих хостах одинаковый тип виртуального оборудования.
4. ВМ переносится штатной миграцией, а не клонированием.
5. Сервер лицензирования не меняет свои идентификаторы.
6. Есть резервные PIN-коды 1С.
7. Перед переносом проверяется доступность аппаратного ключа или сервера лицензий.
8. Старая копия ВМ выключается до запуска новой в рабочей сети.
9. После миграции проверяется запуск клиента 1С, сервера 1С и получение лицензии.Если лицензия 1С уже сломалась после переезда, сначала нужно вернуть прежние параметры ВМ, особенно MAC-адрес и CPU. Если это не помогло, выполнять восстановление программной лицензии через резервный PIN-код, а не просто копировать файлы лицензии со старой машины.
Привет! Да, конечно, могу отвечать на узбекском языке. Пишите свой вопрос на узбекском.
19 октября 2026 в 19:17 в ответ на: В чём разница между старой и новой методикой контроля остатков в 1С? #38871На экзамене под старой и новой методикой контроля остатков обычно понимают порядок выполнения трех операций:
1. удаление старых движений текущего документа;
2. установка блокировки;
3. чтение остатков и формирование новых движений.Главное различие: в какой момент устанавливается блокировка относительно удаления старых движений.
—
# 1. Зачем вообще нужно удалять старые движения
Рассмотрим документ, который уже был проведен.
Например, раньше документ списывал:
1С (Код)1Товар А: 3 штукиПозже пользователь изменил документ:
1С (Код)1Товар А: 5 штукПеред повторной проверкой остатков старые движения текущего документа нужно удалить. Иначе остаток будет рассчитан неправильно.
Было:
1С (Код)123Фактический остаток без этого документа: 10Старое движение документа: расход 3Остаток с учетом старого документа: 7Если при перепроведении нужно списать 5, проверять надо остаток 10, а не 7.
Для удаления прежних движений текущего документа используется:
1С (Код)12Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();После этого старые движения текущего документа удаляются из регистра.
Важно: эта команда не записывает новые движения, потому что новые движения еще не добавлены в коллекцию. Она фактически удаляет старые движения текущего документа.
—
# 2. Старая методика
Старая последовательность выглядит так:
1С (Код)1234561. Разрешить запись движений.2. Записать движения, чтобы удалить старые движения текущего документа.3. Установить блокировку.4. Прочитать остатки.5. Проверить наличие товара.6. Добавить новые движения.Пример:
1С (Код)1234567891011121314151617181920212223242526Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();Блокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.УстановитьЗначение("Склад",Склад);ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.ИсточникДанных =СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();Затем выполняется запрос остатков:
1С (Код)12345678910111213141516171819202122232425262728Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| Остатки.Номенклатура КАК Номенклатура,| Остатки.КоличествоОстаток КАК КоличествоОстаток|ИЗ| РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| Товары.Номенклатура| ИЗ| &Товары КАК Товары| )| И Склад = &Склад| ) КАК Остатки";Запрос.УстановитьПараметр("МоментВремени",МоментВремени());Запрос.УстановитьПараметр("Склад",Склад);## Проблема старой методики
Между командами:
1С (Код)1Движения.Записать();и:
1С (Код)1Блокировка.Заблокировать();существует промежуток времени, когда старые движения текущего документа уже удалены, но нужные данные еще не заблокированы.
Условно:
1С (Код)12345Старые движения удалены↓Остатки еще не заблокированы↓Установлена блокировкаВ этот промежуток другой пользователь может начать проведение документа по тем же товарам.
Это создает несколько проблем:
— другой документ может прочитать остатки до установки блокировки;
— несколько документов могут одновременно начать проверку одного товара;
— удаление старых движений и проверка остатков выполняются не в одной защищенной последовательности;
— при сложной схеме блокировок возможны конфликты и взаимные ожидания.Старая методика часто встречается в старых материалах, старых экзаменационных решениях и типовых примерах.
—
# 3. Новая методика
В новой методике порядок меняется:
1С (Код)1234561. Разрешить запись движений.2. Установить блокировку.3. Удалить старые движения текущего документа.4. Прочитать остатки.5. Проверить наличие товара.6. Добавить новые движения.То есть блокировка ставится до
Движения.Записать().Пример:
1С (Код)12345678910111213141516171819202122232425262728Движения.ОстаткиНоменклатуры.Записывать = Истина;Блокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.УстановитьЗначение("Склад",Склад);ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.ИсточникДанных =СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();// Теперь старые движения удаляются уже внутри защищенного участка.Движения.Записать();После этого читаются остатки:
1С (Код)12345678910111213141516171819202122232425262728Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| Остатки.Номенклатура КАК Номенклатура,| Остатки.КоличествоОстаток КАК КоличествоОстаток|ИЗ| РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| Товары.Номенклатура| ИЗ| &Товары КАК Товары| )| И Склад = &Склад| ) КАК Остатки";Запрос.УстановитьПараметр("МоментВремени",МоментВремени());Запрос.УстановитьПараметр("Склад",Склад);## Преимущество новой методики
Получается защищенная последовательность:
1С (Код)123456789Получили блокировку↓Удалили старые движения↓Прочитали остатки↓Проверили наличие↓Сформировали новые движенияДругой документ не сможет вмешаться в работу с теми же складом и номенклатурой между удалением старых движений и проверкой остатков.
—
# 4. Сравнение на конкретном примере
Пусть имеется:
1С (Код)123Склад: Основной складТовар: Товар АФактический остаток: 10Есть два документа:
1С (Код)12Документ 1: списать 7Документ 2: списать 7Они проводятся почти одновременно.
## При корректной блокировке
Документ 1:
1С (Код)1234Установил блокировкуПрочитал остаток 10Списал 7Завершил проведениеДокумент 2:
1С (Код)1234Получил блокировку после документа 1Прочитал остаток 3Обнаружил нехваткуНе провелсяОтрицательного остатка не возникает.
## При отсутствии блокировки
Оба документа могут сделать так:
1С (Код)1234Документ 1 прочитал остаток 10Документ 2 прочитал остаток 10Документ 1 списал 7Документ 2 списал 7Итог:
1С (Код)110 - 7 - 7 = -4Именно поэтому блокировка должна быть установлена до чтения остатков.
—
# 5. Почему в новой методике
Движения.Записать()идет после блокировкиНа первый взгляд кажется, что это нелогично:
1С (Код)12Блокировка.Заблокировать();Движения.Записать();Ведь
Движения.Записать()удаляет старые движения, а не проверяет остатки.Но при перепроведении документа это обязательная часть алгоритма:
1С (Код)123456789Документ уже имеет старые движения↓Получаем блокировку по нужным остаткам↓Удаляем старые движения↓Считаем остатки без старой версии документа↓Формируем новую версию движенийИменно поэтому новая методика безопаснее.
—
# 6. Что блокируется в новой методике
Блокируется не виртуальная таблица
.Остатки, а сам регистр:1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");В запросе используется виртуальная таблица:
1С (Код)1|РегистрНакопления.ОстаткиНоменклатуры.Остатки(...)Это разные вещи:
1С (Код)1РегистрНакопления.ОстаткиНоменклатурыэто объект данных, по которому устанавливается блокировка.
1С (Код)1РегистрНакопления.ОстаткиНоменклатуры.Остаткиэто виртуальная таблица запроса, через которую платформа рассчитывает остатки.
Поэтому в блокировке:
1С (Код)1"РегистрНакопления.ОстаткиНоменклатуры"А в запросе:
1С (Код)1|РегистрНакопления.ОстаткиНоменклатуры.Остатки(...)—
# 7. Зачем передавать табличную часть как источник данных
В новой методике часто используется:
1С (Код)1234567ЭлементБлокировки.ИсточникДанных =СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Это означает:
1С (Код)12Блокировать регистр по складу текущего документаи по номенклатуре из табличной части текущего документа.Например, табличная часть содержит:
1С (Код)123Товар АТовар БТовар ВТогда блокировка устанавливается примерно по условию:
1С (Код)12Склад = Основной складИ Номенклатура В (Товар А, Товар Б, Товар В)Табличная часть сама не блокируется. Она используется только как источник значений для отбора.
—
# 8. Когда применять старую методику
Старую методику можно встретить:
— в старых учебных материалах;
— в старых решениях экзаменационных задач;
— в коде, написанном до распространения новой схемы управляемых блокировок;
— в примерах, где не рассматривается безопасное перепроведение;
— в конфигурациях, где алгоритм уже построен именно таким образом и его нельзя быстро изменить.С точки зрения подготовки к экзамену ее нужно знать, потому что в старых сборниках и видео она встречается достаточно часто.
Но если в задании требуется современная реализация оперативного проведения с управляемыми блокировками, предпочтительнее использовать новую методику.
—
# 9. Когда применять новую методику
Новую методику нужно использовать, когда:
— документ является оперативным;
— есть контроль остатков;
— документ может проводиться одновременно с другими документами;
— документ может перепроводиться;
— необходимо защититься от отрицательных остатков;
— используется управляемый режим блокировок;
— в задании явно говорится о конкурентном проведении или необходимости исключить отрицательные остатки.На экзамене это обычно безопасный основной вариант.
—
# 10. Полный каркас новой методики
Общая схема:
1С (Код)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121Процедура ОбработкаПроведения(Отказ, Режим)Движения.ОстаткиНоменклатуры.Записывать = Истина;Блокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.УстановитьЗначение("Склад",Склад);ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.ИсточникДанных =СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();// Удаление старых движений текущего документа.Движения.Записать();// Получение остатков.Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| Товары.Номенклатура КАК Номенклатура,| Товары.Количество КАК Количество,| ЕСТЬNULL(| Остатки.КоличествоОстаток,| 0| ) КАК КоличествоОстаток|ИЗ| &Товары КАК Товары| ЛЕВОЕ СОЕДИНЕНИЕ| РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| Товары.Номенклатура| ИЗ| &Товары КАК Товары| )| И Склад = &Склад| ) КАК Остатки| ПО Товары.Номенклатура =| Остатки.Номенклатура";Запрос.УстановитьПараметр("МоментВремени",МоментВремени());Запрос.УстановитьПараметр("Склад",Склад);Запрос.УстановитьПараметр("Товары",СписокНоменклатуры.Выгрузить());РезультатЗапроса = Запрос.Выполнить();ТаблицаОстатков = РезультатЗапроса.Выгрузить();// Сначала полностью проверяем документ.Для каждого СтрокаОстатковИз ТаблицаОстатков ЦиклЕсли СтрокаОстатков.Количество >СтрокаОстатков.КоличествоОстаток ТогдаСообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ Строка(СтрокаОстатков.Номенклатура);Сообщение.Сообщить();Отказ = Истина;КонецЕсли;КонецЦикла;Если Отказ ТогдаВозврат;КонецЕсли;// Только после полной проверки формируем движения.Для каждого СтрокаОстатковИз ТаблицаОстатков ЦиклДвижение =Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения =ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура =СтрокаОстатков.Номенклатура;Движение.Склад = Склад;Движение.Количество =СтрокаОстатков.Количество;КонецЦикла;КонецПроцедурыВ экзаменационном решении структура может отличаться, но логика должна быть такой:
1С (Код)1234567установить признак записи движенийустановить блокировкузаписать старые движенияполучить остаткипроверить все строкипри нехватке завершить проведениепри отсутствии ошибок сформировать движения—
# 11. Важная оговорка для экзамена
На конкретном экзамене нужно ориентироваться прежде всего на:
— формулировку задания;
— методические рекомендации к текущей версии экзамена;
— каркас конфигурации;
— требования к оперативному или неоперативному проведению;
— наличие управляемого режима блокировок.Термины «старая методика» и «новая методика» могут использоваться авторами учебных материалов немного по-разному. Но практически важное отличие обычно заключается именно в этом:
1С (Код)1234567Старая методика:Движения.Записать();Блокировка.Заблокировать();Новая методика:Блокировка.Заблокировать();Движения.Записать();Для современного решения контроля остатков при конкурентном проведении используйте:
1С (Код)12Блокировка.Заблокировать();Движения.Записать();Затем читайте остатки и только после успешной проверки формируйте новые движения.
Для магазина автозапчастей в большинстве случаев лучше выбирать 1С:Управление торговлей, особенно если планируется полноценный складской учет, большой ассортимент и работа с несколькими поставщиками.
1С:УНФ подойдет, если магазин небольшой и нужно быстро начать работать без сложной системы.
## Краткий выбор
| Задача | Что лучше |
|—|—|
| Один небольшой магазин | 1С:УНФ |
| Один магазин, но большой ассортимент | 1С:УТ |
| Несколько магазинов или складов | 1С:УТ |
| Много поставщиков | 1С:УТ |
| Закупки по остаткам и продажам | 1С:УТ |
| Сложные цены, скидки, акции | 1С:УТ |
| Только продажи, касса и простой склад | 1С:УНФ |
| Интернет-магазин запчастей | 1С:УТ |
| Автосервис вместе с магазином | 1С:УНФ может быть удобнее |
| Необходим бухгалтерский и налоговый учет в одной программе | Нужно отдельно проверять схему, чаще УТ + БП |## Когда выбирать 1С:УНФ
УНФ разумно использовать, если:
— один магазин или небольшая торговая точка;
— 1-3 пользователя;
— ассортимент относительно небольшой;
— нет сложного распределительного склада;
— закупки выполняются вручную;
— достаточно обычных цен и скидок;
— нужен простой интерфейс для продавцов;
— магазин совмещен с автосервисом;
— нужно учитывать работы, услуги, заказы клиентов и небольшое производство;
— бюджет на внедрение ограничен.В УНФ обычно проще работать продавцу. Можно вести:
— продажи через кассу;
— заказы покупателей;
— закупки;
— остатки товаров;
— перемещения;
— возвраты;
— скидки;
— взаиморасчеты;
— работы и услуги;
— простые отчеты по продажам и прибыли.Для небольшой точки это часто удобнее, чем внедрять более тяжелую УТ.
## Когда выбирать 1С:УТ
УТ лучше подходит, если магазин запчастей развивается как полноценный торговый бизнес:
— несколько торговых точек;
— центральный склад и магазины;
— десятки тысяч позиций;
— большое количество поставщиков;
— регулярные закупки;
— импорт товаров;
— заказы клиентов под конкретный автомобиль;
— резервирование товаров;
— перемещение между магазинами;
— продажа под заказ;
— интернет-магазин;
— разные типы цен для розницы, СТО и опта;
— накопительные скидки;
— акции;
— бонусные программы;
— контроль неликвидов и дефицита;
— планирование закупок;
— анализ продаж по поставщикам, брендам и группам товаров.В УТ обычно лучше реализованы:
— управление ассортиментом;
— оптовые и розничные продажи;
— ценообразование;
— закупки;
— контроль остатков;
— обеспечение потребностей;
— складская логистика;
— несколько организаций и складов;
— работа с заказами;
— анализ маржинальности;
— обмен с интернет-магазином.## Главный нюанс для магазина автозапчастей
Ни УТ, ни УНФ сами по себе не являются специализированной системой для каталога автозапчастей.
Для магазина запчастей обычно важны:
— оригинальный номер детали;
— артикулы производителей;
— кросс-номера;
— аналоги;
— применяемость к марке, модели, кузову и двигателю;
— VIN-поиск;
— связь детали с автомобилем;
— бренд;
— страна производства;
— срок поставки;
— несколько артикулов на одну запчасть;
— автоматическая загрузка прайсов поставщиков;
— актуализация остатков и цен поставщиков.Стандартный справочник номенклатуры 1С этого полноценно не решает. Обычно требуется:
1. дополнительная обработка или расширение;
2. интеграция с каталогом автозапчастей;
3. загрузка прайсов поставщиков;
4. настройка сопоставления артикулов;
5. отдельный механизм хранения аналогов и применяемости;
6. интеграция с сайтом или специализированным каталогом.Поэтому при выборе программы нужно оценивать не только название конфигурации, но и то, как будет организован каталог запчастей.
## Что важно настроить в любой из программ
Для автозапчастей не стоит использовать только одно поле «Наименование». Лучше заранее определить структуру:
— Вид номенклатуры: запчасть, масло, расходник, аксессуар;
— Бренд;
— Артикул производителя;
— Оригинальный номер;
— Каталожный номер;
— Единица измерения;
— Вес и габариты;
— Страна производства;
— Группа запчастей;
— Поставщик;
— Срок поставки;
— Аналоги;
— Минимальный остаток;
— Срок хранения;
— Штрихкод.Важный момент: один и тот же товар у разных поставщиков может иметь разные артикулы. Если не настроить сопоставление, в базе появятся дубли:
— «Фильтр воздушный Bosch 1457433525»;
— «Bosch 1 457 433 525»;
— «Фильтр Bosch 1457433525»;
— «Фильтр воздушный 1457433525».Для магазина это приводит к неправильным остаткам и ошибкам закупки.
## УТ плюс Бухгалтерия или УНФ как единая программа
Часто УТ используют для оперативного учета, а бухгалтерский и налоговый учет ведут в 1С:Бухгалтерии:
1С (Код)1231С:Управление торговлей↓ обмен1С:Бухгалтерия предприятияЭто хороший вариант для магазина, где нужны развитые продажи и закупки, но бухгалтер должен работать отдельно.
УНФ больше ориентирована на то, чтобы закрыть в одной программе:
— продажи;
— закупки;
— склад;
— деньги;
— простое производство;
— услуги;
— управленческий учет;
— часть регламентированного учета.Но перед выбором нужно проверить, подходит ли УНФ именно под вашу систему налогообложения и требования бухгалтера.
## Практическая рекомендация
### Выбирайте УНФ, если:
— один магазин;
— до нескольких продавцов;
— до нескольких тысяч основных товарных позиций;
— нет сложной логистики;
— нет нескольких складов;
— продажи и закупки достаточно простые;
— каталог запчастей будет вестись во внешней системе или вручную;
— важны низкая стоимость и простой запуск.### Выбирайте УТ, если:
— ассортимент составляет десятки тысяч позиций;
— есть постоянные заказы под клиентов;
— несколько поставщиков;
— нужно автоматически загружать прайсы;
— есть оптовые продажи;
— планируется интернет-магазин;
— будет несколько складов или торговых точек;
— важен контроль закупок и неликвидов;
— необходимы сложные цены и скидки;
— требуется развитие бизнеса без перехода на другую конфигурацию через год.Для обычного небольшого магазина у дома я бы рассматривал УНФ. Для специализированного магазина автозапчастей с широким ассортиментом, поставщиками и заказами под VIN я бы выбирал УТ, но обязательно закладывал отдельное решение для каталога, аналогов, применяемости и загрузки прайсов.
18 октября 2026 в 17:55 в ответ на: Как правильно обрабатывать «Ошибка 5. Движения добавляются даже после обнаружени #38867ПродолжитьиВозвратработают по-разному.## Если написать
Возврат1С (Код)123Если Отказ ТогдаВозврат;КонецЕсли;процедура проведения немедленно завершится.
Если этот код находится после цикла проверки:
1С (Код)1234567891011121314Пока Выборка.Следующий() ЦиклЕсли Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;КонецЕсли;КонецЦикла;Если Отказ ТогдаВозврат;КонецЕсли;то результат такой:
1. Проверены все строки.
2. Если хотя бы по одной строке нехватка, установленОтказ = Истина.
3. После завершения цикла процедура завершилась.
4. Формирование движений не выполняется.Это правильный вариант, если проверка и формирование движений находятся в одной процедуре последовательно.
## Если написать
Продолжить1С (Код)123Если Отказ ТогдаПродолжить;КонецЕсли;Продолжитьне завершает процедуру. Он только пропускает текущую итерацию цикла и переходит к следующей строке.Например:
1С (Код)1234567891011121314151617181920212223242526272829Пока Выборка.Следующий() ЦиклЕсли Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;Сообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ Выборка.НоменклатураПредставление;Сообщение.Сообщить();Продолжить;КонецЕсли;Движение =Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения =ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура = Выборка.Номенклатура;Движение.Склад = Склад;Движение.Количество = Выборка.Количество;КонецЦикла;Здесь получится следующая логика:
1С (Код)123Товар 1: остатка хватает, движение добавленоТовар 2: остатка не хватает, движение не добавленоТовар 3: остатка хватает, движение добавленоТо есть
Продолжитьпропустит только товар с нехваткой. Для следующих товаров цикл продолжится.## Но при
Отказ = Истинадокумент все равно не проведетсяВ типовой процедуре проведения, если в конце остается:
1С (Код)1Отказ = Истина;документ не должен быть проведен, а автоматически формируемые движения не должны попасть в регистр.
Поэтому при таком коде:
1С (Код)123456789Если Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;Продолжить;КонецЕсли;Движение = Движения.ОстаткиНоменклатуры.Добавить();движения по товарам, которых хватает, будут добавлены в коллекцию
Движения, но при отказе проведение всего документа будет отменено.Однако это не означает, что такой вариант лучше.
## В чем проблема подхода с
ПродолжитьПроблема в том, что в коллекции движений уже появятся движения по части товаров, хотя весь документ в итоге будет отклонен.
Получится промежуточное состояние:
1С (Код)123Отказ = ИстинаВ Движения добавлены движения по некоторым товарамДокумент не проведенПлатформа обычно не запишет эти движения при отказе, но сам алгоритм становится менее понятным. Если в процедуре есть явные вызовы:
1С (Код)1Движения.Записать();или другая дополнительная запись движений, можно получить нежелательные последствия.
Главный принцип:
> Сначала полностью проверить документ, и только если ошибок нет, формировать движения.
## Правильный вариант: два цикла
Лучше разделить проверку остатков и формирование движений.
### Первый цикл, только проверка
1С (Код)12345678910111213141516171819202122232425262728293031Отказ = Ложь;ТаблицаОстатков =РезультатЗапроса.Выгрузить();Для каждого СтрокаОстатков Из ТаблицаОстатков ЦиклЕсли СтрокаОстатков.Количество >СтрокаОстатков.КоличествоОстаток ТогдаНехватка =СтрокаОстатков.Количество- СтрокаОстатков.КоличествоОстаток;Сообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ СтрокаОстатков.НоменклатураПредставление+ ". Требуется: "+ Строка(СтрокаОстатков.Количество)+ ", остаток: "+ Строка(СтрокаОстатков.КоличествоОстаток)+ ", нехватка: "+ Строка(Нехватка);Сообщение.Сообщить();Отказ = Истина;КонецЕсли;КонецЦикла;### Если есть ошибка, завершить процедуру
1С (Код)123Если Отказ ТогдаВозврат;КонецЕсли;### Второй цикл, только формирование движений
1С (Код)12345678910111213141516Для каждого СтрокаОстатков Из ТаблицаОстатков ЦиклДвижение =Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения =ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура =СтрокаОстатков.Номенклатура;Движение.Склад = Склад;Движение.Количество =СтрокаОстатков.Количество;КонецЦикла;Это наиболее прозрачная схема:
1С (Код)1234получить остаткипроверить все товарыпри ошибке завершить проведениеесли ошибок нет, создать все движения## Когда
Продолжитьдействительно уместенПродолжитьуместен, если вы сознательно хотите пропускать отдельные строки и обрабатывать остальные:1С (Код)123456789Для каждого Строка Из ТаблицаТоваров ЦиклЕсли Строка.Номенклатура.ПомеченНаУдаление ТогдаПродолжить;КонецЕсли;// обработка остальных строкКонецЦикла;Например:
— пропустить пустую строку;
— пропустить товар определенного вида;
— не формировать движение по строкам, не участвующим в операции;
— собрать ошибки по всем строкам и продолжить проверку.Но для контроля остатков расходной накладной обычно нужно не просто пропустить проблемную строку, а отменить проведение всего документа. Поэтому здесь лучше использовать не
ПродолжитьвместоВозврат, а отдельный цикл проверки и затем:1С (Код)123Если Отказ ТогдаВозврат;КонецЕсли;## Вариант с одним циклом
Если не хочется делать два цикла, можно проверять все строки, но движения не формировать сразу:
1С (Код)1234567891011121314151617181920212223242526Отказ = Ложь;Пока Выборка.Следующий() ЦиклЕсли Выборка.Количество >Выборка.КоличествоОстаток ТогдаОтказ = Истина;Сообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ Выборка.НоменклатураПредставление;Сообщение.Сообщить();Продолжить;КонецЕсли;// Здесь движение пока не добавляемКонецЦикла;Если Отказ ТогдаВозврат;КонецЕсли;Но после этого потребуется снова пройти результат запроса для формирования движений. Поэтому практически удобнее:
1С (Код)1РезультатЗапроса.Выгрузить()и два прохода по таблице значений.
## Кратко по различиям
1С (Код)1Продолжить;означает:
1С (Код)1пропустить текущую строку и перейти к следующей строке цикла1С (Код)1Возврат;означает:
1С (Код)1немедленно выйти из процедурыВ вашем случае:
1С (Код)123Если Отказ ТогдаПродолжить;КонецЕсли;не прекращает обработку документа. Он позволяет продолжить цикл, и движения по следующим товарам будут добавляться.
Для полного запрета проведения при нехватке хотя бы одного товара лучше использовать такую схему:
1С (Код)123456789101112Сначала проверить все строки.Если найдена нехватка:Отказ = Истина.После цикла:Если Отказ ТогдаВозврат;КонецЕсли;И только после этого:сформировать движения.18 октября 2026 в 13:00 в ответ на: Почему блокировка выполняется по регистру, а не по виртуальной таблице остатков, #38865В вашем коде смешаны три разных понятия:
1. Физический регистр накопления.
2. Виртуальная таблица регистра.Остатки.
3. Табличная часть документа, которая используется как источник ключей для блокировки.Разберем по порядку.
## 1. Почему в блокировке используется регистр без
.ОстаткиДля блокировки нужно указывать имя самого регистра накопления:
1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");А в запросе остатки получаются через виртуальную таблицу:
1С (Код)1|РегистрНакопления.ОстаткиНоменклатуры.Остатки(...)Это разные конструкции.
### Физический регистр
1С (Код)1РегистрНакопления.ОстаткиНоменклатурыЭто объект метаданных, в котором хранятся движения:
1С (Код)123456789Приход:СкладНоменклатураКоличествоРасход:СкладНоменклатураКоличествоИменно этот объект можно заблокировать.
### Виртуальная таблица остатков
1С (Код)1РегистрНакопления.ОстаткиНоменклатуры.ОстаткиЭто не отдельная таблица хранения. Это виртуальная таблица, которую платформа рассчитывает по движениям регистра.
Она возвращает рассчитанный результат:
1С (Код)123СкладНоменклатураКоличествоОстатокВиртуальная таблица существует только во время выполнения запроса. В ней нельзя устанавливать блокировку как в самостоятельном объекте данных.
Поэтому:
1С (Код)1234// Неправильная идея для блокировкиБлокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры.Остатки");Нужно:
1С (Код)1234// ПравильноБлокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");Проще запомнить так:
1С (Код)12Блокируем движения регистра.Читаем остатки через виртуальную таблицу регистра.Блокировка движений гарантирует, что пока текущая транзакция проверяет остатки и формирует свои движения, другая транзакция не сможет одновременно изменить те же самые остатки с использованием конфликтующей управляемой блокировки.
## 2. Почему источник блокировки является табличной частью документа
Вот этот код:
1С (Код)12345ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");не означает, что блокируется табличная часть документа.
Табличная часть здесь используется только как источник значений для формирования блокировки.
То есть платформа берет из
СписокНоменклатурызначения колонкиНоменклатураи строит условие блокировки примерно такого вида:1С (Код)12345678Регистр.ОстаткиНоменклатурыГДЕСклад = текущий складИ Номенклатура В (Товар 1,Товар 2,Товар 3)Блокируется не документ и не табличная часть.
Блокируется именно регистр:
1С (Код)1РегистрНакопления.ОстаткиНоменклатурыТабличная часть только сообщает, по каким значениям измерения
Номенклатуранужно блокировать регистр.## 3. Что делает
ИсточникДанныхРассмотрим эти строки:
1С (Код)123456ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Вызов:
1С (Код)1ИсточникДанных = СписокНоменклатурыпередает платформе таблицу или табличную часть, из которой нужно взять значения.
Вызов:
1С (Код)1234ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура")устанавливает соответствие:
1С (Код)12Измерение регистра Колонка источникаНоменклатура НоменклатураЛевый параметр:
1С (Код)1"Номенклатура"это имя измерения регистра.
Правый параметр:
1С (Код)1"Номенклатура"это имя колонки табличной части.
В вашем случае имена совпадают, поэтому код выглядит симметрично. Они могут называться по-разному:
1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Товар");Это означало бы:
1С (Код)12измерение регистра Номенклатуразаполнять значениями колонки Товар## 4. Разбор блокировки построчно
Ваш фрагмент:
1С (Код)1Блокировка = Новый БлокировкаДанных;Создается объект управляемой блокировки данных.
Пока вызван только конструктор, никакие данные еще не заблокированы.
1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");В объект блокировки добавляется один элемент.
Он указывает, какой объект данных нужно блокировать:
1С (Код)1РегистрНакопления.ОстаткиНоменклатурыПравильный вариант должен быть именно без
.Остатки:1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");1С (Код)1234ЭлементБлокировки.УстановитьЗначение("Склад",Склад);Устанавливается фиксированное значение измерения
Склад.Если текущий документ оформляется по складу
Склад1, то блокировка будет ограничена этим складом:1С (Код)1Склад = Склад1Пока измерение
Номенклатураеще не задано, условие можно представить так:1С (Код)12Все записи регистрапо складу Склад1Следующая настройка ограничит его еще и по номенклатуре.
1С (Код)12ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;Устанавливается исключительный режим блокировки.
Смысл:
> текущая транзакция получает исключительное право на изменение заблокированных наборов данных относительно других управляемых блокировок.
Если второй пользователь одновременно пытается провести документ по тем же складу и товарам, его блокировка будет конфликтовать с первой.
Это предотвращает ситуацию:
1С (Код)123456789Остаток товара: 10Документ пользователя 1: списать 7Документ пользователя 2: списать 7Оба пользователя одновременно читают остаток 10.Оба считают, что товара хватает.Оба проводят документы.Итоговый остаток становится -4.При правильной блокировке происходит иначе:
1С (Код)12345678Пользователь 1 захватывает блокировку.Пользователь 1 видит остаток 10.Пользователь 1 списывает 7.Пользователь 1 завершает транзакцию.Пользователь 2 получает блокировку после этого.Пользователь 2 видит остаток 3.Пользователь 2 получает отказ.Важно: управляемая блокировка работает только между операциями, которые также используют управляемые блокировки. Если часть кода или внешняя система работает в обход установленной схемы блокировок, защита может быть неполной.
1С (Код)12ЭлементБлокировки.ИсточникДанных =СписокНоменклатуры;Источником значений для отбора является табличная часть текущего документа.
Платформа будет брать из нее строки, например:
1С (Код)12345Номенклатура-----------Товар АТовар БТовар ВЭта строка не блокирует табличную часть. Она только передает значения для блокировки регистра.
1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Настраивается отбор:
1С (Код)12Измерение регистра Номенклатураполучить из колонки источника НоменклатураПосле этой строки итоговая блокировка концептуально становится такой:
1С (Код)123456РегистрНакопления.ОстаткиНоменклатурыГДЕСклад = СкладИ Номенклатура В (значения из СписокНоменклатуры.Номенклатура)1С (Код)1Блокировка.Заблокировать();Именно здесь блокировка реально устанавливается.
До вызова:
1С (Код)1Блокировка.Заблокировать();объект только настраивается.
После вызова:
1С (Код)1Блокировка.Заблокировать();текущая транзакция пытается получить указанные блокировки.
Только после успешного получения блокировки нужно читать остатки:
1С (Код)1234получили блокировкупрочитали остаткисравнили с количеством документазаписали движения## 5. Что именно блокируется в вашем случае
Предположим:
1С (Код)12345Склад = Основной складСписокНоменклатуры:МолотокДрельТогда блокировка концептуально будет такой:
1С (Код)123РегистрНакопления.ОстаткиНоменклатурыСклад = Основной складНоменклатура = Молоток или ДрельОна не блокирует:
1С (Код)1234567весь документ;всю табличную часть;все склады;всю номенклатуру;виртуальную таблицу Остатки;остатки других товаров на этом складе;остатки этих товаров на других складах.Она блокирует нужный участок регистра по аналитикам, участвующим в списании.
## 6. Почему источник лучше брать из табличной части
Потому что табличная часть содержит конкретный набор товаров, с которыми работает документ.
Если вручную формировать список блокируемой номенклатуры, пришлось бы сначала:
1. прочитать табличную часть;
2. собрать массив или таблицу значений;
3. передать ее в блокировку.При использовании источника данных платформа может использовать табличную часть напрямую:
1С (Код)1ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;Это удобно и наглядно.
Кроме того, блокировка получается ограниченной:
1С (Код)123не весь регистр,а только товары текущего документана текущем складе## 7. Но в вашем коде есть ошибка в имени регистра
Сейчас у вас:
1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры.Остатки");Нужно исправить на:
1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");.Остаткииспользуется в запросе:1С (Код)12345|РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В (...)| И Склад = &Склад|)А в блокировке используется имя объекта данных:
1С (Код)1"РегистрНакопления.ОстаткиНоменклатуры"## 8. Еще одна важная ошибка: движения записываются до блокировки
В начале процедуры у вас:
1С (Код)1234Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();Движения.ОстаткиНоменклатуры.Записывать = Истина;Вторая строка:
1С (Код)1Движения.ОстаткиНоменклатуры.Записывать = Истина;дублируется и сама по себе не нужна.
Первый вызов:
1С (Код)1Движения.Записать();обычно используется для удаления старых движений текущего документа перед чтением остатков. Это нужно при перепроведении документа, чтобы его старые движения не увеличивали остаток во время проверки.
Но в вашем коде это выполняется до блокировки:
1С (Код)123записать пустые или текущие движенияпопытаться установить блокировкупрочитать остаткиНадежнее сначала установить блокировку, а затем записать набор движений, чтобы исключить старые движения текущего документа:
1С (Код)123456789101112131415161718Движения.ОстаткиНоменклатуры.Записывать = Истина;Блокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.УстановитьЗначение("Склад", Склад);ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();// Удаляем старые движения текущего документа// из расчета остатков при перепроведении.Движения.Записать();Зачем вообще нужен
Движения.Записать()до запроса?Представим документ уже проводился раньше:
1С (Код)123Остаток до старого документа: 10Старое движение этого документа: расход 3Остаток в регистре: 7Теперь пользователь изменил документ, и новый расход должен быть 5.
Если читать остаток, не удалив старое движение, можно получить:
1С (Код)1остаток 7Но для повторной проверки нужно учитывать состояние без старого варианта этого же документа:
1С (Код)1остаток 10И только после проверки необходимо записать новое движение расхода 5, получив остаток 5.
## 9. Поле
Количествов блокировке не используетсяВы блокируете регистр по:
1С (Код)12СкладНоменклатураПоле
Количествоне нужно блокировать, потому что это ресурс, а не измерение.Блокировка устанавливается по аналитикам, определяющим остаток.
Если регистр имеет структуру:
1С (Код)123456Измерения:СкладНоменклатураРесурсы:Количеството блокировать нужно:
1С (Код)12СкладНоменклатураЕсли в регистре появятся дополнительные измерения:
1С (Код)123ХарактеристикаСерияКачеството их тоже нужно учитывать в блокировке:
1С (Код)123456789101112131415161718ЭлементБлокировки.УстановитьЗначение("Склад", Склад);ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Характеристика","Характеристика");ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Серия","Серия");Иначе можно заблокировать не тот уровень аналитики, который реально используется при расчете остатков.
## 10. В вашем запросе блокировка и отбор должны соответствовать друг другу
В запросе вы получаете остатки по:
1С (Код)12|Номенклатура В (...)|И Склад = &СкладВ блокировке должны использоваться те же аналитики:
1С (Код)12Склад = Склад документаНоменклатура = номенклатура из табличной частиЭто важный принцип:
1С (Код)12Что участвует в чтении остатков,то же должно участвовать в блокировке.Если запрос читает остатки по складу и номенклатуре, а блокировка установлена только по складу, то блокировка будет слишком широкой.
Если запрос читает по складу, номенклатуре и серии, а блокировка установлена только по складу и номенклатуре, то блокировка будет недостаточно точной.
## 11. Исправленный фрагмент проведения
Для вашей структуры регистра базовый вариант может выглядеть так:
1С (Код)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143Процедура ОбработкаПроведения(Отказ, Режим)Движения.ОстаткиНоменклатуры.Записывать = Истина;Блокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.УстановитьЗначение("Склад",Склад);ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.ИсточникДанных =СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();// При перепроведении удаляем прежние движения// текущего документа перед чтением остатков.Движения.Записать();Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество|ПОМЕСТИТЬ втТЧТовары|ИЗ| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры|ГДЕ| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка||СГРУППИРОВАТЬ ПО| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура|;||////////////////////////////////////////////////////////////////////////////////|ВЫБРАТЬ| втТЧТовары.Номенклатура КАК Номенклатура,| втТЧТовары.Номенклатура.Представление КАК НоменклатураПредставление,| втТЧТовары.Количество КАК Количество,| ЕСТЬNULL(| ОстаткиНоменклатурыОстатки.КоличествоОстаток,| 0| ) КАК КоличествоОстаток|ИЗ| втТЧТовары КАК втТЧТовары| ЛЕВОЕ СОЕДИНЕНИЕ| РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| втТЧТовары.Номенклатура| ИЗ| втТЧТовары КАК втТЧТовары| )| И Склад = &Склад| ) КАК ОстаткиНоменклатурыОстатки| ПО втТЧТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.Номенклатура";Запрос.УстановитьПараметр("МоментВремени",МоментВремени());Запрос.УстановитьПараметр("Склад",Склад);Запрос.УстановитьПараметр("Ссылка",Ссылка);РезультатЗапроса = Запрос.Выполнить();Выборка = РезультатЗапроса.Выбрать();Пока Выборка.Следующий() ЦиклЕсли Выборка.Количество >Выборка.КоличествоОстаток ТогдаСообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара "+ Выборка.НоменклатураПредставление+ ". Требуется: "+ Строка(Выборка.Количество)+ ", остаток: "+ Строка(Выборка.КоличествоОстаток)+ ", нехватка: "+ Строка(Выборка.Количество- Выборка.КоличествоОстаток);Сообщение.Сообщить();Отказ = Истина;КонецЕсли;КонецЦикла;Если Отказ ТогдаВозврат;КонецЕсли;// Движения записываются только после успешной проверки.Выборка = РезультатЗапроса.Выбрать();Пока Выборка.Следующий() ЦиклДвижение =Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения =ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура =Выборка.Номенклатура;Движение.Склад = Склад;Движение.Количество =Выборка.Количество;КонецЦикла;КонецПроцедурыОднако в этом варианте есть технический нюанс: после завершения первой выборки результат запроса обычно нужно получить или выбрать заново, как показано выше, либо заранее выгрузить результат в таблицу значений. На практике удобнее сначала выгрузить результат:
1С (Код)1ТаблицаОстатков = РезультатЗапроса.Выгрузить();потом проверить таблицу, а затем пройти по ней второй раз для формирования движений.
## 12. Что в исходном коде нужно исправить
В вашем варианте я бы исправил следующее:
### Ошибка 1. Имя объекта блокировки
Было:
1С (Код)1"РегистрНакопления.ОстаткиНоменклатуры.Остатки"Нужно:
1С (Код)1"РегистрНакопления.ОстаткиНоменклатуры"### Ошибка 2. Дублирование установки записи движений
Было:
1С (Код)1234Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();Движения.ОстаткиНоменклатуры.Записывать = Истина;Вторая строка лишняя.
### Ошибка 3. Старые движения удаляются до блокировки
Лучше устанавливать блокировку до:
1С (Код)1Движения.Записать();чтобы операция удаления старых движений и последующее чтение остатков проходили в защищенной последовательности.
### Ошибка 4. Сообщение показывает не нехватку, а требуемое количество
Сейчас:
1С (Код)12345Сообщение.Текст ="У вас не хватает товара "+ Выборка.НоменклатураПредставление+ " в количестве "+ Выборка.Количество;Здесь выводится количество, которое требуется списать, а не количество нехватки.
Правильнее:
1С (Код)123Нехватка =Выборка.Количество- Выборка.КоличествоОстаток;И выводить
Нехватка.### Ошибка 5. Движения добавляются даже после обнаружения нехватки других товаров
Вы устанавливаете:
1С (Код)1Отказ = Истина;но продолжаете обход и добавляете движения по товарам, которых хватает.
Обычно лучше сначала проверить весь документ, а движения формировать только если:
1С (Код)123Если Отказ ТогдаВозврат;КонецЕсли;### Ошибка 6. При повторном проведении нужно учитывать старые движения
Именно для этого в начале проведения часто выполняют:
1С (Код)12Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();Но делать это нужно в правильной последовательности относительно блокировки и запроса.
18 октября 2026 в 12:23 в ответ на: Как правильно построить запрос на контроль остатков в 1С? #38863Запрос построен почти правильно, но в нем есть существенная ошибка в отборе номенклатуры.
Сейчас у вас написано:
1С (Код)12345|Номенклатура В| (ВЫБРАТЬ| ОстаткиНоменклатуры.Номенклатура КАК Номенклатура| ИЗ| РегистрНакопления.ОстаткиНоменклатуры КАК ОстаткиНоменклатуры)Здесь подзапрос выбирает номенклатуру не из временной таблицы документа, а из самого регистра накопления. То есть условие фактически означает:
> получить остатки по всей номенклатуре, которая когда-либо встречается в регистре.
Нужно выбирать номенклатуру из
втТЧТовары.Исправленный вариант:
1С (Код)123456789101112131415161718192021222324252627282930313233343536373839404142Запрос = Новый Запрос;Запрос.Текст ="ВЫБРАТЬ| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество|ПОМЕСТИТЬ втТЧТовары|ИЗ| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры|ГДЕ| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка||СГРУППИРОВАТЬ ПО| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура|;||////////////////////////////////////////////////////////////////////////////////|ВЫБРАТЬ| втТЧТовары.Номенклатура КАК Номенклатура,| втТЧТовары.Номенклатура.Представление КАК НоменклатураПредставление,| втТЧТовары.Количество КАК Количество,| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток|ИЗ| втТЧТовары КАК втТЧТовары| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| втТЧТовары.Номенклатура| ИЗ| втТЧТовары КАК втТЧТовары| )| И Склад = &Склад| ) КАК ОстаткиНоменклатурыОстатки| ПО втТЧТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.Номенклатура";Запрос.УстановитьПараметр("МоментВремени", МоментВремени());Запрос.УстановитьПараметр("Склад", Склад);Запрос.УстановитьПараметр("Ссылка", Ссылка);РезультатЗапроса = Запрос.Выполнить();## Зачем нужна группировка в первой части
Первая часть запроса формирует список товаров текущего документа:
1С (Код)1|ПОМЕСТИТЬ втТЧТоварыГруппировка нужна, чтобы объединить одинаковую номенклатуру, если она указана в табличной части несколько раз.
Например:
| Номенклатура | Количество |
|—|—:|
| Товар 1 | 3 |
| Товар 1 | 5 |После группировки во временной таблице будет:
| Номенклатура | Количество |
|—|—:|
| Товар 1 | 8 |Это важно для правильного контроля остатка. Проверять две строки отдельно было бы неправильно, потому что общий расход составляет 8 единиц.
## Зачем номенклатура отбирается еще и в параметрах виртуальной таблицы
Вы правы в том, что номенклатура уже используется в связи:
1С (Код)12|ПО втТЧТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.НоменклатураНо связь и параметры виртуальной таблицы выполняют разные задачи.
### Связь
Связь определяет, как соединить уже полученные наборы данных:
1С (Код)123|ЛЕВОЕ СОЕДИНЕНИЕ ...|ПО втТЧТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.НоменклатураОна отвечает на вопрос:
> какие строки из результата виртуальной таблицы присоединить к строкам временной таблицы?
### Параметры виртуальной таблицы
Параметры виртуальной таблицы задаются еще при формировании результата регистра:
1С (Код)1234567891011|РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| втТЧТовары.Номенклатура| ИЗ| втТЧТовары КАК втТЧТовары| )| И Склад = &Склад|)Они отвечают на другой вопрос:
> какие данные вообще нужно получить из регистра?
Это особенно важно для виртуальных таблиц регистров накопления. Без параметров виртуальная таблица может сначала сформировать остатки по большому объему данных регистра, а уже потом эти данные будут соединяться с
втТЧТовары.## Что произойдет без параметра
Номенклатура ВЕсли убрать этот отбор и оставить только связь:
1С (Код)123456|ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Склад = &Склад|) КАК ОстаткиНоменклатурыОстатки|ПО втТЧТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.Номенклатуралогически результат, скорее всего, останется правильным. В итог попадут товары документа.
Но виртуальная таблица может быть рассчитана по всем товарам выбранного склада, а затем соединена с несколькими строками документа. Если в регистре сотни тысяч записей, это может ухудшить производительность.
С параметром:
1С (Код)1|Номенклатура В (...)вы сразу передаете виртуальной таблице ограниченный список товаров текущего документа.
В вашем случае запрос должен получить остатки только для:
1С (Код)123товаров текущей расходной накладнойконкретного складанужного момента времени## Почему одного отбора по складу тоже недостаточно
В параметрах виртуальной таблицы у вас два условия:
1С (Код)12|Номенклатура В (...)|И Склад = &СкладОба условия имеют смысл.
Склад = &Складограничивает данные по складу.Номенклатура В (...)ограничивает данные по товарам документа.Если оставить только склад, запрос может получить остатки по всей номенклатуре на этом складе.
Если оставить только номенклатуру, запрос может получить остатки по этой номенклатуре на всех складах.
Для контроля остатков нужны оба измерения, если в регистре есть измерения:
1С (Код)12НоменклатураСклад## Важное замечание по виртуальной таблице
Параметры виртуальной таблицы нужно задавать именно внутри круглых скобок после
.Остатки():1С (Код)12345|РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В (...)| И Склад = &Склад|)А не в обычном
ГДЕвнешнего запроса.Вариант:
1С (Код)12|ГДЕ| ОстаткиНоменклатурыОстатки.Склад = &Складможет дать правильный результат, но для виртуальной таблицы это обычно менее удачный вариант. Фильтр лучше передать в ее параметры, чтобы ограничить получение данных регистра как можно раньше.
## Проверка результата
После выполнения запроса проверку можно сделать так:
1С (Код)12345678910111213141516171819Выборка = РезультатЗапроса.Выбрать();Пока Выборка.Следующий() ЦиклЕсли Выборка.КоличествоОстаток < Выборка.Количество ТогдаОтказ = Истина;Сообщение = Новый СообщениеПользователю;Сообщение.Текст ="Недостаточно товара """+ Выборка.НоменклатураПредставление+ """. Остаток: "+ Выборка.КоличествоОстаток+ ", требуется: "+ Выборка.Количество;Сообщение.Сообщить();КонецЕсли;КонецЦикла;Если нужно показать сообщение непосредственно в строке табличной части, одной временной таблицы с группировкой по номенклатуре будет недостаточно. Нужно дополнительно хранить номера строк табличной части либо отдельно получать строки документа.
## Обратите внимание на момент времени
Строка:
1С (Код)12bslЗапрос.УстановитьПараметр("МоментВремени", МоментВремени());может быть правильной, но зависит от режима проведения и требований билета.
Для оперативного проведения обычно дополнительно используется управляемая блокировка данных перед чтением остатков. Типовая последовательность:
1С (Код)12345671. Начать транзакцию.2. Установить управляемую блокировку.3. Выполнить запрос остатков.4. Проверить остатки.5. При нехватке установить Отказ = Истина.6. При достатке сформировать движения.7. Зафиксировать транзакцию.Если блокировка устанавливается после запроса остатков, два пользователя могут одновременно увидеть один и тот же остаток и оба провести расход.
Также нужно следить, чтобы блокировка устанавливалась по тем же аналитикам, по которым читаются остатки:
1С (Код)12СкладНоменклатураЕсли остатки контролируются еще по характеристике, серии или качеству, эти поля должны участвовать и в:
— измерениях регистра;
— временной таблице;
— параметрах виртуальной таблицы;
— условиях соединения;
— блокировке.В вашем конкретном запросе главная ошибка только одна: в подзапросе нужно заменить обращение к регистру на обращение к временной таблице:
1С (Код)12|ИЗ| втТЧТовары КАК втТЧТоварыИменно это обеспечивает отбор номенклатуры текущего документа, а не всей номенклатуры регистра.
18 октября 2026 в 12:15 в ответ на: Какой % билета занимает контроль остатков и блокировка в 1С? #38861Если речь именно о решении задачи:
— контроль остатков по складу;
— установка управляемой блокировки;
— получение остатков из виртуальной таблицы;
— сравнение остатка с количеством документа;
— формирование движений расхода,то это обычно только часть задачи оперативного учета, а не значимая часть всего билета.
Ориентировочно:
| Уровень оценки | Доля от всего билета |
|—|—:|
| Только блокировка и чтение остатков | 5–10% |
| Контроль остатков с учетом склада и номенклатуры | 10–15% |
| Полностью рабочая задача оперативного учета | 20–30% |
| Весь билет целиком | 100% |Проценты условные, потому что на экзамене оценивается не количество написанных строк, а полнота и правильность реализации требований.
## Что обычно входит в оперативную задачу
Контроль остатков и блокировка являются важной основой, но вокруг них обычно нужно реализовать еще несколько частей:
1. Правильно спроектировать регистр накопления.
2. Определить измерения, ресурсы и реквизиты.
3. Настроить движения документа прихода.
4. Настроить движения документа расхода.
5. Учесть склад, номенклатуру, характеристики, серии или другие аналитики, если они есть в условии.
6. Удалить старые движения перед повторным проведением.
7. Установить блокировку перед чтением остатков.
8. Получить остатки на правильный момент времени.
9. Проверить достаточность остатков.
10. Выдать понятное сообщение об ошибке.
11. Не допустить проведения документа при нехватке товара.
12. Записать корректные движения расхода.
13. Учесть оперативное и неоперативное проведение, если это указано в билете.
14. Проверить перепроведение старых документов.
15. Сформировать отчет, указанный в задании.То есть блокировка сама по себе может занимать несколько строк, но экзаменационная проверка смотрит на всю учетную модель.
## Примерное распределение всего билета
Условно билет можно представить так:
| Блок | Примерная доля |
|—|—:|
| Настройка интерфейса | 5–10% |
| Оперативный учет | 20–25% |
| Бухгалтерский учет | 20–25% |
| Сложные периодические расчеты | 20–25% |
| Бизнес-процессы или управляемые формы | 15–25% |Распределение зависит от конкретного билета и текущей методики проверки. В старых материалах часто встречается структура из пяти частей: интерфейс, оперативный учет, бухгалтерский учет, расчеты и либо бизнес-процесс, либо управляемая форма.
Внутри оперативного учета контроль остатков с блокировкой может занимать примерно половину задачи оперативного учета или немного меньше:
1С (Код)12Оперативный учет целиком: 20–25% билетаКонтроль остатков и блокировка: 5–15% билетаЕсли в условии есть только простое списание товаров со склада, доля может быть ближе к верхней границе. Если есть характеристики, серии, несколько складов, резервирование, себестоимость, возвраты или сложный отчет, доля непосредственно контроля остатков будет меньше.
## Что обязательно освоить после блокировки
Следующий минимальный набор для оперативного учета:
### 1. Проектирование регистра
Нужно уметь по отчету определить:
— какие должны быть измерения;
— какие ресурсы;
— нужен ли регистр остатков или оборотов;
— какие поля участвуют в контроле;
— какие данные должны закрываться в ноль.Например, если остаток контролируется отдельно по складу и номенклатуре:
1С (Код)123456Измерения:СкладНоменклатураРесурсы:Количество### 2. Движения прихода и расхода
Для прихода:
1С (Код)12Вид движения: ПриходКоличество: +КоличествоДокументаДля расхода:
1С (Код)12Вид движения: РасходКоличество: КоличествоДокументаВ 1С вид движения сам определяет знак движения, поэтому в регистр обычно записывают положительное количество.
### 3. Правильный момент получения остатков
Если старые документы могут перепроводиться неоперативно, часто используется параметр момента:
1С (Код)12345МоментВремени = ?(РежимПроведения = РежимПроведенияДокумента.Оперативный,Неопределено,МоментВремени())Но конкретный вариант зависит от условия билета. Нельзя механически вставлять его во все задачи без анализа требований.
### 4. Проверка недостатка
После получения остатков нужно проверить:
1С (Код)1КоличествоОстаток < КоличествоДокументаПри недостатке:
— сформировать сообщение;
— отменить проведение;
— не записать расходные движения.### 5. Группировка строк документа
Если одна и та же номенклатура может встречаться в табличной части несколько раз, остатки нужно сопоставлять не с каждой строкой отдельно, а с суммарным количеством по товару.
Например:
| Номенклатура | Количество |
|—|—:|
| Товар А | 4 |
| Товар А | 3 |Контролировать нужно 7 единиц, а не две независимые строки.
Для этого обычно создают временную таблицу с группировкой по номенклатуре, а иногда и по складу, характеристике или серии.
### 6. Проверка результата отчетом
После проведения нужно проверить:
— остатки до документа;
— остатки после документа;
— склад;
— номенклатуру;
— количество;
— повторное проведение;
— проведение двух документов по одному товару;
— проведение документов по разным товарам;
— недостаток товара.## Важный вывод для подготовки
На текущем этапе вы освоили не «задачу оперативного учета», а один из ключевых механизмов внутри нее. Это хорошее начало, но для сдачи специалиста этого недостаточно даже для одного блока.
Реалистичная оценка:
1С (Код)12345Освоенный сейчас материал:примерно 5–15% всего экзаменационного билетаОперативный учет после полного освоения:примерно 20–25% билетаПри этом блокировка и контроль остатков являются полезной базой, потому что тот же принцип понадобится в большинстве задач по оперативному учету:
1С (Код)12345определить область блокировкизаблокировать данныеполучить актуальные остаткипроверить наличиезаписать движенияНо далее основную сложность обычно дают не сами строки блокировки, а правильное проектирование регистров, момент получения остатков, повторное проведение, группировка номенклатуры и соответствие итоговому отчету.
18 октября 2026 в 0:59 в ответ на: Как эффективно готовиться к экзамену 1С: специалист по методике Ильи Леонтьева? #38859Проблема не в памяти. Вы сейчас в основном узнаёте решение при просмотре, но не тренируете его самостоятельное воспроизведение. Когда видео открыто, всё кажется понятным. Через два дня исчезают подсказки, и выясняется, что алгоритм ещё не закрепился.
Для подготовки к «Специалисту» пересматривать видео по 2–3 раза подряд обычно менее эффективно, чем один раз посмотреть и несколько раз решить задачу с перерывами.
## Сколько видео смотреть в день
Ориентируйтесь не на количество видео, а на время активной работы:
— 1 сложное видео в день, если после него нужно полностью воспроизвести решение;
— 2 коротких видео, если каждое занимает до 20–30 минут и задачи не перегружены;
— максимум 90–120 минут нового материала в день;
— остальное время тратить на решение старых задач.Практичный режим:
— 30–60 минут на новое видео;
— 1,5–3 часа на самостоятельное решение;
— 20–30 минут на повторение ранее изученных задач.Если смотреть по 5–10 видео в день, создаётся ощущение большого прогресса, но через неделю большая часть материала смешается.
При 129 видео нормальный темп обычно составляет примерно:
— 1 видео в день: около 4 месяцев;
— 2 видео в день: около 2 месяцев;
— 3 видео в день: возможно только для коротких и простых роликов, но с обязательной практикой.Для экзамена лучше пройти плейлист за 2,5–3 месяца с нормальным закреплением, чем быстро просмотреть всё и потом начинать заново.
## Как работать с одним видео
Используйте такой алгоритм.
### 1. До просмотра попробуйте понять задачу
Если в видео разбирается экзаменационная задача, сначала прочитайте условие самостоятельно и ответьте письменно:
— какие объекты конфигурации нужны;
— какие регистры должны появиться;
— какие измерения, ресурсы и реквизиты нужны;
— какие движения должен делать документ;
— какой отчёт требуется получить;
— какие данные должны быть в отчёте.Даже если пока не знаете решение, попробуйте сделать проект на бумаге или в конфигураторе.
Для задач оперативного учёта сначала особенно важно проектировать регистр по итоговому отчёту. Для бухгалтерского учёта нужно заранее думать о счетах, субконто и признаках учета. Для расчетов нужно определить виды расчетов, периоды действия, базу и вытеснение.
### 2. Посмотрите видео один раз
Не переписывайте весь текст и весь код. Записывайте только:
— идею решения;
— почему выбраны именно такие объекты;
— структуру регистров;
— ключевые настройки;
— типовые ошибки;
— короткий алгоритм действий.Например, вместо конспекта на 10 страниц:
1С (Код)12345678910111213141516Задача: списание товаров по партиям.1. Регистр остатков:Номенклатура, Склад, Партия.Ресурс: Количество.2. Приход:Записываем положительное количество.3. Расход:Подбираем партии по дате поступления.Списываем последовательно.Остаток по каждой партии не должен стать отрицательным.4. Отчет:Используем виртуальную таблицу Остатки.Такой конспект полезнее, чем копия всех действий преподавателя.
### 3. Сразу закройте видео и повторите решение
Это самый важный этап.
Создайте чистую конфигурацию или копию учебной базы и попробуйте повторить решение без видео. Не включайте ролик после первой ошибки. Сначала 20–30 минут самостоятельно восстановите ход решения.
Если не получается, применяйте подсказки по уровням:
1. посмотреть только свой конспект;
2. посмотреть условие задачи;
3. открыть нужный объект конфигурации;
4. посмотреть небольшой фрагмент видео;
5. закрыть видео и снова продолжить самому.Не пересматривайте каждый раз весь ролик. Иначе мозг опять перейдет в режим узнавания.
### 4. На следующий день решите задачу заново
Не открывайте проект с готовым решением. Возьмите чистую копию и выполните задачу с нуля.
Если через день вы смогли сделать только 50% решения, это нормально. Именно в этот момент происходит запоминание. Нужно не ругать себя за забывание, а использовать его как тренировку.
### 5. Через несколько дней решите задачу без конспекта
Повторяйте задачу по графику:
— в день изучения;
— на следующий день;
— через 3 дня;
— через 7 дней;
— через 14 дней.Не обязательно каждый раз полностью пересоздавать всю конфигурацию. Иногда достаточно:
— восстановить структуру регистра;
— написать движения документа;
— набросать запрос;
— объяснить вслух алгоритм;
— исправить специально добавленную ошибку.## Как вести конспекты
Не пытайтесь конспектировать каждое действие мышкой и каждый оператор. На экзамене проверяется не способность воспроизвести видео, а способность решить новую формулировку.
На каждую задачу удобно иметь одну страницу с такими разделами:
1С (Код)1234567891011121314151. Суть задачи2. Какие объекты создаются3. Структура регистров4. Логика проведения5. Логика отчета6. Особые настройки платформы7. Типовые ошибки8. Что нужно проверитьОтдельно ведите журнал ошибок. Например:
1С (Код)1234567891011Задача: взаиморасчеты с авансами.Ошибка:В регистр не добавил вид движения для погашения аванса.Причина:Смотрел только на документ реализации, не разобрал экономический смысл движений.Как проверить:После проведения вывести остатки по контрагенту и договору.Аванс и задолженность должны закрываться раздельно.Журнал ошибок часто полезнее обычного конспекта. Перед повторным решением просматривайте только свои ошибки.
## Что делать, если через два дня ничего не помните
Не начинайте сразу пересматривать видео. Сначала попробуйте восстановить решение на бумаге.
Например, для задачи по оперативному учёту ответьте:
1. Какой остаток нужно получить?
2. В каком разрезе он хранится?
3. Какой документ увеличивает остаток?
4. Какой документ уменьшает остаток?
5. Что происходит при нехватке остатка?
6. Каким отчетом проверяется результат?Для задачи по регистрам расчета:
1. Какой вид расчета является основным начислением?
2. Какой период действия?
3. От чего зависит расчет?
4. Какие виды расчетов вытесняются?
5. Как выполняется перерасчет?
6. Какие записи должны попасть в регистр?Если не можете ответить, загляните только в нужный пункт конспекта. Такая попытка извлечения информации из памяти закрепляет материал лучше, чем повторный просмотр.
## Пример режима на день
### Вариант на 3 часа
Первые 20 минут
Повторить задачу, которую изучали вчера или три дня назад.
Следующие 40–60 минут
Посмотреть одно новое видео и сделать короткий конспект.
Следующие 60–90 минут
Решить задачу из видео без подсказок.
Последние 20–30 минут
Записать ошибки и устно объяснить алгоритм решения.
### Вариант на 5 часов
1 час
Повторение двух старых задач.
1 час
Новое видео или два коротких видео.
2 часа
Самостоятельное решение и проверка.
1 час
Решение задачи из другого раздела или исправление ошибок.
На подготовке полезно чередовать разделы. Например:
— понедельник: оперативный учет;
— вторник: бухгалтерский учет;
— среда: периодические расчеты;
— четверг: управляемые формы;
— пятница: оперативный и бухгалтерский учет;
— выходной: смешанный билет.Это лучше, чем месяц заниматься только оперативным учетом, а потом обнаружить, что первые задачи уже забылись.
## Обязательно решайте задачи в смешанном порядке
После изучения 5–7 видео не ограничивайтесь задачами строго из последнего ролика. Возьмите случайную старую задачу и попробуйте решить её без подготовки.
На экзамене не будет подсказки, к какому видео относится условие. Важно научиться определять тип задачи самостоятельно:
— это задача на остатки или обороты;
— нужен регистр накопления или регистр бухгалтерии;
— требуется обычное или оперативное проведение;
— это начисление, удержание или перерасчет;
— нужен динамический список, временное хранилище или параметры формы.## Не заучивайте код целиком
Код, переписанный из видео, быстро забывается. Нужно запоминать не конкретные имена переменных, а шаблон решения:
— откуда получаются данные;
— какие таблицы участвуют;
— где устанавливаются отборы;
— как формируется набор записей;
— когда выполняется запись;
— как проверяется результат.Например, по движению регистра нужно понимать:
1. какие данные вводятся пользователем;
2. какие данные нужно получить запросом;
3. какие движения создаются;
4. каким знаком записывается ресурс;
5. как обрабатывается нехватка;
6. что произойдет при перепроведении документа.Если понимаете этот порядок, конкретный код можно восстановить.
## Как проверять, что задача действительно усвоена
Задача считается закрепленной, если вы можете без видео:
— объяснить решение словами;
— нарисовать структуру регистров;
— создать основные объекты;
— написать проведение;
— получить требуемый отчет;
— объяснить, почему решение работает;
— исправить ошибку в готовой реализации;
— немного изменить условие и адаптировать решение.Последний пункт особенно важен. Например, после задачи на списание по партиям измените условие:
— добавьте склад;
— добавьте характеристику;
— измените порядок списания;
— добавьте контроль отрицательных остатков;
— выведите остатки в разрезе договора.Если решение сразу разваливается, значит вы запомнили последовательность действий, но не поняли механизм.
## Рекомендуемая пропорция времени
На этапе просмотра и первичного изучения:
— 25–30% времени, теория и видео;
— 70–75% времени, самостоятельное решение.Ближе к экзамену:
— 10–20% времени, повторение теории;
— 80–90% времени, решение билетов на время.Когда основные темы пройдены, начинайте решать полноценные билеты. Цель, к которой стоит прийти:
— сначала билет за 8–10 часов;
— затем за 6–7 часов;
— перед экзаменом хотя бы несколько билетов в пределах 5 часов.На самом экзамене обычно нет времени долго вспоминать, «с какого видео это было». Алгоритмы типовых операций должны быть доведены до рабочего автоматизма. При этом не стоит игнорировать четвертый блок, управляемые формы и бизнес-процессы. Даже 20–30 минут, потраченные на дополнительную задачу, могут повлиять на результат.
17 октября 2026 в 21:24 в ответ на: Как исправить ошибку «Поле не найдено ‘ВТТовары.Номенклатура'» в запросе 1С? #38857На скриншоте ошибка:
1С (Код)1Поле не найдено "ВТТовары.Номенклатура"Проблема в том, что в текущем выражении конструктор не видит поле
Номенклатурау таблицыВТТовары.Скорее всего, вы вручную указали условие примерно так:
1С (Код)1234567Номенклатура В(ВЫБРАТЬВТТовары.Номенклатура КАК НоменклатураИЗВТТовары КАК ВТТовары)Само такое условие является корректным, но только если временная таблица
ВТТоварыдействительно была создана ранее и содержит полеНоменклатура.## Проверьте первый запрос
В предыдущем запросе временная таблица должна формироваться примерно так:
1С (Код)12345678910|ВЫБРАТЬ| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество|ПОМЕСТИТЬ ВТТовары|ИЗ| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры|ГДЕ| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка|СГРУППИРОВАТЬ ПО| РасходнаяНакладнаяСписокНоменклатуры.НоменклатураЗдесь важно:
1С (Код)1|РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК НоменклатураИменно
КАК Номенклатурасоздает вВТТоварыполе с именемНоменклатура.Если написать, например:
1С (Код)1|РасходнаяНакладнаяСписокНоменклатуры.Номенклатурабез псевдонима, платформа может присвоить полю другое имя, и обращения:
1С (Код)1ВТТовары.Номенклатуране будет существовать.
## Как должно выглядеть условие виртуальной таблицы
Для регистра остатков запрос можно написать так:
1С (Код)12345678910111213141516171819|ВЫБРАТЬ| ВТТовары.Номенклатура КАК Номенклатура,| ВТТовары.Количество КАК Количество,| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток|ИЗ| ВТТовары КАК ВТТовары| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| ВТТовары.Номенклатура| ИЗ| ВТТовары КАК ВТТовары| )| И Склад = &Склад| ) КАК ОстаткиНоменклатурыОстатки| ПО ВТТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.НоменклатураНо для вашей ситуации условие можно упростить. Поскольку основная таблица запроса уже является
ВТТовары, в параметрах виртуальной таблицы обычно достаточно передать поле напрямую:1С (Код)12345678910111213|ВЫБРАТЬ| ВТТовары.Номенклатура КАК Номенклатура,| ВТТовары.Количество КАК Количество,| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток|ИЗ| ВТТовары КАК ВТТовары| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура = ВТТовары.Номенклатура| И Склад = &Склад| ) КАК ОстаткиНоменклатурыОстатки| ПО ВТТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.НоменклатураНо такой вариант с передачей поля из внешнего запроса в параметры виртуальной таблицы поддерживается не во всех ситуациях и может быть неудобен в конструкторе. Поэтому надежнее использовать подзапрос с
ВТТовары.## Почему ошибка появляется в конструкторе
На скриншоте вы находитесь в окне «Произвольное выражение» конструктора запроса. Конструктор пытается проверить выражение:
1С (Код)1ВТТовары.НоменклатураНо в контексте этого окна временная таблица или ее поле не распознаны.
Возможны три основные причины.
### 1. Временная таблица не содержит такого поля
Проверьте запрос, где создается
ВТТовары.Должно быть:
1С (Код)1|Документ.РасходнаяНакладная.СписокНоменклатуры.Номенклатура КАК НоменклатураА не, например:
1С (Код)1|Документ.РасходнаяНакладная.СписокНоменклатуры.Номенклатура КАК ТоварЕсли указано:
1С (Код)1|...Номенклатура КАК Товарто обращаться нужно так:
1С (Код)1ВТТовары.ТоварЛибо переименовать поле в первом запросе:
1С (Код)1|...Номенклатура КАК Номенклатура### 2. Временная таблица создается не в этом пакете запросов
Временная таблица существует только в рамках одного выполнения пакетного запроса.
Правильно:
1С (Код)1234567891011|ВЫБРАТЬ| ...|ПОМЕСТИТЬ ВТТовары|ИЗ| ...|;||ВЫБРАТЬ| ВТТовары.Номенклатура|ИЗ| ВТТовары КАК ВТТоварыНеправильно:
1С (Код)1Запрос1.Выполнить();А затем в другом объекте:
1С (Код)1Запрос2.Выполнить();В таком случае
ВТТоварыиз первого запроса во втором уже не существует.### 3. Ошибка в имени таблицы
Проверьте точное имя временной таблицы. Например, это разные имена:
1С (Код)1234ВТТоварыВТТТоварыВТТоварВТТоварыДокументаВ запросе имя должно совпадать полностью:
1С (Код)1|ПОМЕСТИТЬ ВТТоварыи:
1С (Код)12|ИЗ| ВТТовары КАК ВТТовары## Что лучше сделать сейчас
В конструкторе удалите произвольное выражение с ошибкой и заново задайте отбор виртуальной таблицы.
Если конструктор продолжает ругаться, сформируйте запрос вручную. В вашем случае используйте такую структуру:
1С (Код)12345678910111213141516171819202122232425262728293031|ВЫБРАТЬ| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура КАК Номенклатура,| СУММА(РасходнаяНакладнаяСписокНоменклатуры.Количество) КАК Количество|ПОМЕСТИТЬ ВТТовары|ИЗ| Документ.РасходнаяНакладная.СписокНоменклатуры КАК РасходнаяНакладнаяСписокНоменклатуры|ГДЕ| РасходнаяНакладнаяСписокНоменклатуры.Ссылка = &Ссылка|СГРУППИРОВАТЬ ПО| РасходнаяНакладнаяСписокНоменклатуры.Номенклатура|;||ВЫБРАТЬ| ВТТовары.Номенклатура КАК Номенклатура,| ВТТовары.Количество КАК Количество,| ЕСТЬNULL(ОстаткиНоменклатурыОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток|ИЗ| ВТТовары КАК ВТТовары| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиНоменклатуры.Остатки(| &МоментВремени,| Номенклатура В| (| ВЫБРАТЬ| ВТТовары.Номенклатура| ИЗ| ВТТовары КАК ВТТовары| )| И Склад = &Склад| ) КАК ОстаткиНоменклатурыОстатки| ПО ВТТовары.Номенклатура =| ОстаткиНоменклатурыОстатки.НоменклатураГлавное здесь:
1. В
ПОМЕСТИТЬ ВТТоварыполе явно названоНоменклатура.
2. Временная таблица создается до второго запроса.
3. Оба запроса находятся в одном пакете.
4. В подзапросе используется именноВТТовары.Номенклатура.
5. ИмяВТТоварывезде написано одинаково.Если в вашей временной таблице поле называется не
Номенклатура, а, например,Товар, тогда нужно заменить обращения:1С (Код)1ВТТовары.Номенклатурана:
1С (Код)1ВТТовары.ТоварПри этом в параметре виртуальной таблицы все равно должно использоваться измерение регистра:
1С (Код)1234567Номенклатура В(ВЫБРАТЬВТТовары.ТоварИЗВТТовары КАК ВТТовары)То есть слева указывается поле регистра, справа поле временной таблицы.
17 октября 2026 в 17:28 в ответ на: Как работают строки кода с управляемой блокировкой данных? #38855Эти строки устанавливают управляемую транзакционную блокировку остатков по нужному складу и товарам. Разберем последовательно.
1С (Код)1Блокировка = Новый БлокировкаДанных;Создается объект, который будет содержать описание одной или нескольких блокировок.
Сам по себе этот оператор ничего не блокирует. Он только создает коллекцию, в которую дальше добавляется область блокировки.
Обычно в одной блокировке можно описать несколько областей, например:
1С (Код)123456789Блокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ДругойЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.СерииТоваров");В вашем случае нужна только одна область, поэтому создается один элемент блокировки.
—
1С (Код)123ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");В объект блокировки добавляется область, соответствующая регистру накопления
ОстаткиНоменклатуры.После выполнения этой строки платформа понимает:
> Блокировка будет установлена на данные регистра накопления
ОстаткиНоменклатуры.Переменная
ЭлементБлокировкипредставляет описание блокировки именно этого регистра.Важно, что строка должна соответствовать имени регистра в конфигураторе:
1С (Код)1"РегистрНакопления.ОстаткиНоменклатуры"Если регистр называется, например,
ТоварныеОстатки, тогда нужно указать:1С (Код)1"РегистрНакопления.ТоварныеОстатки"На этом этапе пока еще не определено:
— какая блокировка устанавливается;
— на какой склад;
— по каким товарам;
— когда она будет установлена.Пока только указано пространство, в котором будет действовать блокировка.
—
1С (Код)12ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;Задается режим блокировки.
Исключительныйозначает, что указанные данные будут заняты текущей транзакцией. Другая управляемая транзакция не сможет получить совместимую блокировку на эти же данные до завершения текущей транзакции.Практически для проведения расходной накладной это означает:
1С (Код)12345678910Текущая транзакция:1. Заблокировала остатки.2. Прочитала остатки.3. Проверила наличие товара.4. Сформировала расход.5. Завершила проведение.Другая транзакция:не сможет одновременно изменить или использовать эти же заблокированные данныедо освобождения блокировки.Это нужно для защиты от ситуации, когда два пользователя одновременно проводят расход одного и того же товара.
Например, на складе есть 10 единиц товара.
Два пользователя одновременно проводят документы:
1С (Код)12Документ 1: расход 7 единицДокумент 2: расход 6 единицБез блокировки может произойти следующая последовательность:
1С (Код)12345Документ 1 прочитал остаток: 10Документ 2 прочитал остаток: 10Документ 1 решил, что 7 единиц хватаетДокумент 2 решил, что 6 единиц хватаетОба документа записали расходВ итоге будет списано 13 единиц при фактическом остатке 10.
При использовании исключительной блокировки одна транзакция блокирует остаток. Вторая транзакция ждет завершения первой, после чего читает уже актуальный остаток.
Почему используется именно исключительный режим:
— документ не только читает остатки;
— документ формирует движения расхода;
— нужно исключить параллельное проведение по тем же товарам;
— проверка остатка и запись расхода должны выполняться согласованно.Для простого чтения данных иногда применяется разделяемая блокировка:
1С (Код)1РежимБлокировкиДанных.РазделяемыйНо для проведения документа расхода обычно применяют исключительную блокировку.
—
1С (Код)1ЭлементБлокировки.УстановитьЗначение("Склад", Склад);Эта строка сужает область блокировки до конкретного склада.
Без нее блокировка могла бы относиться ко всему регистру
ОстаткиНоменклатуры.После установки значения:
1С (Код)1ЭлементБлокировки.УстановитьЗначение("Склад", Склад);платформа блокирует данные, у которых измерение
Складравно значению переменнойСклад.Например, если в документе выбран склад
Основной склад, то логика будет такой:1С (Код)12Блокировать не весь регистр,а остатки только по складу "Основной склад".Если в регистре есть измерения:
1С (Код)12СкладНоменклатурато пока задан только склад, область выглядит примерно так:
1С (Код)12Склад = Основной складНоменклатура = любаяТо есть блокировка пока распространяется на все товары выбранного склада. Следующие строки дополнительно сузят ее по номенклатуре.
Название
"Склад"должно точно совпадать с именем измерения регистра накопления. Если измерение называетсяСкладОрганизация, нужно писать:1С (Код)1234ЭлементБлокировки.УстановитьЗначение("СкладОрганизация",СкладОрганизация);Значение
Складобычно является ссылкой на элемент справочникаСклады.—
1С (Код)1ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;Указывается источник данных, из которого будут взяты значения для ограничения блокировки.
В вашем случае
СписокНоменклатурывероятнее всего является табличной частью документа.Например, табличная часть содержит строки:
| Номенклатура | Количество |
|—|—:|
| Товар А | 5 |
| Товар Б | 3 |
| Товар В | 7 |После установки:
1С (Код)1ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;платформа получает возможность использовать строки этой табличной части для формирования области блокировки.
Но одной этой строки недостаточно. Платформе еще нужно объяснить, какое поле источника соответствует какому измерению регистра. Для этого используется следующая строка:
1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Вместе эти две строки означают:
1С (Код)12Возьми значения номенклатуры из табличной частии используй их для ограничения измерения Номенклатура регистра.Источник данных позволяет заблокировать только товары, которые есть в документе, а не всю номенклатуру склада.
—
1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Здесь задается соответствие между полем регистра и полем источника данных.
Первый параметр:
1С (Код)1"Номенклатура"это поле пространства блокировки, то есть измерение регистра накопления.
Второй параметр:
1С (Код)1"Номенклатура"это поле источника данных, то есть колонка в табличной части
СписокНоменклатуры.Получается соответствие:
1С (Код)12Измерение регистра Поле табличной частиНоменклатура НоменклатураЕсли в табличной части есть товары:
1С (Код)123Товар АТовар БТовар Вто блокировка будет установлена примерно на такие комбинации:
1С (Код)123Склад = выбранный склад, Номенклатура = Товар АСклад = выбранный склад, Номенклатура = Товар БСклад = выбранный склад, Номенклатура = Товар ВОстальные товары на этом складе блокироваться не будут.
Именно поэтому источник данных здесь предпочтительнее, чем блокировка всего регистра или всего склада.
### Если не использовать источник данных
Можно было бы заблокировать весь выбранный склад:
1С (Код)1ЭлементБлокировки.УстановитьЗначение("Склад", Склад);Но тогда блокировка затронула бы все товары этого склада:
1С (Код)1Склад = Основной склад, Номенклатура = любаяЭто избыточно. Два пользователя не смогут одновременно проводить документы даже по разным товарам одного склада.
Например:
1С (Код)12Документ 1 проводит Товар АДокумент 2 проводит Товар БПри блокировке всего склада второй документ будет ждать, хотя товары между собой не пересекаются.
При использовании источника данных блокируются только реально используемые товары.
—
1С (Код)1Блокировка.Заблокировать();Это команда фактической установки блокировки.
До этой строки объект
Блокировкатолько содержит описание:1С (Код)1234Какой регистр блокироватьВ каком режимеКакой складКакие товарыИменно вызов:
1С (Код)1Блокировка.Заблокировать();передает это описание платформе и пытается получить блокировку.
Если нужные данные свободны, блокировка устанавливается сразу.
Если другая транзакция уже удерживает конфликтующую блокировку, выполнение может ожидать ее завершения. После освобождения данных текущая транзакция получит блокировку и продолжит работу.
Блокировка действует до окончания текущей транзакции:
— до успешной фиксации транзакции;
— либо до отмены транзакции при ошибке;
— либо до отката проведения.Она не является постоянной блокировкой данных и не записывается в регистр как отдельная информация.
## Что именно блокируется в вашем коде
Если:
1С (Код)1Склад = Основнойа в табличной части есть:
1С (Код)12Товар АТовар Бто логически блокируются следующие области:
1С (Код)1234567РегистрНакопления.ОстаткиНоменклатурыСклад = ОсновнойНоменклатура = Товар АРегистрНакопления.ОстаткиНоменклатурыСклад = ОсновнойНоменклатура = Товар БДругой склад не блокируется:
1С (Код)1Склад = МагазинДругой товар тоже не блокируется:
1С (Код)12Склад = ОсновнойНоменклатура = Товар ВЕсли другой документ работает с
Товаром В, он, как правило, не будет ждать блокировку документа поТовару А.## Почему блокировку устанавливают до запроса остатков
Правильная последовательность для документа расхода:
1С (Код)1234567891011121314151617181920// Удалить старые движения документаДвижения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();// Установить блокировкуБлокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.Режим =РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.УстановитьЗначение("Склад", Склад);ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();// Только после блокировки читать остаткиПочему нельзя сначала прочитать остаток, а потом установить блокировку:
1С (Код)12341. Прочитали остаток 10.2. Другой пользователь списал 8.3. Установили блокировку.4. Первый документ списал еще 7.В таком случае проверка выполнялась по устаревшим данным.
Блокировку нужно получать до чтения остатков, чтобы между проверкой и формированием движения другой документ не изменил эти же остатки.
## Важное условие для работы блокировки
Регистр накопления, документ и транзакция должны работать в управляемом режиме блокировок.
Если объект находится в автоматическом режиме, а код вручную устанавливает управляемую блокировку, может возникнуть ошибка вида:
1С (Код)1Автоматический режим блокировки недопустим в этой транзакцииВ конфигураторе нужно проверить свойство:
1С (Код)1Режим управления блокировкой данныхДля документа, его регистров и используемых объектов должен быть выбран управляемый режим, если конфигурация использует явные управляемые блокировки.
Кроме того, имена должны совпадать с метаданными:
1С (Код)1"Склад"должно быть измерением регистра, а:
1С (Код)1"Номенклатура"должно быть одновременно:
— измерением регистра
ОстаткиНоменклатуры;
— колонкой табличной частиСписокНоменклатуры.Если в регистре измерение называется
Товар, а в табличной части поле называетсяНоменклатура, код должен выглядеть так:1С (Код)1234ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Товар","Номенклатура");То есть первый параметр относится к регистру, второй к источнику данных.
17 октября 2026 в 16:48 в ответ на: Почему дважды устанавливается признак Записывать в ОбработкаПроведения? #38853Здесь движения записываются не два раза. Фактически метод записи вызывается только один раз:
1С (Код)1234Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();Движения.ОстаткиНоменклатуры.Записывать = Истина;Первая и третья строки только устанавливают признак
Записывать.## Что делает
Движения.Записать()Движенияпредставляет собой коллекцию наборов записей по регистрам, которые связаны с текущим документом.Строка:
1С (Код)1Движения.Записать();записывает в регистры все наборы движений, у которых установлено:
1С (Код)1Движения.ОстаткиНоменклатуры.Записывать = Истина;В данном случае в регистр накопления
ОстаткиНоменклатурызаписывается текущее состояние набора движений документа.Если набор движений на этот момент пустой, то старые движения документа по этому регистру удаляются.
Именно это здесь и используется:
1С (Код)12Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();Перед началом проведения удаляются старые движения текущего документа.
## Зачем удалять старые движения перед проверкой остатков
Рассмотрим ситуацию.
Документ был проведен ранее:
| Документ | Номенклатура | Движение |
|—|—|—:|
| Расходная накладная №1 | Товар А | Расход 10 |Затем пользователь изменил документ, например:
1С (Код)12Было: Товар А, количество 10Стало: Товар А, количество 15При повторном проведении нужно проверить наличие 15 единиц, а не учитывать старый расход 10 единиц как уже существующее движение этого же документа.
Если старое движение документа не удалить перед выполнением запроса остатков, запрос может увидеть остаток с учетом старого расхода текущего документа. В результате получится примерно такая логика:
1С (Код)1234Реальный остаток до проведения: 100Старый расход этого документа: 10Запрос видит остаток: 90Новое количество документа: 15Хотя фактически доступно 100 единиц до проведения текущего документа, проверка будет выполняться против 90.
Поэтому старые движения текущего документа сначала очищаются, затем проверяется остаток, после чего формируются новые движения.
Последовательность такая:
1С (Код)1234561. Удалить старые движения текущего документа.2. Заблокировать остатки.3. Прочитать актуальные остатки.4. Проверить наличие товара.5. Сформировать новые движения.6. Платформа запишет сформированные движения при завершении проведения.## Почему после
Движения.Записать()снова устанавливаетсяЗаписывать = ИстинаПосле ручной записи движений набор записей фактически был записан и очищен от старого состояния. Повторная установка:
1С (Код)1Движения.ОстаткиНоменклатуры.Записывать = Истина;означает:
> Теперь новые движения, которые будут добавлены в этот набор, также нужно записать при завершении проведения.
Дальше в цикле добавляется новое движение:
1С (Код)123456Движение = Движения.ОстаткиНоменклатуры.Добавить();Движение.ВидДвижения = ВидДвиженияНакопления.Расход;Движение.Период = Дата;Движение.Номенклатура = Выборка.Номенклатура;Движение.Склад = Склад;Движение.Количество = Выборка.Количество;Так как
Записыватьснова установлено вИстина, платформа запишет эти движения после успешного проведения документа.То есть это не вторая запись в регистр, а повторная установка режима записи набора движений.
## Что происходит при перепроведении документа
При перепроведении платформа работает примерно по такой схеме:
1С (Код)12345678910111213Старые движения документа уже существуют.↓ОбработкаПроведения↓Движения.Записать()↓Старые движения текущего документа удаляются.↓Выполняется проверка остатков.↓Добавляются новые движения.↓Если Отказ = Ложь, новые движения записываются.Если во время проведения установить:
1С (Код)1Отказ = Истина;то новые движения не должны остаться в регистре. В зависимости от режима проведения и особенностей конфигурации платформа откатывает транзакцию. Поэтому при ошибке нехватки товара документ не проводится.
## Важный момент по вашему коду
Фрагмент:
1С (Код)1234Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();Движения.ОстаткиНоменклатуры.Записывать = Истина;логически означает:
1С (Код)123456789// Включаем запись регистраДвижения.ОстаткиНоменклатуры.Записывать = Истина;// Удаляем старые движения текущего документаДвижения.Записать();// Снова включаем запись регистра,// чтобы новые движения были записаны после проведенияДвижения.ОстаткиНоменклатуры.Записывать = Истина;Однако в таком виде код выглядит неочевидно. Его лучше снабдить комментариями:
1С (Код)12345678// Перед проверкой остатков удаляем старые движения документа,// чтобы они не повлияли на расчет доступного остатка.Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Записать();// Включаем запись набора для новых движений,// которые будут сформированы ниже.Движения.ОстаткиНоменклатуры.Записывать = Истина;## Можно ли не вызывать
Движения.Записать()в началеВ данном алгоритме нежелательно.
Если убрать:
1С (Код)1Движения.Записать();то старые движения текущего документа могут остаться в регистре на момент выполнения запроса:
1С (Код)1РегистрНакопления.ОстаткиНоменклатуры.Остатки(...)Из-за этого остаток может быть рассчитан неправильно при повторном проведении или изменении документа.
Особенно это важно для документов расхода, которые проверяют наличие товара.
## Более современный и безопасный вариант
Вместо чтения табличной части документа напрямую можно передавать в блокировку временную таблицу или использовать источник данных с теми же товарами, которые участвуют в запросе. Но общая логика остается прежней:
1С (Код)1234567891011121314151617181920212223Движения.ОстаткиНоменклатуры.Записывать = Истина;// Удаляем движения текущего документаДвижения.Записать();// Повторно включаем запись для новых движенийДвижения.ОстаткиНоменклатуры.Записывать = Истина;// Блокируем остаткиБлокировка = Новый БлокировкаДанных;ЭлементБлокировки = Блокировка.Добавить("РегистрНакопления.ОстаткиНоменклатуры");ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;ЭлементБлокировки.УстановитьЗначение("Склад", Склад);ЭлементБлокировки.ИсточникДанных = СписокНоменклатуры;ЭлементБлокировки.ИспользоватьИзИсточникаДанных("Номенклатура","Номенклатура");Блокировка.Заблокировать();// Проверяем остатки и формируем новые движения## Еще один нюанс:
Движения.Записать()записывает не обязательно все регистрыВызов:
1С (Код)1Движения.Записать();обрабатывает наборы движений, для которых включен признак:
1С (Код)1Движения.ИмяРегистра.Записывать = Истина;Например:
1С (Код)12Движения.ОстаткиНоменклатуры.Записывать = Истина;Движения.Продажи.Записывать = Ложь;В таком случае вызов
Движения.Записать()затронетОстаткиНоменклатуры, но не будет записывать движения регистраПродажи.В вашем коде повторная строка:
1С (Код)1Движения.ОстаткиНоменклатуры.Записывать = Истина;нужна не для повторной записи, а для того, чтобы после очистки старых движений платформа записала новые движения, добавленные ниже.
-
АвторЗаписи