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

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. zarankony 304 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. zarankony 304 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. zarankony 304 21.05.19 08:53 Сейчас в теме
(6)а производительность считывания через com? миллион вы в любом случае не дождетесь, плюс можете нехватку памяти схватить. десятки тысяч строк таким методом читал, сотни не попадались.
starik-2005; +1 Ответить
7. user1015647 21.05.19 06:20 Сейчас в теме
(5)мне в обычной форме нужно .
Вот задача.
Создать загрузку прайса из MS Excel.

Выбираем файл Excel — Прайс, файл «Прайс» в приложении;
Выбираем тип цены который будем загружать;
Должна быть галка создавать номенклатуру, которая не найдена (стоит — создавать, не стоит — не создавать);
Пример прайса в приложении. Колонки будут оставаться неизменными;
Обработка при необходимости создаёт номенклатуру и всегда создаёт документ «Установка цен номенклатуры».
9. zarankony 304 21.05.19 08:55 Сейчас в теме
(7) в обычной форме ещё проще, файл на сервер передавать не надо, сразу ТабличныйДокумент.Прочитать() и в путь.
10. user1015647 21.05.19 08:56 Сейчас в теме
(7)т.е в обычном приложении ,не в упр
11. zarankony 304 21.05.19 08:57 Сейчас в теме
12. starik-2005 3033 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 3033 21.05.19 13:03 Сейчас в теме
(13) А какая платформа вообще? 8.2? И не совсем понятно, зачем читать эксель в модуле объекта.

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

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)

Программист 1С
Москва
зарплата от 250 000 руб.
Полный день

Программист 1C
Волгоград
зарплата от 200 000 руб.
Полный день

Аналитик
Санкт-Петербург
зарплата от 200 000 руб. до 250 000 руб.
Полный день