Цель: есть документ "Заказ" с табличной частью "Товары" и колонками "Номенклатура" и "Количество". Этот документ заполнен рядом номенклатур и количеств. Далее от клиента попадает документ Exel с номенклатурами и количеством и нужно реализовать механизм, который найдёт соответствие номенклатуры с документа "Заказ" и файла Exel, после чего изменит значение количества в заказе.
В кратце, с файла нужно обновить данные в заказе.
Для этого я сделал так как показано ниже в коде, но мне все же интересно. Можно было как то реализовать проверку файла не скидывая его на сервер, то есть сразу на клиенте?
Так же в коде есть комментарии с моими страданиями, а именно попытки использовать процедуру "НачатьПомещениеФайлаНаСервер", которая, как оказалось, не поддерживается на моей платформе, а так же попытка чтения через потоки, который, как снова оказалось, не умеют работать с форматом файла xlsx.
В кратце, с файла нужно обновить данные в заказе.
Для этого я сделал так как показано ниже в коде, но мне все же интересно. Можно было как то реализовать проверку файла не скидывая его на сервер, то есть сразу на клиенте?
Так же в коде есть комментарии с моими страданиями, а именно попытки использовать процедуру "НачатьПомещениеФайлаНаСервер", которая, как оказалось, не поддерживается на моей платформе, а так же попытка чтения через потоки, который, как снова оказалось, не умеют работать с форматом файла xlsx.
&НаКлиенте
Процедура ОбновитьСФайла(Команда)
ДиалогВыбораФайлаЗаказа=Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбораФайлаЗаказа.Заголовок="Выбор файла";
ДиалогВыбораФайлаЗаказа.МножественныйВыбор = Ложь;
ДиалогВыбораФайлаЗаказа.Фильтр="Файл Exel(*.xlsx)|*.xlsx";
ДиалогВыбораФайлаЗаказа.ПредварительныйПросмотр=Истина;
ДиалогВыбораФайлаЗаказа.Показать(Новый ОписаниеОповещения("РезультатВыбораФайла",ЭтаФорма));
КонецПроцедуры
&НаКлиенте
Процедура РезультатВыбораФайла(ВыбраныеФайлы,ДополнительныеПараметры) Экспорт
Если НЕ ЗначениеЗаполнено(ВыбраныеФайлы) Тогда
Возврат;
КонецЕсли;
//НачатьПомещениеФайлаНаСервер(Новый ОписаниеОповещения("РезультатПерегрузкиФайлаНаСервер",ЭтаФорма),,,,ВыбраныеФайлы[0],УникальныйИдентификатор);
Файл = Новый ДвоичныеДанные(ВыбраныеФайлы[0]);
Адрес = ПоместитьВоВременноеХранилище(Файл, ЭтаФорма.УникальныйИдентификатор);
ОбработкаНаСервере(Адрес);
КонецПроцедуры
&НаСервере
Процедура ОбработкаНаСервере(Адрес=Неопределено)
Если НЕ ЗначениеЗаполнено(Адрес) Тогда
Возврат;
КонецЕсли;
ИмяВременногоФайла=ПолучитьИмяВременногоФайла(".xlsx");
ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
ДвоичныеДанные.Записать(ИмяВременногоФайла);
ТабДокумент=Новый ТабличныйДокумент;
ТабДокумент.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Текст);
//невозможно реализовать через потоки из за отсутствия поддержки обработки документов формата xlsx
//ПотокДляЧтения=ДвоичныеДанные.ОткрытьПотокДляЧтения();
//ПотокДляЧтения.Перейти(0, ПозицияВПотоке.Начало);
//ТабДокумент=Новый ТабличныйДокумент;
//ТабДокумент.Прочитать(ПотокДляЧтения, СпособЧтенияЗначенийТабличногоДокумента.Текст);
//ПотокДляЧтения.Закрыть();
СтолбецИтога=16;
//R - строка, C - колонка
//обход документа
Для СтрокаНомер=4 По 500 Цикл
НоменклатураТабДок=ТабДокумент.Область("R"+Строка(СтрокаНомер)+"C1").Текст;
ГотовитьсяКОтправке=ТабДокумент.Область("R"+Строка(СтрокаНомер)+"C"+Строка(СтолбецИтога)).Текст;
Если ЗначениеЗаполнено(НоменклатураТабДок) И ЗначениеЗаполнено(ГотовитьсяКОтправке) Тогда
Попытка
ГотовитьсяКОтправке=Число(ГотовитьсяКОтправке);
Исключение
Сообщить("Не удалось распорзанать итоговое количество для номенклатры "+НоменклатураТабДок+". Операция завершилась наудачей!");
Возврат;
КонецПопытки;
//поиск строки для замены итогового количества
Для каждого СтрокаТовары Из Объект.ТоварыЗаказ Цикл
Если СтрокаТовары.Номенклатура.Наименование=НоменклатураТабДок Тогда
СтрокаТовары.РезультатРеальный=ГотовитьсяКОтправке;
КонецЕсли;
КонецЦикла;
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
//очистка от файла
Попытка
УдалитьФайлы(ИмяВременногоФайла);
Исключение
Сообщить("Возникли проблемы с удалением временного файла");
Возврат;
КонецПопытки;
КонецПроцедуры;
ПоказатьПо теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Можно на клиенте. См пример
&НаКлиенте
Процедура ЗагрузитьИзXLS(Команда)
// ПолноеИмяФайлаШаблона = КаталогДокументов() + "ОценочнаяСводный.xlsx";
ПолноеИмяФайлаШаблона = Объект.ИмяЭксельФайла;
Файл = Новый Файл(ПолноеИмяФайлаШаблона);
Если НЕ Файл.Существует() Тогда
Сообщить("Файл шаблона (отсутствует) " + ПолноеИмяФайлаШаблона);
Иначе
//ПолноеИмяФайлаЭкспорт = КаталогДокументов() + СокрЛП(Объект.Сотрудник) + ".xlsx";
//КопироватьФайл(ПолноеИмяФайлаШаблона, ПолноеИмяФайлаЭкспорт);
//Сообщить("Создаем файл " + ПолноеИмяФайлаЭкспорт);
//ВыгрузитьВЭксельФайл(ПолноеИмяФайлаЭкспорт);
Если ЗагрузитьИзЭкселя(ПолноеИмяФайлаШаблона) Тогда
Сообщить("Данные загружены из " + ПолноеИмяФайлаШаблона);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция ЗагрузитьИзЭкселя(ИмяФайла)
// Вставить содержимое обработчика.
Попытка
Excel = новый COMОбъект("Excel.Application");
Исключение
Сообщить("Похоже, Excel на компьютере не установлен. Необходимо выполнить установку/переустановку Excel.");
Возврат Ложь;
КонецПопытки;
// Подключились успешно, открываем файл (только для чтения)
Excel.Workbooks.Open(ИмяФайла,,Истина);
//Номер листа в книге Excel для получения данных
// НомерЛиста = 1;
//Открываем необходимый лист
Sheet = Excel.Sheets("Лист1");
Sheet.Select();
НачСтрока = 0; НачКолонка = 0; КонСтрока = 0;
Если ПолучитьRowColДиапазона(Sheet, "Блок", НачСтрока, НачКолонка, КонСтрока, "$L$5:$P$8") Тогда
тчБлок = Объект.Блок;
тчБлок.Очистить();
// Блок :: F4 - J7
Для б=НачСтрока по КонСтрока Цикл
стр = тчБлок.Добавить();
стр.ФункБлок = Excel.Cells(б, НачКолонка).Value; // F
стр.Выручка = Excel.Cells(б, НачКолонка+1).Value; // G
стр.OIBDA = Excel.Cells(б, НачКолонка+2).Value; // H
стр.Roll_out = Excel.Cells(б, НачКолонка+3).Value; // I
КонецЦикла;
Иначе
Сообщить("Функциональный блок - не загружен");
КонецЕсли;
НачСтрока = 0; НачКолонка = 0; КонСтрока = 0;
Если ПолучитьRowColДиапазона(Sheet, "весгод", НачСтрока, НачКолонка, КонСтрока, "$F$15:$H$24") Тогда
тчВесгод = Объект.Весгод;
тчВесгод.Очистить();
// Весгод F15 (6) : H24 (8)
Для б=НачСтрока по КонСтрока Цикл
стр = тчВесгод.Добавить();
стр.Грейд = Excel.Cells(б, НачКолонка).Value; // F
стр.БизнесПоказатели = Excel.Cells(б, НачКолонка + 1).Value; // G
стр.ИндЗадачи = Excel.Cells(б, НачКолонка + 2).Value; // H
КонецЦикла;
Иначе
Сообщить("Вес показателей - не загружен");
КонецЕсли;
НачСтрока = 0; НачКолонка = 0; КонСтрока = 0;
Если ПолучитьRowColДиапазона(Sheet, "грейд", НачСтрока, НачКолонка, КонСтрока, "$A$3:$C$12") Тогда
тчГрейд = Объект.Грейд;
тчГрейд.Очистить();
// Грейд A3 : C12 (3)
Для б=НачСтрока по КонСтрока Цикл
стр = тчГрейд.Добавить();
стр.Грейд = Excel.Cells(б, НачКолонка).Value; // A
стр.Полугодовая = Excel.Cells(б, НачКолонка + 1).Value; // B
стр.Годовая = Excel.Cells(б, НачКолонка + 2).Value; // C
стр.ИтогоПремиальныйФонд = стр.Полугодовая + стр.Годовая;
КонецЦикла;
Иначе
Сообщить("Грейд - не загружен");
КонецЕсли;
НачСтрока = 0; НачКолонка = 0; КонСтрока = 0;
Если ПолучитьRowColДиапазона(Sheet, "бизнес", НачСтрока, НачКолонка, КонСтрока, "$F$10:$K$12") Тогда
тчБизнес = Объект.БизнесПоказатели;
тчБизнес.Очистить();
// бизнес F10 : K12
Для б=НачСтрока по КонСтрока Цикл
стр = тчБизнес.Добавить();
стр.Показатель = Excel.Cells(б, НачКолонка).Value; // F
стр.Нижняя = Excel.Cells(б, НачКолонка+1).Value; // G
стр.Целевое = Excel.Cells(б, НачКолонка+2).Value; // H
стр.Верхняя = Excel.Cells(б, НачКолонка+3).Value; // I
стр.Факт = Excel.Cells(б, НачКолонка+4).Value; // J
КонецЦикла;
Иначе
Сообщить("Бизнес показатели - не загружены");
КонецЕсли;
НачСтрока = 0; НачКолонка = 0; КонСтрока = 0;
Если ПолучитьRowColДиапазона(Sheet, "kriterii", НачСтрока, НачКолонка, КонСтрока, "$J$15:$K$18") Тогда
тчКритерии = Объект.Критерии;
тчКритерии.Очистить();
// Критерии J15 : K18
Для б=НачСтрока по КонСтрока Цикл
стр = тчКритерии.Добавить();
стр.Оценка = Excel.Cells(б, НачКолонка).Value; // J
стр.Процент = Excel.Cells(б, НачКолонка+1).Value; // K
КонецЦикла;
Иначе
Сообщить("Критерии - не загружены");
КонецЕсли;
НачСтрока = 0; НачКолонка = 0; КонСтрока = 0;
Если ПолучитьRowColДиапазона(Sheet, "ГраницыПремирования", НачСтрока, НачКолонка, КонСтрока, "$N$10:$O$12") Тогда
тчГраницыПремирования = Объект.ГраницыПремирования;
тчГраницыПремирования.Очистить();
// Критерии N10 : O12
Для б=НачСтрока по КонСтрока Цикл
стр = тчГраницыПремирования.Добавить();
стр.Процент = Excel.Cells(б, НачКолонка).Value; // N
стр.Граница = Excel.Cells(б, НачКолонка+1).Value; // O
КонецЦикла;
Иначе
Сообщить("Границы премирования - не загружены");
КонецЕсли;
// Excel.ActiveWorkbook.Save();
Excel.ActiveWorkbook.Close();
Возврат Истина;
КонецФункции
&НаКлиенте
Функция ПолучитьRowColДиапазона(Sheet, ИменованныйДиапазон, НачСтрока, НачКолонка, КонСтрока, АдресДиапазонаПоУмолчанию=Неопределено)
Попытка
Адр = Sheet.Range(ИменованныйДиапазон).Address; // $F$4:$J$7
Исключение
Адр = АдресДиапазонаПоУмолчанию;
КонецПопытки;
Если Адр = Неопределено Тогда
ДиапазонПолучен = Ложь;
Иначе
Разделитель = Найти(Адр,":");
Если Разделитель = 0 Тогда
ЛевАдр = Адр;
ПравАдр = Адр;
Иначе
ЛевАдр = Лев(Адр, Разделитель - 1);
ПравАдр= Сред(Адр,Разделитель + 1);
КонецЕсли;
S = Найти(ЛевАдр,"$");
ЛевАдр= Сред(ЛевАдр, S + 1);
S = Найти(ЛевАдр,"$");
ЛевАдрКолонка = Лев(ЛевАдр, S - 1); // F
ЛевАдрРяд = Сред(ЛевАдр, S + 1); // 4
S = Найти(ПравАдр,"$");
ПравАдр = Сред(ПравАдр, S + 1);
S = Найти(ПравАдр,"$");
ПравАдрКолонка = Лев(ПравАдр, S-1); // J
ПравАдрРяд = Сред(ПравАдр, S + 1); // 7
НачКолонка = КодСимвола(ЛевАдрКолонка) - КодСимвола("A") + 1;
НачСтрока = Число(ЛевАдрРяд);
КонСтрока = Число(ПравАдрРяд);
ДиапазонПолучен = Истина;
КонецЕсли;
Возврат ДиапазонПолучен;
КонецФункции
Показать
Можно прочитать файл на сервере в табличный документ, являющийся реквизитом формы, а потом к этому реквизиту формы ограниченно можно достучаться и на клиенте. Не сохраняя файл Excel не получится его прочитать в табличный документ - глюк платформы, походу. Можно xlsx распаковать на клиенте чтением ZIP, оттуда выдрать сам документ и работать с ним, как с XML - вполне рабочий вариант, но придется несколько повозиться с интерпретацией XML.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот