На данном портате нашел внешнюю обработку по загрузке данных в ТЧ документов (https://infostart.ru/public/722665/) Немного модифицирую под себя. Убрал проверку на Начало таблицы, внес коррективы по поводу игнора пустых и необнаруженных строк с Артикулом.
Взялся за изменение формы.
Дорисовал свои поля. (фото1) В частности и Кнопку Выполнить (в оригинале там было просто открыть файл excel и заполнить ТЧ ).
Но на этапе нажатия кнопки Выполнить, вызывается исключение, что
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Команда ""%1"" не поддерживается данной обработкой!'"),
ИдентификаторКоманды);
Сам модифицированный код обработки такой
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения) Экспорт
Если ИдентификаторКоманды = "ЗагрузкаИзExcel" Тогда
ПутьКФайлуНачалоВыбора(,,);
ЗагрузитьВДокумент(ОбъектыНазначения[0]);
п = Новый Структура("Ключ", ОбъектыНазначения[0]);
Если ТипЗнч(ОбъектыНазначения[0]) = Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
Форма = ПолучитьФорму("Документ.ПеремещениеТоваров.ФормаОбъекта", п);
Форма.Прочитать();
ИначеЕсли ТипЗнч(ОбъектыНазначения[0]) = Тип("ДокументСсылка.СписаниеНедостачТоваров") Тогда
Форма = ПолучитьФорму("Документ.СписаниеНедостачТоваров.ФормаОбъекта", п);
Форма.Прочитать();
Иначе
Сообщить("Некорректный тип документа "+ТипЗнч(ОбъектыНазначения[0]));
КонецЕсли;
ПоказатьОповещениеПользователя("Загрузка завершена !");
Иначе
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Команда ""%1"" не поддерживается данной обработкой!'"),
ИдентификаторКоманды);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПутьКФайлуНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка);
//Режим = РежимДиалогаВыбораФайла.Открытие;
Режим = РежимДиалогаВыбораФайла.Открытие;
ДиалогОткрытия = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытия.ПолноеИмяФайла = "";
Фильтр = "Документы Excel (*.xls, *.xlsx)|*.xl*";
ДиалогОткрытия.Фильтр = Фильтр;
ДиалогОткрытия.МножественныйВыбор = Ложь;
ДиалогОткрытия.Заголовок = "Выберите файл с данными";
Если ДиалогОткрытия.Выбрать() Тогда
Объект.ПутьКФайлу = ДиалогОткрытия.ПолноеИмяФайла;
Иначе
Сообщить("Файл не выбран !");
Возврат;
КонецЕсли;
ДД = Новый ДвоичныеДанные(Объект.ПутьКФайлу);
СДД = ПоместитьВоВременноеХранилище(ДД);
ПрочитатьДанныеНаСервере(СДД);
КонецПроцедуры
&НаСервере
Процедура ПрочитатьДанныеНаСервере(СсылкаДД)
XLDATA = ПолучитьИзВременногоХранилища(СсылкаДД);
ИмяФ = ПолучитьИмяВременногоФайла("xlsx");
XLDATA.Записать(ИмяФ);
Попытка
ДанныеXL.Прочитать(ИмяФ, СпособЧтенияЗначенийТабличногоДокумента.Текст); // СпособЧтенияЗначенийТабличногоДокумента - новый параметр платформы 8.3.6. Второе значение "Текст".
Исключение
Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
КонецПроцедуры
&НаСервере
Функция ВЧисло(СтрокаЧисло)
Если СокрЛП(СтрокаЧисло) = "" Тогда
Возврат 0;
КонецЕсли;
Если СтрокаЧисло = "- 0 р." Тогда
Возврат 0;
КонецЕсли;
СтрокаЧисло = СтрЗаменить(СтрокаЧисло,"р .","");
СтрокаЧисло = СтрЗаменить(СтрокаЧисло,"р.","");
СтрокаЧисло = СтрЗаменить(СтрокаЧисло,",",".");
СтрокаЧисло = СтрЗаменить(СтрокаЧисло,"-","");
СтрокаЧисло = СокрЛП(СтрокаЧисло);
Попытка
Возврат Число(СтрокаЧисло);
Исключение
Сообщить("Не удалось преобразовать в число: "+СтрокаЧисло);
Возврат 0;
КонецПопытки;
КонецФункции
&НаСервере
Процедура ЗагрузитьВДокумент(ТекущийДокумент)
ТабДок = ДанныеXL;
КолвоСтрокФайла = ТабДок.ВысотаТаблицы;
КонечнаяКолонка = ТабДок.ПолучитьОбласть().ШиринаТаблицы;
//НашлиНачало = Ложь;
ДокументОбъект = ТекущийДокумент.ПолучитьОбъект();
Если ТипЗнч(ТекущийДокумент) = Тип("ДокументСсылка.ПересчетТоваров") Тогда
Для каждого стр Из ДокументОбъект.Товары Цикл
стр.КоличествоФакт = 0;
стр.КоличествоУпаковокФакт = 0;
КонецЦикла;
Иначе
ДокументОбъект.Товары.Очистить();
КонецЕсли;
Для k = 1 По КолвоСтрокФайла Цикл
ТС = Формат(k,"ЧГ=");
Артикул = СокрЛП(ТабДок.Область("R"+ТС+"C1").Текст);
//Если Не НашлиНачало Тогда
// Если Артикул = "Артикул" Тогда
// НашлиНачало = Истина;
// Продолжить;
// Иначе
// Продолжить;
// КонецЕсли;
//КонецЕсли;
Если Артикул = "" Тогда
Прервать;
КонецЕсли;
Номенклатура = Справочники.Номенклатура.ПустаяСсылка();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ПометкаУдаления = ЛОЖЬ
| И Номенклатура.Артикул = &Артикул";
Запрос.Параметры.Вставить("Артикул", Артикул);
Результат = Запрос.Выполнить().Выбрать();
Если Результат.Количество() > 1 Тогда
сообщить("Найдено несколько позиций номенклатуры по артикулу: " + Артикул, СтатусСообщения.Важное);
ИначеЕсли Результат.Следующий() Тогда
Номенклатура = Результат.Ссылка;
Иначе
сообщить("Номенклатура по артикулу: " + Артикул + ", не найдена.", СтатусСообщения.Важное);
КонецЕсли;
//Номенклатура = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул",Артикул);
//Если Не ЗначениеЗаполнено(Номенклатура) Тогда
// Сообщить("Не найдена номенклатура с артикулом "+Артикул);
// Продолжить;
//КонецЕсли;
Если ТипЗнч(ТекущийДокумент) = Тип("ДокументСсылка.УстановкаЦенНоменклатуры") Тогда
ИмяПрайса = ТабДок.Область("R"+ТС+"C3").Текст;
Прайс = Справочники.ВидыЦен.НайтиПоНаименованию(ИмяПрайса);
Если Не ЗначениеЗаполнено(Прайс) Тогда
Сообщить("Не найден вид цены с наименованием "+ИмяПрайса);
Продолжить;
КонецЕсли;
Цена = ВЧисло(ТабДок.Область("R"+ТС+"C4").Текст);
НС = ДокументОбъект.Товары.Добавить();
НС.Номенклатура = Номенклатура;
НС.Цена = Цена;
НС.ВидЦены = Прайс;
НС.ЦенаИзмененаВручную = Истина;
ИначеЕсли ТипЗнч(ТекущийДокумент) = Тип("ДокументСсылка.ПересчетТоваров") Тогда
ИмяСклада = ТабДок.Область("R"+ТС+"C3").Текст;
Склад = Справочники.Склады.НайтиПоНаименованию(ИмяСклада);
Если Не ЗначениеЗаполнено(Склад) Тогда
Сообщить("Не найден склад с наименованием "+ИмяСклада);
Продолжить;
КонецЕсли;
Если Склад <> ДокументОбъект.Склад Тогда
Продолжить;
КонецЕсли;
Количество = ВЧисло(ТабДок.Область("R"+ТС+"C2").Текст);
Если Количество = 0 Тогда
Сообщить("По товару "+Артикул+" "+Номенклатура+" количество = 0.");
КонецЕсли;
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Номенклатура", Номенклатура);
НайденныеСтроки = ДокументОбъект.Товары.НайтиСтроки(ПараметрыОтбора);
Если НайденныеСтроки.Количество() = 0 Тогда
Сообщить("По товару "+Артикул+" "+Номенклатура+" не найдено строк в пересчете товаров. Позиция добавлена в конец таблицы в количестве "+Количество+".",СтатусСообщения.Важное);
НС = ДокументОбъект.Товары.Добавить();
НС.Номенклатура = Номенклатура;
НС.КоличествоФакт = Количество;
НС.КоличествоУпаковокФакт = Количество;
Продолжить;
КонецЕсли;
Если НайденныеСтроки.Количество() = 1 Тогда
Для каждого строчка Из НайденныеСтроки Цикл
строчка.КоличествоФакт = Количество;
строчка.КоличествоУпаковокФакт = Количество;
КонецЦикла;
Иначе
КолвоСвободно = 0;
КолвоРезерв = 0;
Для каждого строчка Из НайденныеСтроки Цикл
Если ЗначениеЗаполнено(строчка.Назначение) Тогда
КолвоРезерв = КолвоРезерв+строчка.Количество;
Иначе
КолвоСвободно = КолвоСвободно+строчка.Количество;
КонецЕсли;
КонецЦикла;
Если (КолвоРезерв+КолвоСвободно) = Количество Тогда
Для каждого строчка Из НайденныеСтроки Цикл
строчка.КоличествоФакт = строчка.Количество;
строчка.КоличествоУпаковокФакт = строчка.КоличествоУпаковок;
КонецЦикла;
ИначеЕсли (КолвоРезерв+КолвоСвободно)<Количество Тогда
Для каждого строчка Из НайденныеСтроки Цикл
Если Не ЗначениеЗаполнено(строчка.Назначение) Тогда
строчка.КоличествоФакт = Количество-КолвоРезерв;
строчка.КоличествоУпаковокФакт = Количество-КолвоРезерв;
Прервать;
КонецЕсли;
КонецЦикла;
Для каждого строчка Из НайденныеСтроки Цикл
Если ЗначениеЗаполнено(строчка.Назначение) Тогда
строчка.КоличествоФакт = строчка.Количество;
строчка.КоличествоУпаковокФакт = строчка.КоличествоУпаковок;
КонецЕсли;
КонецЦикла;
Иначе
Если КолвоРезерв>=Количество Тогда
Доля = Количество/КолвоРезерв;
КолОсталось = Количество;
ПослСтрочка = Неопределено;
Для каждого строчка Из НайденныеСтроки Цикл
Если КолОсталось = 0 Тогда
Прервать;
КонецЕсли;
Если ЗначениеЗаполнено(строчка.Назначение) Тогда
ПослСтрочка = строчка;
Кол = Окр(Доля*строчка.Количество+0.5);
Если Кол>КолОсталось Тогда
Кол = КолОсталось;
КонецЕсли;
КолОсталось = КолОсталось-Кол;
строчка.КоличествоФакт = Кол;
строчка.КоличествоУпаковокФакт = Кол;
КонецЕсли;
КонецЦикла;
Если КолОсталось<>0 и ПослСтрочка<>Неопределено Тогда
ПослСтрочка.КоличествоФакт = ПослСтрочка.КоличествоФакт+КолОсталось;
ПослСтрочка.КоличествоУпаковокФакт = ПослСтрочка.КоличествоУпаковокФакт+КолОсталось;
КолОсталось = 0;
КонецЕсли;
Если КолОсталось<>0 Тогда
Сообщить("!!! По товару "+Артикул+" "+Номенклатура+" осталось нераспределенное количество остатка среди резерва = "+КолОсталось+".",СтатусСообщения.ОченьВажное);
КонецЕсли;
Иначе
Для каждого строчка Из НайденныеСтроки Цикл
Если ЗначениеЗаполнено(строчка.Назначение) Тогда
строчка.КоличествоФакт = строчка.Количество;
строчка.КоличествоУпаковокФакт = строчка.КоличествоУпаковок;
КонецЕсли;
КонецЦикла;
Для каждого строчка Из НайденныеСтроки Цикл
Если Не ЗначениеЗаполнено(строчка.Назначение) Тогда
строчка.КоличествоФакт = Количество-КолвоРезерв;
строчка.КоличествоУпаковокФакт = Количество-КолвоРезерв;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Иначе
Количество = ВЧисло(ТабДок.Область("R"+ТС+"C2").Текст);
Если ТипЗнч(ТекущийДокумент) = Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
НС = ДокументОбъект.Товары.Добавить();
НС.Номенклатура = Номенклатура;
НС.Количество = Количество;
НС.КоличествоУпаковок = Количество;
ИначеЕсли ТипЗнч(ТекущийДокумент) = Тип("ДокументСсылка.СписаниеНедостачТоваров") Тогда
НС = ДокументОбъект.Товары.Добавить();
НС.Номенклатура = Номенклатура;
НС.Количество = Количество;
КонецЕсли;
КонецЕсли;
КонецЦикла;
//Если Не НашлиНачало Тогда
// Сообщить("Неправильный формат файла.");
// Возврат;
//КонецЕсли;
ДокументОбъект.Записать();
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьЗагрузкуИзФайла(Команда)
Если не ЗначениеЗаполнено(Объект.ПутьКФайлу) Тогда
предупреждение("Не указан файл для загрузки.");
возврат;
КонецЕсли;
Файл = Новый Файл(Объект.ПутьКФайлу);
Если не Файл.Существует() ТОгда
Предупреждение("Указанный файл не существет. Выберите другой файл.");
возврат;
КонецЕсли;
ВыполнитьКоманду(,);
КонецПроцедуры
Показать
Вот с обходом исключения уже получаются косяки при модификации кода. Как можно "культурно" обойти данную проблему, и сделать загрузку именно через кнопку "Выполнить"?
&НаКлиенте
Процедура ВыполнитьЗагрузкуИзФайла(Команда)
Если не ЗначениеЗаполнено(Объект.ПутьКФайлу) Тогда
предупреждение("Не указан файл для загрузки.");
возврат;
КонецЕсли;
Файл = Новый Файл(Объект.ПутьКФайлу);
Если не Файл.Существует() ТОгда
Предупреждение("Указанный файл не существет. Выберите другой файл.");
возврат;
КонецЕсли;
ВыполнитьКоманду(,);
КонецПроцедуры
ОбъектыНазначения - Массив - Ссылки, для которых выполняется команда.
ЗагрузитьВДокумент(ОбъектыНазначения[0]);
п = Новый Структура("Ключ", ОбъектыНазначения[0]);
Если ТипЗнч(ОбъектыНазначения[0]) = Тип("ДокументСсылка.ПеремещениеТоваров") Тогда
Форма = ПолучитьФорму("Документ.ПеремещениеТоваров.ФормаОбъекта", п);
Форма.Прочитать();
ИначеЕсли ТипЗнч(ОбъектыНазначения[0]) = Тип("ДокументСсылка.СписаниеНедостачТоваров") Тогда
Форма = ПолучитьФорму("Документ.СписаниеНедостачТоваров.ФормаОбъекта", п);
Форма.Прочитать();
Иначе
Сообщить("Некорректный тип документа "+ТипЗнч(ОбъектыНазначения[0]));
КонецЕсли;
(10)
да, лучше, спасибо.
еще вопрос, если можно.
как возможно реализовать, чтобы кнопка выводилась не в панели сверху "Заполнение", а допустим ниже в "заполнить" - "загрузка из Excel".?
параллельно в макет добавил Параметры_Авторегистрации, а модуль обработки дописал процедуру:
Вам форма нужна только для того, чтобы предоставить возможность указания очищать или нет табличную часть ?
Или цели другие есть ?
Обработка писалась так, чтобы минимизировать количество различных диалоговых окон при работе с загрузкой. Просто - выбрали файл - загрузили.
Если нужно дополнительное значение "булево" от пользователя (например очищать ли табличную часть перед загрузкой) или любое простое значение, то просто можно решить вопрос так:
если есть хоть одна строка в документе - можете вывести вопрос асинхронный на очистку табличной части.