Имя: Пароль:
1C
 
Проверка файла эксель перед загрузкой.
0 lirt82
 
09.04.26
13:50
Всем привет, где правильнее реализовать проверку файла эксель на наличие в файле тех или иных колонок до загрузки файла в базу, с указанием на невозможность загрузки и подробным указанием причины?
#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ЗаполнитьИзExcel(Команда)
	
	ОписаниеОповещения = Новый ОписаниеОповещения("ЗагрузитьФайлЗавершение", ЭтотОбъект);
	ОбработкаНачалаЗагрузки = Новый ОписаниеОповещения("ОбработчикНачалаЗагрузки", ЭтотОбъект);
	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.Фильтр = НСтр("ru='Выберите файл Excel(*.xls, *.xlsx)|*.xls*'");
	НачатьПомещениеФайла(ОписаниеОповещения, , Диалог, Истина, УникальныйИдентификатор, ОбработкаНачалаЗагрузки);
	
КонецПроцедуры

 &НаКлиенте 
Процедура ОбработчикНачалаЗагрузки(ПомещаемыйФайл, ОтказОтПомещенияФайла, ДополнительныеПараметры) Экспорт 
	
	РасширениеExcelФайла = СтрЗаменить(ПомещаемыйФайл.Расширение, ".", "");
	ОтказОтПомещенияФайла = Ложь; 
	
	Если НЕ РасширениеExcelФайла = "xls" И НЕ РасширениеExcelФайла = "xlsx" Тогда 
		
		ПоказатьПредупреждение( , "Вы пытаетесь загрузить не Excel файл. Загрузка не может быть выполнена."); 
		ОтказОтПомещенияФайла = Истина; 
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьФайлЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
	
	Если Результат Тогда
		СписокСообщений = ЗаполнитьФормуИзФайлаExcelНаСервере(Адрес, Неопределено);
		Если ЗначениеЗаполнено(СписокСообщений) Тогда
			ОбщегоНазначенияКлиент.СообщитьПользователю(СписокСообщений);
		КонецЕсли;
	Иначе
		ТекстСообщения = НСтр("ru = 'Файл не был выбран!'");
		ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстСообщения);
	КонецЕсли;
	
КонецПроцедуры


&НаСервере
Процедура СоздатьВременныйФайл()
	
	Данные = ПолучитьИзВременногоХранилища(АдресExcelФайла);
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла(РасширениеExcelФайла);
	Данные.Записать(ИмяВременногоФайла);
	ЭтаФорма.ИмяВременногоФайла = ИмяВременногоФайла;
			
КонецПроцедуры

&НаСервере
Функция ЗаполнитьФормуИзФайлаExcelНаСервере(Адрес, ТекстОшибки) Экспорт
	
	Данные = ПолучитьИзВременногоХранилища(Адрес);
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла(РасширениеExcelФайла);
	Данные.Записать(ИмяВременногоФайла);
	
	Документ = Новый ТабличныйДокумент;
	Документ.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
	
	ПЗ = Новый ПостроительЗапроса;
	ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(Документ.Область(1, 1, Документ.ВысотаТаблицы, 6));
	ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
	ПЗ.ЗаполнитьНастройки();
	ПЗ.Выполнить();
	
	ТЗ_Excel = Новый ТаблицаЗначений;
	КвалификаторСтроки = Новый КвалификаторыСтроки(19);
	ТЗ_Excel.Колонки.Добавить("ФИО", Новый ОписаниеТипов("Строка"));
	ТЗ_Excel.Колонки.Добавить("ИНН", Новый ОписаниеТипов("Строка",,,,КвалификаторСтроки));
	ТЗ_Excel.Колонки.Добавить("Должность", Новый ОписаниеТипов("Строка"));
..........
1 Eiffil123
 
09.04.26
13:49
(0) на сервере
2 Fish
 
гуру
09.04.26
13:50
(1) +100. И обязательно ДО загрузки файла в базу
3 Lama12
 
09.04.26
13:52
(0) В самом файле. Скрипты в помощь. Ну и как вариант, выдавать заполняющему уже подготовленный файл с нужными колонками.
4 Garykom
 
гуру
09.04.26
14:29
(0) правильнее потребовать файл не формата эксель
а более строго формата, лучше с валидацией
например xml
5 Garykom
 
гуру
09.04.26
14:30
а то можно до схем (описания и заодно для валидации) эксель файлов додуматься
6 lirt82
 
09.04.26
15:12
ПЗ = Новый ПостроительЗапроса;
    ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(Документ.Область(1, 1, Документ.ВысотаТаблицы, 6));
    ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
    ПЗ.ЗаполнитьНастройки();
    ПЗ.Выполнить();
    
    ТЗ_Excel = Новый ТаблицаЗначений;
    КвалификаторСтроки = Новый КвалификаторыСтроки(19);
    ТЗ_Excel.Колонки.Добавить("ФИО", Новый ОписаниеТипов("Строка"));
    ТЗ_Excel.Колонки.Добавить("ИИН", Новый ОписаниеТипов("Строка",,,,КвалификаторСтроки));
    ТЗ_Excel.Колонки.Добавить("Должность", Новый ОписаниеТипов("Строка"));
    ТЗ_Excel.Колонки.Добавить("Грейд", Новый ОписаниеТипов("Строка"));
    ТЗ_Excel.Колонки.Добавить("Руководитель", Новый ОписаниеТипов("Строка"));
    ТЗ_Excel.Колонки.Добавить("ИИН_Руководителя", Новый ОписаниеТипов("Строка",,,,КвалификаторСтроки));
    ТЗ_Excel = ПЗ.Результат.Выгрузить();
    
    //+ функция проверки
    РезультатПроверкиТипСтруктура = ПроверитьТЗ_ExcelНаНаличиеКолонок(ТЗ_Excel);
Значение = Неопределено;
    Если РезультатПроверкиТипСтруктура.Свойство("ЕстьОшибкаТипБулево", Значение) Тогда
            Возврат РезультатПроверкиТипСтруктура.Свойство("ТекстОшибкиТипСтрока", Значение);
    Иначе
        
Для Каждого Стр Из ТЗ_Excel Цикл

как вариант можно было перед созданием ТЗ_Excel, функцией проверить на наличие ДоступныеПоля ПостроительЗапроса (ПЗ) но тогда нужно было в этой функции создать объект Соответствие или объект Массив его заполнить и проверить ПостроительЗапроса на наличие полей, но подумал оптимальнее работать с уже созданной ТЗ_Excel. т.е. чтобы не создавать 2 объекта(нагружать ресурсы базы) а проверять только один созданный объект, который впоследствии и обрабатывается.
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.