1. user1015647 20.05.19 13:45 Сейчас в теме

ЗагрузкаДанныхИзТабличногоДокумента

Задача следующая: Нужно создать обработку ЗагрузкаДанныхИзТабличногоДокумента в обычной форме. Можете книгу посоветовать?!
Найденные решения
18. user1015647 22.05.19 13:44 Сейчас в теме
Функция ДокументНачалоВыбора()
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл";
Диалог.Фильтр = "Все файлы Excel (*.xls, *.xlsx)|*.*";
Диалог.ПолноеИмяФайла = Документ;
Диалог.ПредварительныйПросмотр = Ложь;

Если Диалог.Выбрать() Тогда
ИмяКаталога = Диалог.Каталог;
Возврат Диалог.ПолноеИмяФайла;
КонецЕсли;
КонецФункции

Процедура КнопкаВыполнитьНажатие()
//
ИмяФайла = ДокументНачалоВыбора();

////подключаемся к эксель
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.WorkBooks.Open(Документ);

Состояние("Обработка файла Microsoft Excel...");

Исключение
Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
Сообщить(ОписаниеОшибки());
Возврат;

КонецПопытки;

Попытка
//Открываем необходимый лист
Excel.Sheets(1).Select(); // лист 1, по умолчанию
Исключение
//Закрываем Excel
Excel.ActiveWorkbook.Close();
Excel = 0;
Сообщить("Файл "+Строка(Документ)+" не соответствует необходимому формату! Первый лист не найден!");
ОтменитьТранзакцию();
Возврат;

КонецПопытки;

//Получим количество строк и колонок.
//В разных версиях Excel получаются по-разному, поэтому сначала определим версию Excel
Версия = Лев(Excel.Version,Найти(Excel.Version,".")-1);
Если Версия = "8" тогда
ФайлСтрок = Excel.Cells.CurrentRegion.Rows.Count;
ФайлКолонок = Макс(Excel.Cells.CurrentRegion.Columns.Count, 13);
Иначе
ФайлСтрок = Excel.Cells(1,1).SpecialCells(11).Row;
ФайлКолонок = Excel.Cells(1,1).SpecialCells(11).Column;
Конецесли;

КонецПроцедуры
Всем спасибо!
Остальные ответы
Избранное Подписка Сортировка: Древо
2. alex-l19041 8 20.05.19 13:55 Сейчас в теме
(1) есть типовая обработка с таким названием. Возьмите ее за основу и сделайте так как надо в конкретном случае
16. user1015647 22.05.19 06:49 Сейчас в теме
Процедура ДокументНачалоВыбора(Элемент, СтандартнаяОбработка)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл";
Диалог.ПолноеИмяФайла = Документ;
Диалог.ПредварительныйПросмотр = Ложь;
Диалог.Фильтр = "Все файлы Excel (*.xls, *.xlsx)|*.*";

Если Диалог.Выбрать() Тогда

ФайлНаДиске = Новый Файл(Диалог.ПолноеИмяФайла);
Если нРег(ФайлНаДиске.Расширение) = ".xls" Тогда
КнопкаВыполнитьНажатие(Элемент);
КонецЕсли;
КонецЕсли;
КонецПроцедуры


Функция КнопкаВыполнитьНажатие(Кнопка) Экспорт
ФайлНаДиске = Новый Файл(Документ);
Если НЕ ФайлНаДиске.Существует() Тогда
Сообщить("Файл не существует!");
Возврат Ложь;
КонецЕсли;

//подключаемся к эксель
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.WorkBooks.Open(Документ);

Состояние("Обработка файла Microsoft Excel...");

Исключение
Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
Сообщить(ОписаниеОшибки());
Возврат ложь;

КонецПопытки;

Попытка
//Открываем необходимый лист
Excel.Sheets(1).Select(); // лист 1, по умолчанию
Исключение
//Закрываем Excel
Excel.ActiveWorkbook.Close();
Excel = 0;
Сообщить("Файл "+Строка(Документ)+" не соответствует необходимому формату! Первый лист не найден!");
ОтменитьТранзакцию();
Возврат ложь;

КонецПопытки;

//Получим количество строк и колонок.
//В разных версиях Excel получаются по-разному, поэтому сначала определим версию Excel
Версия = Лев(Excel.Version,Найти(Excel.Version,".")-1);
Если Версия = "8" тогда
ФайлСтрок = Excel.Cells.CurrentRegion.Rows.Count;
ФайлКолонок = Макс(Excel.Cells.CurrentRegion.Columns.Count, 13);
Иначе
ФайлСтрок = Excel.Cells(1,1).SpecialCells(11).Row;
ФайлКолонок = Excel.Cells(1,1).SpecialCells(11).Column;
Конецесли;

КонецФункции
Говорит "Файл не существует!. Где неправильно подскажите
17. nikita0832 190 22.05.19 11:36 Сейчас в теме
(16)
ФайлНаДиске = Новый Файл(Документ);
по-моему не хватает
Если Диалог.Выбрать() Тогда
Документ = Диалог.ПолноеИмяФайла;
18. user1015647 22.05.19 13:44 Сейчас в теме
Функция ДокументНачалоВыбора()
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл";
Диалог.Фильтр = "Все файлы Excel (*.xls, *.xlsx)|*.*";
Диалог.ПолноеИмяФайла = Документ;
Диалог.ПредварительныйПросмотр = Ложь;

Если Диалог.Выбрать() Тогда
ИмяКаталога = Диалог.Каталог;
Возврат Диалог.ПолноеИмяФайла;
КонецЕсли;
КонецФункции

Процедура КнопкаВыполнитьНажатие()
//
ИмяФайла = ДокументНачалоВыбора();

////подключаемся к эксель
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.WorkBooks.Open(Документ);

Состояние("Обработка файла Microsoft Excel...");

Исключение
Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
Сообщить(ОписаниеОшибки());
Возврат;

КонецПопытки;

Попытка
//Открываем необходимый лист
Excel.Sheets(1).Select(); // лист 1, по умолчанию
Исключение
//Закрываем Excel
Excel.ActiveWorkbook.Close();
Excel = 0;
Сообщить("Файл "+Строка(Документ)+" не соответствует необходимому формату! Первый лист не найден!");
ОтменитьТранзакцию();
Возврат;

КонецПопытки;

//Получим количество строк и колонок.
//В разных версиях Excel получаются по-разному, поэтому сначала определим версию Excel
Версия = Лев(Excel.Version,Найти(Excel.Version,".")-1);
Если Версия = "8" тогда
ФайлСтрок = Excel.Cells.CurrentRegion.Rows.Count;
ФайлКолонок = Макс(Excel.Cells.CurrentRegion.Columns.Count, 13);
Иначе
ФайлСтрок = Excel.Cells(1,1).SpecialCells(11).Row;
ФайлКолонок = Excel.Cells(1,1).SpecialCells(11).Column;
Конецесли;

КонецПроцедуры
Всем спасибо!
3. alex-l19041 8 20.05.19 13:56 Сейчас в теме
4. ksen 20.05.19 14:02 Сейчас в теме
(3)Боюсь что на этой штуке он расплавится, сложно с такого начинать


(1)Книгу не посоветую, но вот что нужно сделать в общих чертах.
1)Изучить структуру табл части документа
2)Получить ссылку на документ/ссылку на табл часть документа(Ссылка.ПолучитьОбъект())
3)В цикле построчно записать новые значения согласно структуре табл части
4)Сохранить что получилось(Документ.Записать())
5. nikita0832 190 20.05.19 16:44 Сейчас в теме
Ух, люди, не засоряйте человеку голову com объектами...
&НаКлиенте
Процедура Загрузить(Команда)
	ОбработкаОкончанияПомещения = Новый ОписаниеОповещения
        ("ОбработчикОкончанияПомещения", ЭтотОбъект);
    
    НачатьПомещениеФайла(ОбработкаОкончанияПомещения, , , Истина,     
            ЭтаФорма.УникальныйИдентификатор);
КонецПроцедуры

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

&НаСервере
Функция ЗагрузитьИзExcel(Адрес,Расширение)
	Попытка
		Файл = ПолучитьИмяВременногоФайла(Расширение);
		ДД = ПолучитьИзВременногоХранилища(Адрес);
		ДД.Записать(Файл);
		Таб = ФайлExcelВТаблицуЗначений(Файл,1);
		Запрос = Новый Запрос;
		Запрос.УстановитьПараметр("Таб",Таб);
		Запрос.Текст = 
		#Область ТекстЗапроса
		"ВЫБРАТЬ
		|	Таб.*
		|ПОМЕСТИТЬ ВТ
		|ИЗ
		|	&Таб КАК Таб
		|;
		|
		|//Далее во 2 пакете дополняете ваш запрос ссылками из базы до готовой таблицы, которую загрузите в ТЧ
		|";
		#КонецОбласти
		Таблица= Запрос.Выполнить().Выгрузить();
		Объект.ТабличнаяЧасть.Загрузить(Таблица);
		Возврат СтрШаблон("Загружено %1 строк",Таблица.Количество());
	Исключение
		Возврат СтрШаблон("Ошибка загрузки: %1",ОписаниеОшибки());
	КонецПопытки;
	
КонецФункции

//Эту и следующую функцию лучше в общий модуль
Функция ФайлExcelВТаблицуЗначений(Файл,НомерЛиста=0,КолУровнейШапки=0,ЧитатьКакТекст=Ложь,УдалятьПустыеСтроки=Истина) Экспорт
	
	ТабДок = Новый ТабличныйДокумент;
	ТабДок.Прочитать(Файл,?(ЧитатьКакТекст,СпособЧтенияЗначенийТабличногоДокумента.Текст,СпособЧтенияЗначенийТабличногоДокумента.Значение));
	
	ЧитаемаяОбласть = ТабДок.Область();
	Если НомерЛиста>0 Тогда
		
		ТабОбластей = Новый ТаблицаЗначений;
		ТабОбластей.Колонки.Добавить("Верх");
		ТабОбластей.Колонки.Добавить("Область");
		
		Для Каждого Область Из ТабДок.Области Цикл
			Строка = ТабОбластей.Добавить();
			Строка.Область = Область;
			Строка.Верх = Область.Верх;
		КонецЦикла;
		
		ТабОбластей.Сортировать("Верх");
		Область = ТабОбластей[НомерЛиста-1].Область;
	КонецЕсли;
	
	Если КолУровнейШапки > 1 Тогда
		Область = СвернутьСложнуюШапку(ТабДок,КолУровнейШапки,Область);
	КонецЕсли;
	
	ПЗ = Новый ПостроительЗапроса;
	
	ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(Область);
	
	ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
	
	ПЗ.ЗаполнитьНастройки();
	
	ПЗ.Выполнить();
	
	Таб = ПЗ.Результат.Выгрузить();
	
	Если НЕ УдалятьПустыеСтроки Тогда
		Возврат Таб;
	КонецЕсли;
	Удаленные = 0;
	Для инд = 0 По Таб.Количество()-1 Цикл 
		Стр = Таб[инд-Удаленные];
		Заполнена = Ложь;
		Для Каждого Колонка Из Таб.Колонки Цикл
			Если ЗначениеЗаполнено(Стр[Колонка.Имя]) Тогда
				Заполнена = Истина;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Если Не Заполнена Тогда 
			Таб.Удалить(Стр);
			Удаленные = Удаленные+1;
		КонецЕсли;
	КонецЦикла;
	Возврат Таб;

КонецФункции // ФайлExcelВТаблицуЗначений()

// Для парсинга табличных документов: сворачивает шапку для построителя запросов до 1 уровня
//
// Параметры:
//  Область  - ТабличныйДокумент,ОбластьТабличногоДокумента - <описание параметра>
//  КолУровней  - Число - Исходное количество уровней начиная с 2. Передавать меньше 2 не имеет смысла.
//        
// Возвращаемое значение:
//   ОбластьТабличногоДокумента   - Область с обрезанной до 1 строки шапкой.
Функция СвернутьСложнуюШапку(ТабДок,КолУровней,Область=Неопределено) Экспорт
	Если Область=Неопределено Тогда
		Область = ТабДок.Область();
	КонецЕсли;
	МассивЗаголовков = Новый Массив;	
	МаксКолонок = ТабДок.ПолучитьРазмерОбластиДанныхПоГоризонтали();
	ПерваяСтрока = Область.Верх;
	Для Сч = 1 По КолУровней Цикл
		ПредЗначение = "";
		Для Кол = 1 По МаксКолонок Цикл
			Текст = ТабДок.Область("R"+Строка(ПерваяСтрока+Сч-1)+"C"+Кол).Текст;
			
			Если Сч = 1 Тогда
				МассивЗаголовков.Добавить(Новый Массив);
				Если ЗначениеЗаполнено(Текст) Тогда
					МассивЗаголовков[Кол-1].Добавить(Текст);
					ПредЗначение = Текст;
				Иначе
					МассивЗаголовков[Кол-1].Добавить(ПредЗначение);
				КонецЕсли;
			Иначе
				ИменаЗаголовка = МассивЗаголовков[Кол-1];
				РодительОтличается = Ложь;
				Если Кол >1 Тогда
					Для Инд = 0 по Сч-2 Цикл
						Если ИменаЗаголовка[Инд] <> МассивЗаголовков[Кол-2][Инд] Тогда
							РодительОтличается = Истина;
							Прервать;
						КонецЕсли;
					КонецЦикла;
				КонецЕсли;
				Если ЗначениеЗаполнено(Текст) Тогда
					ИменаЗаголовка.Добавить(Текст);
				Иначе
					Если ЗначениеЗаполнено(ПредЗначение) И НЕ РодительОтличается Тогда 
						ИменаЗаголовка.Добавить(ПредЗначение);
					КонецЕсли;
				КонецЕсли;
				ПредЗначение = Текст;
			КонецЕсли;
			
		КонецЦикла;
	КонецЦикла;
	Для Кол = 1 По МаксКолонок Цикл
		ТабДок.Область("R"+Строка(ПерваяСтрока+КолУровней-1)+"C"+Кол).Текст = СтрСоединить(МассивЗаголовков[Кол-1],"_");
		
	КонецЦикла;
	НоваяОбласть = ТабДок.Область("R"+Строка(ПерваяСтрока+КолУровней-1)+":R"+Область.Низ);
	Возврат НоваяОбласть;
КонецФункции // СвернутьСложнуюШапку()

Показать
6. Oldsad 21.05.19 04:36 Сейчас в теме
(5)
не забывайте только добавить что данный метод повиснет на эксель таблицах с ~100 тыс строк и более
в то время как эксель поддерживает таблицы размером до 1 млн строк, и через ком легко считываются
8. nikita0832 190 21.05.19 08:53 Сейчас в теме
(6)а производительность считывания через com? миллион вы в любом случае не дождетесь, плюс можете нехватку памяти схватить. десятки тысяч строк таким методом читал, сотни не попадались.
starik-2005; +1 Ответить
7. user1015647 21.05.19 06:20 Сейчас в теме
(5)мне в обычной форме нужно .
Вот задача.
Создать загрузку прайса из MS Excel.

Выбираем файл Excel — Прайс, файл «Прайс» в приложении;
Выбираем тип цены который будем загружать;
Должна быть галка создавать номенклатуру, которая не найдена (стоит — создавать, не стоит — не создавать);
Пример прайса в приложении. Колонки будут оставаться неизменными;
Обработка при необходимости создаёт номенклатуру и всегда создаёт документ «Установка цен номенклатуры».
9. nikita0832 190 21.05.19 08:55 Сейчас в теме
(7) в обычной форме ещё проще, файл на сервер передавать не надо, сразу ТабличныйДокумент.Прочитать() и в путь.
10. user1015647 21.05.19 08:56 Сейчас в теме
(7)т.е в обычном приложении ,не в упр
11. nikita0832 190 21.05.19 08:57 Сейчас в теме
12. starik-2005 1965 21.05.19 09:09 Сейчас в теме
(7)
Выбираем файл Excel — Прайс, файл «Прайс» в приложении;

1. Диалог выбора файла на открытие, результат в реквизит формы.
2. Тип цены - реквизит формы.
3. Чтение файла в новый табличный документ - см. синтаксис-помощник.
4. Для А = номер первой строки ПО ТабличныйДокумент.Высота - см. в синтаксис-помощник.
5. Поиск номенклатуры по заданным условиям (имя, фамилия, артикул, ...)
6. Если не найдена и галочка создавать - создадим:
6.1. СоздатьЭлемент(). Наименование = Таблица.Область(А, КолонкаСНаимеованием).Текст, Артикул = колонка с артикулом. ... Записать()
7. В документ установки цен добавляем строку, в нее найденную/созданную номенклатуру, цену с типом цен, ... - там может быть непросто, но в 10-й торговле вроде не так замороченно, как в 11-й.
8. конец цикла по А
9. Запись документа установки цен.
10. Получить заработную плату и отдать половину мне )))

Вот реально 20 минут обработка пишется с нуля.
13. user1015647 21.05.19 11:30 Сейчас в теме
модуль объекта
Функция ПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт
	
	xlLastCell = 11;
	
	ВыбФайл = Новый Файл(ИмяФайла);
	Если НЕ ВыбФайл.Существует() Тогда
		Сообщить("Файл не существует!");
		Возврат Ложь;
	КонецЕсли;
	
	Попытка
		Excel = Новый COMОбъект("Excel.Application");
		Excel.WorkBooks.Open(ИмяФайла);
		Состояние("Обработка файла Microsoft Excel...");
		ExcelЛист = Excel.Sheets(НомерЛистаExcel);
	Исключение
		Сообщить("Ошибка. Возможно неверно указан номер листа книги Excel.");
		Возврат ложь;
		
	КонецПопытки;
	
	ТабличныйДокумент.Очистить();
	
	ActiveCell = Excel.ActiveCell.SpecialCells(xlLastCell);
	RowCount = ActiveCell.Row;
	ColumnCount = ActiveCell.Column;
	Для Column = 1 По ColumnCount Цикл
		ТабличныйДокумент.Область("C" + Формат(Column, "ЧГ=")).ШиринаКолонки = ExcelЛист.Columns(Column).ColumnWidth;
	КонецЦикла;
	Для Row = 1 По RowCount Цикл
		
		Для Column = 1 По ColumnCount Цикл
			ТабличныйДокумент.Область("R" + Формат(Row, "ЧГ=") +"C" + Формат(Column, "ЧГ=")).Текст = ExcelЛист.Cells(Row,Column).Value;
		КонецЦикла;
		
	КонецЦикла;
	
	Excel.WorkBooks.Close();
	Excel = 0;
	
	Возврат Истина;
	
КонецФункции // ()

модуль формы 

Процедура КоманднаяПанель1Открыть(Кнопка)
	// Вставить содержимое обработчика.
	ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	ДиалогВыбора.Фильтр    = "Табличный документ (*.mxl)|*.mxl|Лист Excel (*.xls)|*.xls|Текстовый документ (*.txt)|*.txt|dBase III (*.dbf)|*.dbf|";
	Если ДиалогВыбора.Выбрать() Тогда
		ТабличныйДокумент = ЭлементыФормы.ТабличныйДокумент;
		ФайлНаДиске = Новый Файл(ДиалогВыбора.ПолноеИмяФайла);
		ИначеЕсли нРег(ФайлНаДиске.Расширение) = ".xls" Тогда
			ПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент,ДиалогВыбора.ПолноеИмяФайла);
		
		  	КонецЕсли;
КонецПроцедуры
Показать


Дальше что нужно сделать чтобы выбранный документ загрузился
14. starik-2005 1965 21.05.19 13:03 Сейчас в теме
(13) А какая платформа вообще? 8.2? И не совсем понятно, зачем читать эксель в модуле объекта.

А дальше с п.4 из (12) - цикл по количеству строк загруженной таблицы. Табличный документ при таком раскладе (загрузка из Excel через Ж... COM) не нужен вообще.
15. user1015647 21.05.19 13:21 Сейчас в теме
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Бизнес-архитектор 1С, ведущий консультант
Санкт-Петербург
Полный день

Руководитель проектов 1С
Санкт-Петербург
Полный день

Программист 1С
Краснодар
зарплата от 80 000 руб. до 160 000 руб.
Полный день

Консультант 1 С
Краснодар
зарплата от 50 000 руб. до 150 000 руб.
Полный день

Консультант-методолог 1С
Краснодар
зарплата от 110 000 руб.
Полный день