diff --git a/CHANGELOG.md b/CHANGELOG.md
index f9ad581..3871e17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,27 @@
---
+## 1.3.1.57 (2026-08-12)
+
+### РК_ЗагрузкаОстатков — понятная ошибка при Активно = Ложь
+
+- Текст исключения в `РК_ОбменСВнешнейБазой.НастройкиПодключения`: что включить «Активно» и что проверка health работает без флажка.
+- Команды формы (подбор складов, загрузка, сопоставление, создание документов) показывают предупреждение вместо стека исключения.
+
+---
+
+## 1.3.1.56 (2026-08-12)
+
+### РК_ЗагрузкаОстатков — создание документов ввода остатков
+
+- Реквизиты: `Организация`, `ПерезаписатьДокументы`.
+- ТЧ: `ДокументВвода`, `ЗагруженоВДокумент`.
+- Команда «Создать документы»: `ВводОстатковТоваров` (1 документ на склад, операция «собственные товары»),
+ только количество (без себестоимости — данных в API пока нет).
+- Тег комментария: `РК_ПереносОстатков yyyyMMdd`; опционально удаление непроведённых документов волны.
+
+---
+
## 1.3.1.55 (2026-08-11)
### Добавлено
diff --git a/VERSION b/VERSION
index f228051..09b0584 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.3.1.55
+1.3.1.57
diff --git a/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl b/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl
index b64749c..20c0dc2 100644
--- a/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl
+++ b/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl
@@ -2,6 +2,8 @@
#Область ПрограммныйИнтерфейс
// Настройки подключения из элемента справочника РК_НастройкиПодключенияКВнешнейБазе.
+// Для рабочих вызовов (остатки, склады) требуется «Активно = Истина».
+// Проверка «Проверить» в карточке справочника намеренно не смотрит на этот флажок.
//
Функция НастройкиПодключения(Подключение) Экспорт
@@ -12,8 +14,10 @@
Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Подключение,
"АдресПодключения, Токен, Таймаут, Логин, Пароль, Активно, ИмяТекущейБазы");
- Если Реквизиты.Активно = Ложь Тогда
- ВызватьИсключение "Подключение к сторонней базе отключено (Активно = Ложь)";
+ Если Реквизиты.Активно <> Истина Тогда
+ ВызватьИсключение НСтр("ru = 'Подключение к сторонней базе отключено.'")
+ + Символы.ПС + НСтр("ru = 'Откройте карточку настройки, включите флажок «Активно» и запишите элемент.'")
+ + Символы.ПС + НСтр("ru = 'Проверка соединения («Проверить») работает и без этого флажка.'");
КонецЕсли;
Адрес = СокрЛП(Строка(Реквизиты.АдресПодключения));
diff --git a/src/Configuration.xml b/src/Configuration.xml
index b83e83c..718181c 100644
--- a/src/Configuration.xml
+++ b/src/Configuration.xml
@@ -62,7 +62,7 @@
Role.РК_ОсновнаяРоль
- 1.3.1.55
+ 1.3.1.57
Language.Русский
diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков.xml b/src/DataProcessors/РК_ЗагрузкаОстатков.xml
index ed4ef0c..9af24a4 100644
--- a/src/DataProcessors/РК_ЗагрузкаОстатков.xml
+++ b/src/DataProcessors/РК_ЗагрузкаОстатков.xml
@@ -136,6 +136,74 @@
Auto
+
+
+ Организация
+
+
+ ru
+ Организация
+
+
+
+
+ cfg:CatalogRef.Организации
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ ShowError
+ Items
+
+
+ Auto
+ Auto
+
+
+ Auto
+
+
+
+
+ ПерезаписатьДокументы
+
+
+ ru
+ Перезаписать документы
+
+
+ Удалить непроведённые документы волны перед созданием
+
+ xs:boolean
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ DontCheck
+ Items
+
+
+ Auto
+ Auto
+
+
+ Auto
+
+
@@ -1307,6 +1375,78 @@
Auto
+
+
+ ДокументВвода
+
+
+ ru
+ Документ ввода
+
+
+
+
+ cfg:DocumentRef.ВводОстатковТоваров
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ false
+
+ DontCheck
+ Items
+
+
+ Auto
+ Auto
+
+
+ Auto
+
+
+
+
+ ЗагруженоВДокумент
+
+
+ ru
+ Загружено в документ
+
+
+
+
+ xs:boolean
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ false
+ false
+ DontCheck
+ Items
+
+
+ Auto
+ Auto
+
+
+ Auto
+
+
diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl b/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl
index 376efa0..b24c5eb 100644
--- a/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl
+++ b/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl
@@ -113,10 +113,236 @@
КонецФункции
+// Создание документов ВводОстатковТоваров по сопоставленным строкам (1 документ на склад).
+// Себестоимость не заполняется (нет данных в API) — только оперативный учёт количества.
+//
+// Параметры:
+// РежимТест - Булево - только подсчёт без записи
+//
+// Возвращаемое значение:
+// Структура - СозданоДокументов, УдаленоДокументов, СтрокВДокументах, Пропущено, Ошибок, ТекстТега
+//
+Функция СоздатьДокументыВводаОстатков(РежимТест = Истина) Экспорт
+
+ Результат = Новый Структура;
+ Результат.Вставить("СозданоДокументов", 0);
+ Результат.Вставить("УдаленоДокументов", 0);
+ Результат.Вставить("СтрокВДокументах", 0);
+ Результат.Вставить("Пропущено", 0);
+ Результат.Вставить("Ошибок", 0);
+ Результат.Вставить("ТекстТега", "");
+
+ Если Не ЗначениеЗаполнено(Организация) Тогда
+ ВызватьИсключение "Укажите организацию для документов ввода остатков";
+ КонецЕсли;
+ Если Не ЗначениеЗаполнено(ДатаДокументовВвода) Тогда
+ ВызватьИсключение "Укажите дату документов ввода";
+ КонецЕсли;
+
+ ТекстТега = ТегКомментарияДокументов();
+ Результат.ТекстТега = ТекстТега;
+
+ СтрокиПоСкладу = СгруппироватьСопоставленныеСтрокиПоСкладу();
+ Если СтрокиПоСкладу.Количество() = 0 Тогда
+ Возврат Результат;
+ КонецЕсли;
+
+ Если ПерезаписатьДокументы И Не РежимТест Тогда
+ Результат.УдаленоДокументов = УдалитьПрежниеДокументыВолны(ТекстТега);
+ КонецЕсли;
+
+ Для Каждого ЭлементСклада Из СтрокиПоСкладу Цикл
+
+ СкладДок = ЭлементСклада.Ключ;
+ СтрокиСклада = ЭлементСклада.Значение;
+ Если СтрокиСклада.Количество() = 0 Тогда
+ Продолжить;
+ КонецЕсли;
+
+ Попытка
+ Если РежимТест Тогда
+ Результат.СозданоДокументов = Результат.СозданоДокументов + 1;
+ Результат.СтрокВДокументах = Результат.СтрокВДокументах + СтрокиСклада.Количество();
+ Продолжить;
+ КонецЕсли;
+
+ Док = СоздатьДокументПоСкладу(СкладДок, СтрокиСклада, ТекстТега);
+ Если ЗначениеЗаполнено(Док) Тогда
+ Результат.СозданоДокументов = Результат.СозданоДокументов + 1;
+ Результат.СтрокВДокументах = Результат.СтрокВДокументах + Док.Товары.Количество();
+ Для Каждого СтрТ Из СтрокиСклада Цикл
+ СтрТ.ДокументВвода = Док.Ссылка;
+ СтрТ.ЗагруженоВДокумент = Истина;
+ КонецЦикла;
+ КонецЕсли;
+ Исключение
+ Результат.Ошибок = Результат.Ошибок + 1;
+ КонецПопытки;
+
+ КонецЦикла;
+
+ Возврат Результат;
+
+КонецФункции
+
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
+Функция ТегКомментарияДокументов()
+
+ Суффикс = Формат(ДатаДокументовВвода, "ДФ=yyyyMMdd");
+ Если ПустаяСтрока(Суффикс) Тогда
+ Суффикс = Формат(ДатаОстатков, "ДФ=yyyyMMdd");
+ КонецЕсли;
+ Возврат "РК_ПереносОстатков " + Суффикс;
+
+КонецФункции
+
+Функция СгруппироватьСопоставленныеСтрокиПоСкладу()
+
+ Группы = Новый Соответствие;
+ Для Каждого СтрТ Из ВходящиеДанные Цикл
+ Если Не СтрТ.Сопоставлено Тогда
+ Продолжить;
+ КонецЕсли;
+ Если Не ЗначениеЗаполнено(СтрТ.Склад) Или Не ЗначениеЗаполнено(СтрТ.Номенклатура) Тогда
+ Продолжить;
+ КонецЕсли;
+ Если СтрТ.Количество <= 0 Тогда
+ Продолжить;
+ КонецЕсли;
+ КлючСклада = Строка(СтрТ.Склад.УникальныйИдентификатор());
+ СтрокиСклада = Группы.Получить(КлючСклада);
+ Если СтрокиСклада = Неопределено Тогда
+ СтрокиСклада = Новый Массив;
+ Группы.Вставить(КлючСклада, СтрокиСклада);
+ КонецЕсли;
+ СтрокиСклада.Добавить(СтрТ);
+ КонецЦикла;
+
+ // Переключить ключи на ссылки складов для удобства обхода.
+ Результат = Новый Соответствие;
+ Для Каждого СтрТ Из ВходящиеДанные Цикл
+ Если Не СтрТ.Сопоставлено Или Не ЗначениеЗаполнено(СтрТ.Склад) Тогда
+ Продолжить;
+ КонецЕсли;
+ КлючСклада = Строка(СтрТ.Склад.УникальныйИдентификатор());
+ СтрокиСклада = Группы.Получить(КлючСклада);
+ Если СтрокиСклада <> Неопределено И Результат.Получить(СтрТ.Склад) = Неопределено Тогда
+ Результат.Вставить(СтрТ.Склад, СтрокиСклада);
+ КонецЕсли;
+ КонецЦикла;
+ Возврат Результат;
+
+КонецФункции
+
+Функция УдалитьПрежниеДокументыВолны(ТекстТега)
+
+ Удалено = 0;
+ Запрос = Новый Запрос;
+ Запрос.Текст =
+ "ВЫБРАТЬ
+ | Ввод.Ссылка КАК Ссылка
+ |ИЗ
+ | Документ.ВводОстатковТоваров КАК Ввод
+ |ГДЕ
+ | НЕ Ввод.ПометкаУдаления
+ | И НЕ Ввод.Проведен
+ | И Ввод.Организация = &Организация
+ | И Ввод.Комментарий ПОДОБНО &Тег
+ | И Ввод.ХозяйственнаяОперация = ЗНАЧЕНИЕ(Перечисление.ХозяйственныеОперации.ВводОстатковСобственныхТоваров)";
+ Запрос.УстановитьПараметр("Организация", Организация);
+ Запрос.УстановитьПараметр("Тег", "%" + ТекстТега + "%");
+
+ Выборка = Запрос.Выполнить().Выбрать();
+ Пока Выборка.Следующий() Цикл
+ Попытка
+ ДокОб = Выборка.Ссылка.ПолучитьОбъект();
+ ДокОб.Удалить();
+ Удалено = Удалено + 1;
+ Исключение
+ КонецПопытки;
+ КонецЦикла;
+ Возврат Удалено;
+
+КонецФункции
+
+Функция СоздатьДокументПоСкладу(СкладДок, СтрокиСклада, ТекстТега)
+
+ Док = Документы.ВводОстатковТоваров.СоздатьДокумент();
+ Док.Дата = ДатаДокументовВвода;
+ Док.Организация = Организация;
+ Док.Склад = СкладДок;
+ Док.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ВводОстатковСобственныхТоваров;
+ Док.Комментарий = ТекстТега + ", склад " + СокрЛП(Строка(СкладДок));
+ Док.ОтражатьВОперативномУчете = Истина;
+ Док.ОтражатьСебестоимость = Ложь;
+ Док.ЦенаВключаетНДС = Ложь;
+
+ Попытка
+ Док.Подразделение = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СкладДок, "Подразделение");
+ Исключение
+ КонецПопытки;
+
+ Попытка
+ Док.Валюта = ЗначениеНастроекПовтИсп.ВалютаРегламентированногоУчетаОрганизации(Организация);
+ Исключение
+ Док.Валюта = Константы.ВалютаРегламентированногоУчета.Получить();
+ КонецПопытки;
+
+ Если Не ЗначениеЗаполнено(Док.НалогообложениеНДС) Тогда
+ Док.НалогообложениеНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаОблагаетсяНДС;
+ КонецЕсли;
+ Попытка
+ ПараметрыНДС = Документы.ВводОстатковТоваров.ИнициализироватьПараметрыВидовДеятельностиНДС(Док);
+ УчетНДСУП.ЗаполнитьВидДеятельностиНДС(Док.ВидДеятельностиНДС, ПараметрыНДС);
+ Исключение
+ КонецПопытки;
+
+ Для Каждого СтрТ Из СтрокиСклада Цикл
+ НовСтр = Док.Товары.Добавить();
+ НовСтр.Номенклатура = СтрТ.Номенклатура;
+ НовСтр.Характеристика = СтрТ.Характеристика;
+ НовСтр.Серия = СтрТ.СерияСсылка;
+ НовСтр.Количество = СтрТ.Количество;
+ НовСтр.КоличествоУпаковок = СтрТ.Количество;
+ НовСтр.Цена = 0;
+ НовСтр.Сумма = 0;
+ Попытка
+ НовСтр.СтавкаНДС = СтрТ.Номенклатура.СтавкаНДС;
+ Исключение
+ КонецПопытки;
+ Если ЗначениеЗаполнено(СтрТ.НомерГТДСсылка) Тогда
+ НовСтр.НомерГТД = СтрТ.НомерГТДСсылка;
+ КонецЕсли;
+ Если ЗначениеЗаполнено(СтрТ.СерияСсылка) Тогда
+ СтрСер = Док.Серии.Добавить();
+ СтрСер.Номенклатура = НовСтр.Номенклатура;
+ СтрСер.Характеристика = НовСтр.Характеристика;
+ СтрСер.Серия = СтрТ.СерияСсылка;
+ СтрСер.Количество = НовСтр.Количество;
+ СтрСер.КоличествоУпаковок = НовСтр.Количество;
+ КонецЕсли;
+ КонецЦикла;
+
+ Если Док.Товары.Количество() = 0 Тогда
+ Возврат Документы.ВводОстатковТоваров.ПустаяСсылка();
+ КонецЕсли;
+
+ ОбщегоНазначенияУТ.ЗаполнитьИдентификаторыДокумента(Док, "Товары");
+ Попытка
+ ПараметрыУказанияСерий = НоменклатураСервер.ПараметрыУказанияСерий(Док, Документы.ВводОстатковТоваров);
+ НоменклатураСервер.ЗаполнитьСтатусыУказанияСерий(Док, ПараметрыУказанияСерий);
+ Исключение
+ КонецПопытки;
+
+ Док.ОбменДанными.Загрузка = Ложь;
+ Док.Записать(РежимЗаписиДокумента.Запись);
+ Возврат Док;
+
+КонецФункции
+
Процедура ЗаполнитьСтрокуВходящихДанныхИзAPI(НовСтр, СтрокаAPI)
НовСтр.НоменклатураИдентификатор = UUIDИзСтроки(ЗначениеСвойства(СтрокаAPI, "nomenclature_guid", ""));
diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml
index 63b5932..9103185 100644
--- a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml
+++ b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml
@@ -19,6 +19,11 @@
Form.Command.Сопоставить
+
@@ -43,6 +48,25 @@
+
+ Объект.Организация
+ true
+
+
+
+
+ Объект.ПерезаписатьДокументы
+
+
+ ru
+ Удалить непроведённые документы этой волны перед созданием
+
+
+ ShowRight
+ Auto
+
+
+
@@ -227,6 +251,19 @@
+
+ Объект.ВходящиеДанные.ДокументВвода
+ EnterOnInput
+
+
+
+
+ Объект.ВходящиеДанные.ЗагруженоВДокумент
+ EnterOnInput
+ Auto
+
+
+
@@ -439,5 +476,20 @@
Сопоставить
+
+
+
+ ru
+ Создать документы
+
+
+
+
+ ru
+ Создать ВводОстатковТоваров по сопоставленным строкам
+
+
+ СоздатьДокументы
+
\ No newline at end of file
diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl
index a59c694..2b73d87 100644
--- a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl
+++ b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl
@@ -32,7 +32,12 @@
Возврат;
КонецЕсли;
- ПодобратьСкладыНаСервере();
+ Попытка
+ ПодобратьСкладыНаСервере();
+ Исключение
+ ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
+ Возврат;
+ КонецПопытки;
Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.ГруппаОтбор;
КонецПроцедуры
@@ -49,7 +54,12 @@
Возврат;
КонецЕсли;
- Количество = ЗагрузитьОстаткиНаСервере();
+ Попытка
+ Количество = ЗагрузитьОстаткиНаСервере();
+ Исключение
+ ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
+ Возврат;
+ КонецПопытки;
Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.ГруппаВходящиеДанные;
ПоказатьОповещениеПользователя("Загрузка остатков", , "Загружено строк: " + Формат(Количество, "ЧГ=0"));
@@ -79,11 +89,53 @@
Возврат;
КонецЕсли;
РежимТест = (РезультатВопроса <> КодВозвратаДиалога.Да);
- Текст = СопоставитьНаСервере(РежимТест);
+ Попытка
+ Текст = СопоставитьНаСервере(РежимТест);
+ Исключение
+ ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
+ Возврат;
+ КонецПопытки;
ПоказатьОповещениеПользователя("Сопоставление", , Текст);
КонецПроцедуры
+&НаКлиенте
+Процедура СоздатьДокументы(Команда)
+
+ Если Не ЗначениеЗаполнено(Объект.Организация) Тогда
+ ПоказатьПредупреждение(, "Укажите организацию");
+ Возврат;
+ КонецЕсли;
+ Если Не ЗначениеЗаполнено(Объект.ДатаДокументовВвода) Тогда
+ ПоказатьПредупреждение(, "Укажите дату документов ввода");
+ Возврат;
+ КонецЕсли;
+
+ Описание = Новый ОписаниеОповещения("СоздатьДокументыПослеВопроса", ЭтотОбъект);
+ ПоказатьВопрос(Описание,
+ "Создать документы ВводОстатковТоваров?" + Символы.ПС
+ + "Да — запись; Нет — только подсчёт (тест); Отмена — прервать.",
+ РежимДиалогаВопрос.ДаНетОтмена);
+
+КонецПроцедуры
+
+&НаКлиенте
+Процедура СоздатьДокументыПослеВопроса(РезультатВопроса, ДопПараметры) Экспорт
+
+ Если РезультатВопроса = КодВозвратаДиалога.Отмена Тогда
+ Возврат;
+ КонецЕсли;
+ РежимТест = (РезультатВопроса <> КодВозвратаДиалога.Да);
+ Попытка
+ Текст = СоздатьДокументыНаСервере(РежимТест);
+ Исключение
+ ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
+ Возврат;
+ КонецПопытки;
+ ПоказатьОповещениеПользователя("Документы ввода", , Текст);
+
+КонецПроцедуры
+
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
@@ -210,6 +262,24 @@
КонецФункции
+&НаСервере
+Функция СоздатьДокументыНаСервере(РежимТест)
+
+ ОбъектОбработки = РеквизитФормыВЗначение("Объект");
+ Результат = ОбъектОбработки.СоздатьДокументыВводаОстатков(РежимТест);
+ ЗначениеВРеквизитФормы(ОбъектОбработки, "Объект");
+
+ Возврат СтрШаблон(
+ "Документов: %1; строк: %2; удалено прежних: %3; ошибок: %4; тег: %5%6",
+ Формат(Результат.СозданоДокументов, "ЧН=0; ЧГ=0"),
+ Формат(Результат.СтрокВДокументах, "ЧН=0; ЧГ=0"),
+ Формат(Результат.УдаленоДокументов, "ЧН=0; ЧГ=0"),
+ Формат(Результат.Ошибок, "ЧН=0; ЧГ=0"),
+ Результат.ТекстТега,
+ ?(РежимТест, " (тест)", ""));
+
+КонецФункции
+
&НаСервере
Функция ЗначениеСвойстваОтвета(Источник, Имя)