Чтение/Запись документа Excel 2007 без офиса, без внешних компонент. (с примером для 7.7, 8.1 и 8.2 на управляемых формах)

Опубликовал Василий Демидов (Душелов) в раздел Программирование - Практика программирования

Чтение/запись документ Excel 2007 без установленного Excel'а, без внешних компонент, исключительно средствами 1С (7.7, 8.1, 8.2 на управляемых формах).

Написано в ознакомительных целях, по аналогии с //infostart.ru/projects/2365/

Использование (1С 8.x): вставляете обработку в конфигурацию и используете ее методы:

Процедура ОткрытьФайлЭкзекль2007(ПутьКФайлу)
    Экзель = Обработки.Excel2007.Создать();
 
    Если НЕ Экзель.ОткрытьФайл(ПутьКФайлу) Тогда
        Предупреждение("Файл " + ПутьКФайлу + " не открыт!");
        Возврат;
    КонецЕсли;
 
    Если НЕ Экзель.ОткрытьЛист(1) Тогда
        Предупреждение("Лист 1 не открыт!");
        Возврат;
    КонецЕсли;
 
    Сообщить("Количество строк: " + Экзель.Лист.Количество());
    Сообщить("Количество колонок: " + Экзель.Лист.Колонки.Количество());
КонецПроцедуры

Процедура СоздатьФайлЭкзель2007(ПутьКФайлу)
    //заполняем ТЗ
    ТЗ = Новый ТаблицаЗначений;
    ТЗ.Колонки.Добавить("К1");
    ТЗ.Колонки.Добавить("К2");
 
    Стр = ТЗ.Добавить();
    Стр.К1 = "Номенклатура";
    Стр.К2 = "Количество";
 
    Стр = ТЗ.Добавить();
    Стр.К1 = "Хлеб";
    Стр.К2 = 10;
 
    Стр = ТЗ.Добавить();
    Стр.К1 = "Мясо";
    Стр.К2 = 14;
 
    //сохраняем тз в экзель
    Экзель = Обработки.Excel2007.Создать();
    Экзель.Лист = ТЗ;
    Экзель.Записать(ПутьКФайлу);
 
КонецПроцедуры

Использование (1С 7.7): добавляете из демо-базы все из глобального модуля в свой, файл шаблона кладете в папку с конфигурацией и используете по примеру:

Процедура ОткрытьФайлЭкзекль2007(ПутьКФайлу)
    Если экзель_ОткрытьФайл(ПутьКФайлу) = 0 Тогда
        Предупреждение("Файл " + ПутьКФайлу + " не открыт!");
        Возврат;
    КонецЕсли;
 
    Если экзель_ОткрытьЛист(1) = 0 Тогда
        Предупреждение("Лист 1 не открыт!");
        Возврат;
    КонецЕсли;
 
    Сообщить("Количество строк: " + экзель_Лист.КоличествоСтрок());
    Сообщить("Количество колонок: " + экзель_Лист.КоличествоКолонок());
    Сообщить("***");
 
    //выведем 1 строку
    Для сч = 1 По экзель_Лист.КоличествоКолонок() Цикл
        Сообщить(экзель_Лист.ПолучитьЗначение(1, сч));
    КонецЦикла;
КонецПроцедуры
//*******************************************
Процедура СоздатьФайлЭкзель2007(ПутьКФайлу)
    //заполняем ТЗ
    ТЗ = СоздатьОбъект("ТаблицаЗначений");
    ТЗ.НоваяКолонка("К1");
    ТЗ.НоваяКолонка("К2");
 
    ТЗ.НоваяСтрока();
    ТЗ.К1 = "Номенклатура";
    ТЗ.К2 = "Количество";
 
    ТЗ.НоваяСтрока();
    ТЗ.К1 = "Хлеб";
    ТЗ.К2 = 10;
 
    ТЗ.НоваяСтрока();
    ТЗ.К1 = "Мясо";
    ТЗ.К2 = 14;
 
    //сохраняем тз в экзель
    экзель_Лист = ТЗ;
    Если экзель_Записать(ПутьКФайлу) = 1 Тогда
        Сообщить("Создан " + ПутьКФайлу);
        ЗапуститьПриложение(ПутьКФайлу);
    КонецЕсли;
КонецПроцедуры

Скачать файлы

Наименование Файл Версия Размер
Обработка для 8.1 и 8.2
.zip 29,08Kb
20.01.10
2336
.zip 29,08Kb 2336 Бесплатно
Конфигурация для 1С 7.7
.1235567370 37,10Kb
25.09.09
850
.1235567370 37,10Kb 850 Бесплатно

См. также

Комментарии
1. Василий Демидов (Душелов) 3778 24.02.09 17:10 Сейчас в теме
Свойство "Лист" у обработки - это таблица значений.
2. Василий Демидов (Душелов) 3778 24.02.09 17:14 Сейчас в теме
Собственно код довольно прост, идея, думаю, ясна ;)
SonasLOL; +1 Ответить
3. Сергей Кучеров (СергейКа) 610 24.02.09 17:40 Сейчас в теме
+ адназначна. Идея супер.
4. Александр Шишкин (Шёпот теней) 1681 24.02.09 17:51 Сейчас в теме
Душелов... НУуу..., блин, ТЫ ДАёШЬ...

... жаль что пятьПлюсиков не могу поставить...


воОотВеДь...
5. Василий Демидов (Душелов) 3778 24.02.09 17:54 Сейчас в теме
Для 7-ки сделаю, наверное, вечером обработочку... Но сразу оговорюсь, понадобится либо ВК для архивирования, либо какой-либо архиватор, ибо сама платформа с зипами работать не умеет.
6. Александр Шишкин (Шёпот теней) 1681 24.02.09 17:56 Сейчас в теме
гы... уговорил... поставил в твоих других работах...

всё равно за всё заслуженно....!!! удачи во всём....!!!!

воооот....ведь....
7. Алексей Коробов (WiseSnake) 1721 24.02.09 17:59 Сейчас в теме
8. Сhe Burashka (CheBurator) 24.02.09 20:41 Сейчас в теме
> ибо сама платформа с зипами работать не умеет.
если считать, что работаем на хрюне и выше - то можно юзать встроенный в винды зиповщик
9. Василий Демидов (Душелов) 3778 24.02.09 20:45 Сейчас в теме
10. Сhe Burashka (CheBurator) 24.02.09 20:47 Сейчас в теме
встроенный!!! пошарь на мисте! там Абрахамс показывал ккак делать.. если не найдешь стукнись - у мну есть в загашнике где-то... просто ща работы срочная дофига
11. Сергей (СЫРОЖА) 25.02.09 07:20 Сейчас в теме
Не понял, причем тут архиватор? И вообще, если это только идея,
причем тут привязка к 2007-му экзелю?
12. Василий Демидов (Душелов) 3778 25.02.09 09:12 Сейчас в теме
(11) :))))) Мои "идеи" отличаются от "идей" некоторых других "коллег" по инфостарту.

А посмотреть разработку?
13. Сергей (seermak) 654 25.02.09 09:20 Сейчас в теме
Вопрос на расширение кругозора): 1.а зачем в шаблоне заполнено поле значением "aha". 2. а как сделать так, чтобы сохранилось форматирование(допустим объединение ячеек). Узнал много нового о ".xlsx". За это отдельное спасибо!)))
14. Василий Демидов (Душелов) 3778 25.02.09 09:29 Сейчас в теме
(13) 1. Да просто... Только, чтобы экзель создал все нужные файлы для шаблона, на всякий случай.
2. По поводу форматирования - это уже надо копать в сторону других файлов, отвечающих за оформление. Как я делаю - беру файл, объединяю, к примеру, ячейки, сохраняю и смотрю изменения.
15. Алексей Плутенко (Noy) 1054 25.02.09 09:29 Сейчас в теме
16. Василий Демидов (Душелов) 3778 25.02.09 09:46 Сейчас в теме
(15) Спасибо, я уже разобрался... ;)
Вот только метод Темп.CopyHere(Файл), открывает диалог и предлагает заменить файлы, если такие существуют. И на 2 параметр (8, 16 и т.д.) не реагирует никак. Но это я поборю :)
17. baa (baa) 25.02.09 10:00 Сейчас в теме
Душелов, я на тебя отдельную папку завел в каталоге для скачаных файлов 1С. Так сказать есть 7.7, есть 8.1 и есть отдельный проект "Душелов" :) Однозначно молодец.
18. Василий Демидов (Душелов) 3778 25.02.09 16:13 Сейчас в теме
Упарился я с вашей 7-кой... ;) Давно не писал ничего толкового...
Вообщем... В 7-ке тоже, никаких ВК.
19. Василий Демидов (Душелов) 3778 25.02.09 16:15 Сейчас в теме
Как бы глюки какие-то возможно в 7-ке, т.к. работа с архивами и xml тоже написаны на языке платформы (мисте привет ;)).
20. Трактор Трактор (Трактор) 1110 25.02.09 19:44 Сейчас в теме
Вах, молодец! Скачивать не стал. Просто буду знать что такая разработка есть.
21. Трактор Трактор (Трактор) 1110 25.02.09 22:36 Сейчас в теме
Не удержался. Скачал. Красиво. Спасибо.
22. Игорь Белышев (biv75) 26.02.09 14:36 Сейчас в теме
Супер! Плюсую однозначно
23. minimax (minimaxpo) 26.02.09 14:37 Сейчас в теме
Гут, мне нравится ход ваших мыслей.
24. Tregi (Vitalk) 03.03.09 14:50 Сейчас в теме
В принципе, хорошая вешь! Кому то да и пригодится!
Только небольшая помарочка в Excel2007. Когда пустой путь к файлу и при нажатии на "Открыть" пишет: Преобразование значения к типу Число не может быть выполнено ФайлЛиста = ВременныйКаталог + "\xl\worksheets\sheet" + НомерЛиста + ".xml". Просто не определена переменная "ВременныйКаталог"!
25. Alex P (alexmif) 17.04.09 12:14 Сейчас в теме
Скачал! Не удержался. Интересная мысль... Теперь не забыть куда скачал.
+ однозначно, хотя мона и +++++.
26. ac86 (Aleanza) 09.05.09 13:28 Сейчас в теме
Если есть пустое поле в таблице значений тип "Строка" оно глючит.
28. ac86 (Aleanza) 09.05.09 13:28 Сейчас в теме
29. ac86 (Aleanza) 09.05.09 13:34 Сейчас в теме
А еще оно не сохраняет заголовки, очень не удобно :(
30. Павел Городилов (bxz) 368 23.08.09 21:13 Сейчас в теме
Возникла проблема при записи таблицы значений с количеством строк больше 999 решилась заменой функции ПолучитьИмяСтроки(а) на:
Функция ПолучитьИмяСтроки(а)
Возврат Формат(а + 1,"ЧГ=");
КонецФункции
но это все не важно )) за идею ++++++++
31. dushelov (Душелов) 20.01.10 12:34 Сейчас в теме
(26), (30) поправил

Добавил версию для 8.2 на управляемых формах для тонкого клиента.
32. Руслан Батршин (RuslanBZ) 10.03.10 13:50 Сейчас в теме
В версии 8.2 при нажатии на открыть ругается в функции ОткрытьЛист(НомерЛиста)

{ВнешняяОбработка.Excel2007.МодульОбъекта(64)}: Значение не является значением объектного типа (Строки)
Для Каждого Стр Из Колонки.Строки Цикл
33. Андрей Д. (detec) 122 25.05.10 11:02 Сейчас в теме
Идея очень красивая. Но для произвольных файлов, редактируемых пользователями, я бы не советовал. Взял 3 файла. Два выгружены из PL/SQL Developer, один сделан из пользовательского в Office 2010. В результате открылся только 1. Остальные ругнулись .

{ВнешняяОбработка.Excel2007(63)}: Значение не является значением объектного типа (Строки)
Для сч = 0 По Колонки.Строки.Количество() - 1 Цикл


{ВнешняяОбработка.Excel2007(93)}: Поле объекта не обнаружено (F)
НоваяСтрока[МассивБукв[ИндексСтроки]] = ЗначениеЯчейки;


34. ntl 31.05.10 18:32 Сейчас в теме
При сохранении ТЗ в которой были пустые ячейки, обработка выдает ошибку.

{ВнешняяОбработка.Excel2007(266)}: Ошибка при вызове метода контекста (Индекс): Несоответствие типов (параметр номер '1')
ЗначЯчейки = СписокСтрок.Индекс(Элем);
по причине:
Несоответствие типов (параметр номер '1')
35. ntl 31.05.10 20:41 Сейчас в теме
Не помогло. Все равно дает ошибку:
{ВнешняяОбработка.Excel2007(266)}: Ошибка при вызове метода контекста (Индекс): Несоответствие типов (параметр номер '1')
ЗначЯчейки = СписокСтрок.Индекс(Элем);
по причине:
Несоответствие типов (параметр номер '1')
36. ntl 31.05.10 20:59 Сейчас в теме
Интересный момент. Пробую сохранить ТЗ размером 14 на 710 ячеек.
1. Выдает ошибки при пустых ячейках. Если ячейка не текст, а большое поле типа Memo.
2. Где то с 283 строки в ячейки начинает подставлять числа, начиная с 1000. и пошел часть ячеек записывает нормально а потом оп и 1001, часть ячеек нормально, 1002 и т д.
Хотя вторая ошибка это возможно результат исправления первой ) Такой я программист )))
37. ntl 31.05.10 21:27 Сейчас в теме
Да так и есть ошибка №2 из п. (36) это результат моих фокусов.
Но 2 момента остались:
1. Если есть пустое большое поле, то она выдает ошибку
2. Дата при открытии получается в формате DD.MM. YYYY обрезается. При этом если стр.252: ЗначЯчейки = Лист.Получить(иСтр).Получить(иКол); заменить на ЗначЯчейки = Строка(Лист.Получить(иСтр).Получить(иКол)); то эта ошибка решается. Но появляются другие :)
Не подумайте что я жалуюсь. Идея супер. Буду искать причины и править. Но если кто быстрее меня сообразит, дайте знать. т.к. искать я могу очень долго )))
38. Александр Цегельников (markers) 186 17.06.10 08:00 Сейчас в теме
Подтверждаю проблему с "сдвигом" ячеек при наличии пустых ячеек, решил её по своему, но потом полез сюда, и заменил всё на новый код, начал матюгатся как в (33) Вернул старый код с своей правкой, Автору боооольшое спасибо! Надеюсь когда вернётся сможет нам помочь.

ADD: Кстати старый код работает нормально и быстро, интересно, новый код быстрей?
39. Александр Цегельников (markers) 186 17.06.10 09:03 Сейчас в теме
Кому нужно получить список листов и кто не догадался как это сделать, даю функцию:
Функция Excel2007СписокЛистов(ВременныйКаталог);
	Листы = НайтиФайлы(ВременныйКаталог + "\xl\worksheets\", "sheet*.xml");
	Возврат Листы.Количество();
КонецФункции	

40. dushelov (Душелов) 17.06.10 11:51 Сейчас в теме
Выложите сюда проблемный файл, посмотрим.
41. Александр Цегельников (markers) 186 17.06.10 12:30 Сейчас в теме
(40) Ловите, простой прайс правда сделанный в 2003-ем и сконвертированный в 2007-й
Там 3 листа, 2-й пустой, в моём варианте они обрабатываются все вместе
Прикрепленные файлы:
price_test.xlsx
42. Александр Цегельников (markers) 186 22.06.10 06:00 Сейчас в теме
43. Игорь Степанов (webstep) 8 25.06.10 17:55 Сейчас в теме
если в файле excel данные не стоят стройными рядами, а "гуляют" по полю, то при работе алгоритма возникает ошибка потому что "мелкософтмасдай" почему то в "cols" пишет не все колонки. Пришлось ориентироваться на "dimension". Соответственно в функции ОткрытьЛист заменил код
//создаем колонки
Колонки = ДеревоДанных.Строки.Найти("cols", "Объект", Истина);
сч = 0;	
Для Каждого Стр Из Колонки.Строки Цикл
 Если Стр.Объект <> "col" Тогда
 Продолжить;
 КонецЕсли;
		
 Лист.Колонки.Добавить(МассивБукв[сч]);
 сч = сч + 1;
 КонецЦикла;
...Показать Скрыть

на
//создаем колонки
Колонки = ДеревоДанных.Строки.Найти("dimension", "Объект", Истина);
Счетчик = 0;	
Для Каждого Стр Из Колонки.Строки Цикл
 Если Стр.Объект = "ref" Тогда
 Диапозон = Стр.Значение; 
 //поиск максимального значения колонки
 Счетчик=МассивБукв.Количество();
 Пока Счетчик>0 Цикл 
 Счетчик = Счетчик - 1;
 Если Найти(Диапозон, МассивБукв[Счетчик])>0 Тогда
 Для Индекс=0 По Счетчик Цикл					
 Лист.Колонки.Добавить(МассивБукв[Индекс]);
 КонецЦикла;	
 Счетчик = 0;
 КонецЕсли;	
 КонецЦикла;
 Прервать;
 КонецЕсли;
КонецЦикла;
...Показать Скрыть

теперь колонки формирует правильно.
44. Игорь Степанов (webstep) 8 28.06.10 11:34 Сейчас в теме
проблема сдвига ячеек...

удалил
ИндексСтроки = -1;

и, ориентируясь на значение в "r", заменил:
ИндексСтроки = ИндексСтроки + 1;

на
 //поиск колонки
 СтрЗначение = Колонка.Строки.Найти("r", "Объект");
 Если СтрЗначение <> Неопределено Тогда
 ИмяКолонки = СтрЗначение.Значение;
 КонецЕсли;
 ИндексСтроки = Неопределено;
 Счетчик = МассивБукв.Количество();
 Пока Счетчик>0 Цикл 
 Счетчик = Счетчик - 1;
 Если Найти(ИмяКолонки, МассивБукв[Счетчик])>0 Тогда
 ИндексСтроки = Счетчик;
 Счетчик = 0;
 КонецЕсли;	
 КонецЦикла;
.........................
...Показать Скрыть

проблема решена

extralook; gluker3; +2 Ответить
45. Игорь Степанов (webstep) 8 28.06.10 11:38 Сейчас в теме
да, все это в функции ОткрытьЛист модуля обработки

прошу не пинать ногами - на больших таблицах код может работать медленно, но это уже менять МассивБукв на что-то иное...

и вот еще что... обработка благодаря этому самому массиву букв расчитана на не очень большие таблицы, но я на всякий случай предусмотрел его расширение и на двухбуквенные колонки, поэтому поиск ведется от конца к началу, а не наоборот.

кстати, как здесь можно свой комментарий удалить? вот еще проблема...
46. Игорь Степанов (webstep) 8 28.06.10 12:34 Сейчас в теме
Прошу прощения автора, я на основании его обработки создал для себя функцию, которая читает лист из файла и возвращает таблицу значений.

Функция ПолучитьЛистEXCEL_XML(ИмяФайлаExcel, НомерЛиста=1) Экспорт
	
	ИмяФайла = СокрЛП(ИмяФайлаExcel);
	Если Прав(НРег(ИмяФайла),4)<>".xlsx" Тогда 
		//ошибка
	КонецЕсли;
	
	пФайл = Новый Файл(ИмяФайла);
	Если Не пФайл.Существует() Тогда
		//ошибка
	КонецЕсли;
	
	СписокСтрок = Новый СписокЗначений;
	
	ВременныйКаталог = КаталогВременныхФайлов() + "NightReg";
	УдалитьФайлы(ВременныйКаталог);
	
	Зип = Новый ЧтениеZipФайла;
	Зип.Открыть(ИмяФайла);
	Зип.ИзвлечьВсе(ВременныйКаталог, РежимВосстановленияПутейФайловZIP.Восстанавливать);
	
	ФайлСтрок = ВременныйКаталог + "\xl\sharedStrings.xml";
	
	хмл = Новый ЧтениеXML;
	хмл.ОткрытьФайл(ФайлСтрок);
	
	Пока хмл.Прочитать() Цикл
		Если хмл.ТипУзла = ТипУзлаXML.Текст Тогда
			СписокСтрок.Добавить(хмл.Значение);
		КонецЕсли;
	КонецЦикла;
	
	хмл.Закрыть();
	
	ФайлЛиста = ВременныйКаталог + "\xl\worksheets\sheet"+НомерЛиста+".xml";
	Файл = Новый Файл(ФайлЛиста);
	Если НЕ Файл.Существует() Тогда
		//ошибка
	КонецЕсли;
	
	МассивБукв = Новый Массив;
	МассивБукв.Добавить("A");
	МассивБукв.Добавить("B");
	МассивБукв.Добавить("C");
	МассивБукв.Добавить("D");
	МассивБукв.Добавить("E");
	МассивБукв.Добавить("F");
	МассивБукв.Добавить("G");
	МассивБукв.Добавить("H");
	МассивБукв.Добавить("I");
	МассивБукв.Добавить("J");
	МассивБукв.Добавить("K");
	МассивБукв.Добавить("L");
	МассивБукв.Добавить("M");
	МассивБукв.Добавить("N");
	МассивБукв.Добавить("O");
	МассивБукв.Добавить("P");
	МассивБукв.Добавить("Q");
	МассивБукв.Добавить("R");
	МассивБукв.Добавить("S");
	МассивБукв.Добавить("T");
	МассивБукв.Добавить("U");
	МассивБукв.Добавить("V");
	МассивБукв.Добавить("W");
	МассивБукв.Добавить("X");
	МассивБукв.Добавить("Y");
	МассивБукв.Добавить("Z"); 
	//здесь можно расширить двухбуквенными значениями
	
	ДеревоДанных = Новый ДеревоЗначений;
	ДеревоДанных.Колонки.Добавить("Объект");
	ДеревоДанных.Колонки.Добавить("Значение");
	
	ЧтениеXML = Новый ЧтениеXML;
	ЧтениеXML.ОткрытьФайл(Файл);
	
	ТекЭлемент = Неопределено;
	ТекБаза = Неопределено;
	
	Пока ЧтениеXML.Прочитать() Цикл
		Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
			РежимЗагрузки = ЧтениеXML.Имя;
			
			Если ТекЭлемент = Неопределено Тогда
				ТекЭлемент = ДеревоДанных.Строки.Добавить();
				ТекЭлемент.Объект = РежимЗагрузки;
			Иначе
				ТекЭлемент = ТекЭлемент.Строки.Добавить();
				ТекЭлемент.Объект = РежимЗагрузки;					
			КонецЕсли;
			
		ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
			Если ТекЭлемент = Неопределено Тогда
				ТекЭлемент = Неопределено;
			Иначе
				ТекЭлемент = ТекЭлемент.Родитель;
			КонецЕсли;
		ИначеЕсли ЧтениеXML.ТипУзла = ТипУзлаXML.Текст Тогда
			ТекЭлемент.Значение = ЧтениеXML.Значение;
		КонецЕсли;
		
		Для сч = 0 По ЧтениеXML.КоличествоАтрибутов() - 1 Цикл
			Стр = ТекЭлемент.Строки.Добавить();
			Стр.Объект = ЧтениеXML.ИмяАтрибута(сч);
			Стр.Значение = ЧтениеXML.ЗначениеАтрибута(сч);
		КонецЦикла;
	КонецЦикла;
	
	ЧтениеXML.Закрыть();
	
	Лист = Новый ТаблицаЗначений;
	
	//создаем колонки
	Колонки = ДеревоДанных.Строки.Найти("dimension", "Объект", Истина);
	Счетчик = 0;	
	Для Каждого Стр Из Колонки.Строки Цикл
		Если Стр.Объект = "ref" Тогда
			Диапазон = Стр.Значение; 
			
			//поиск максимального значения колонки
			Счетчик=МассивБукв.Количество();
			Пока Счетчик>0 Цикл 
				Счетчик = Счетчик - 1;
				Если Найти(Диапазон, МассивБукв[Счетчик])>0 Тогда
					Для Индекс=0 По Счетчик Цикл					
						Лист.Колонки.Добавить(МассивБукв[Индекс]);
					КонецЦикла;	
					Счетчик = 0;
				КонецЕсли;	
			КонецЦикла;
			
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	//читаем строки
	СтрСтрок = ДеревоДанных.Строки.Найти("sheetData", "Объект", Истина);
	Для Каждого Строка Из СтрСтрок.Строки Цикл
		НоваяСтрока = Лист.Добавить();
		
		Для Каждого Колонка Из Строка.Строки Цикл
			Если Колонка.Объект <> "c" Тогда
				Продолжить;
			КонецЕсли;
			
			//поиск колонки
			СтрЗначение = Колонка.Строки.Найти("r", "Объект");
			Если СтрЗначение <> Неопределено Тогда
				ИмяКолонки = СтрЗначение.Значение;
			КонецЕсли;
			ИндексСтроки = Неопределено;
			Счетчик = МассивБукв.Количество();
			Пока Счетчик>0 Цикл 
				Счетчик = Счетчик - 1;
				Если Найти(ИмяКолонки, МассивБукв[Счетчик])>0 Тогда
					ИндексСтроки = Счетчик;
					Счетчик = 0;
				КонецЕсли;	
			КонецЦикла;
			
			ЗначениеЯчейки = Неопределено;
			
			СтрЗначение = Колонка.Строки.Найти("v", "Объект");
			Если СтрЗначение <> Неопределено Тогда
				ЗначениеЯчейки = СтрЗначение.Значение;
			КонецЕсли;
			
			СтрЗначение = Колонка.Строки.Найти("t", "Объект");
			Если СтрЗначение <> Неопределено И СтрЗначение.Значение = "s" И ЗначениеЯчейки <> Неопределено Тогда
				ЗначениеЯчейки = СписокСтрок.Получить(Число(ЗначениеЯчейки)).Значение;
			КонецЕсли;
			
			НоваяСтрока[МассивБукв[ИндексСтроки]] = ЗначениеЯчейки;
		КонецЦикла;
	КонецЦикла;
	
	Возврат Лист;
КонецФункции
...Показать Скрыть
kazann; artbear; +2 Ответить
47. Игорь Степанов (webstep) 8 28.06.10 17:36 Сейчас в теме
да вот еще что до меня дошло - пустые строки тоже исчезают, нужно еще думать... впрочем для многих это не будет такой уж потерей :)

и еще у меня в коде (46) тоже закралась ошибочка:
Если Прав(НРег(ИмяФайла),4)<>".xlsx" Тогда 

тут циферку 5 надо :oops:
48. Артур Аюханов (artbear) 851 27.09.10 13:39 Сейчас в теме
(31) Вчера скачал версию для 8.1
В нем (26) "Если есть пустое поле в таблице значений тип "Строка" оно глючит." так и не исправлено.
49. Артур Аюханов (artbear) 851 27.09.10 14:03 Сейчас в теме
Также есть ошибка при записи листа, если у числа в таблице есть дробная часть :(
Запись проходит успешно, но при попытке открыть полученный файл в Офис 2007 выдается ошибка о невозможности открытия :(
Проблема в том, что число выгружается в формате через запятую :(
а нужно через точку.

ЗЫ или это зависит от региональных установок? вроде они у меня штатные как для Офиса, так и для 1С
50. Артур Аюханов (artbear) 851 27.09.10 14:38 Сейчас в теме
(49) + Исправление
В методе ЗаписатьДанныеЛиста(хмл)

нужно поправить код
	Попытка
		А = Число(ЗначЯчейки);
		ЭтоЧисло = Истина;
	Исключение
...Показать Скрыть
на код
	Попытка
		А = Число(ЗначЯчейки);
		ЭтоЧисло = Истина;
		ЗначЯчейки = СтрЗаменить(Формат(А, "ЧРД=."), Символы.НПП, ""); // Артур
	Исключение
...Показать Скрыть

ЗЫ кстати, приведенный код решает проблему неверного сохранения чисел более 999, при сохранении в строку в которых появляется неразрывный пробел.
При открытии подобного файла в Офис 2007 также будет ошибка открытия :(
51. Артур Аюханов (artbear) 851 30.09.10 07:50 Сейчас в теме
Проблема из (30) по записи файла с количеством строк более 999 также не решена :(
для ее исправления нужно исправить код модуля
1. завести новую функцию
Функция ЧислоВСтроку(значениеЧисла) // Артур для исключения ошибок открытия файлов
Возврат СокрЛП(Формат(значениеЧисла, "ЧРД=.; ЧГ="));
КонецФункции
2. прописать ее использование
а) хмл.ЗаписатьАтрибут("spans", "1:" + ЧислоВСтроку(ЧислоСтрок)); // вместо хмл.ЗаписатьАтрибут("spans", "1:" + ЧислоСтрок);
б) хмл.ЗаписатьАтрибут("count", ЧислоВСтроку(Строки.Количество())); // Артур вместо //Строка(Строки.Количество())
хмл.ЗаписатьАтрибут("uniqueCount", ЧислоВСтроку(Строки.Количество())); // Артур вместо //Строка(Строки.Количество())

Прикрепил готовый файл для 8.1 с моими правками + дополнения от webstep
Прикрепленные файлы:
Excel2007_v81.epf
52. Роман Лиль (Lalei2008) 28.10.10 17:16 Сейчас в теме
54. Юрий Португалов (Sprite) 471 04.02.12 16:25 Сейчас в теме
Загружаю демо-конфигурацию 7.7

Получаю сообщение:
Папка=Шел.namespace(Архив+"\"+Путь);
{Глобальный модуль(365)}: Плохой тип переменной

Help me!!!
55. Юрий Зайцев (Yury1001) 1449 07.02.12 17:32 Сейчас в теме
Рановато плюсанул пример 7.7 нерабочий: плохой тип переменной стр. 363

Папка=Шел.namespace(Архив+"\"+Путь);

Архив = "D:\DataBase\Джигель\ЧтениеЗаписьExcel\Excel2007\Template.zip"
Путь = "D:\DataBase\Джигель\ЧтениеЗаписьExcel\Excel2007\Template.zip\_rels"
Архив+"\"+Путь = "D:\DataBase\Джигель\ЧтениеЗаписьExcel\Excel2007\Template.zip\D:\DataBase\Джигель\ЧтениеЗаписьExcel\Excel2007\Template.zip\_rels"

поправил, теперь плохой тип 404

ПутьФайла = "D:\DataBase\Джигель\ЧтениеЗаписьExcel\Excel2007\Template.zip\[Content_Types].xml"

чё к чему не пойму.
56. Юрий Зайцев (Yury1001) 1449 07.02.12 17:34 Сейчас в теме
(0) Вопросик в догонку: нужно выгрузить большой объем данных в excel 90 000 строк и штук 10 колонок, этим методом получится?
57. amatisol amatisol (amatisol) 25.03.12 22:43 Сейчас в теме
Народ а че реально работает? А то сидят многие на openoffice и хотят чтоб у них ексели открывались нормально, если реально работает то плюсау и скачаю
58. Andrey Dyak (electronik) 07.05.12 14:00 Сейчас в теме
В принципе, хорошая вешь нужная! С екзелем работаем если не все то через одного, поетому актуальность даного потрясающая. На основании даной разработки создал свою и что самое интерсное работает. Автору респект и уважение ну и заслуженое 5+++++
59. lesorubka (lesorubka) 18 23.07.12 11:58 Сейчас в теме
Спасибо автору! Отлично работает! Жаль ушел от нас, столько бы еще сделал.
Царствие ему Небесное!!!
Istur; rybamech; +2 Ответить
60. Алекс Ю (AlexO) 115 10.10.12 18:00 Сейчас в теме
(57) amatisol,
это создание текстовых XML-ек и упаковка их в zip.
Более ранние версии файлов Excel так создать не удастся.
61. Npoen Dzogchen (Dansur) 261 18.10.12 10:58 Сейчас в теме
Ему еще много лет будут говорить спасибо. жаль что он это уже не услышит. Покойся с миром.
62. nnurik (nnurik) 08.02.13 11:00 Сейчас в теме
Спасибо автору! Очень пригодилось.
63. Максим Евсенкин (tehas) 39 13.02.13 12:47 Сейчас в теме
{ВнешняяОбработка.Excel2007.МодульОбъекта(119)}: Поле объекта не обнаружено (K)
НоваяСтрока[МассивБукв[ИндексСтроки]] = ЗначениеЯчейки;

файл (прайс 1С пересохранен в xlsx)
Прикрепленные файлы:
PRICE_1C.xlsx
64. Иван Т (Spartan) 300 29.03.13 10:51 Сейчас в теме
(26),(48) Как-то так видимо:
Функция ПрочитатьСписокСтрок(ФайлСтрок)
	Строки = Новый СписокЗначений;
	
	хмл = Новый ЧтениеXML;
	хмл.ОткрытьФайл(ФайлСтрок);
	
	Пока хмл.Прочитать() Цикл
		//Если хмл.ТипУзла = ТипУзлаXML.Текст Тогда  // некорректно работает для пустых строк!!!
		//	Строки.Добавить(хмл.Значение);
		//КонецЕсли;
		// Spartan - 29.03.2013 - начало
		Если хмл.Имя = "t" И хмл.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
			Если хмл.Прочитать() И хмл.Имя = "#text" Тогда
				Строки.Добавить(хмл.Значение);
			Иначе
				Строки.Добавить("");
			КонецЕсли; 
		КонецЕсли;
		// Spartan - 29.03.2013 - конец
	КонецЦикла;
	
	хмл.Закрыть();
	
	Возврат Строки;
КонецФункции
...Показать Скрыть
65. mozz mozz (mozz) 144 30.04.13 13:22 Сейчас в теме
(64) Туда же:
(уже встроены багфиксы из (51) )
Процедура ЗаписатьДанныеЛиста(хмл)
	ЧислоСтрок = Лист.Количество();
	ЧислоКолонок = Лист.Колонки.Количество();
	
	Для иСтр = 0 По ЧислоСтрок - 1 Цикл
		хмл.ЗаписатьНачалоЭлемента("row");
		хмл.ЗаписатьАтрибут("r", ПолучитьИмяСтроки(иСтр));
		хмл.ЗаписатьАтрибут("spans", "1:" + ЧислоВСтроку(ЧислоСтрок)); // вместо хмл.ЗаписатьАтрибут("spans", "1:" + ЧислоСтрок); 
		
		Для иКол = 0 По ЧислоКолонок - 1 Цикл
			хмл.ЗаписатьНачалоЭлемента("c");
			хмл.ЗаписатьАтрибут("r", ПолучитьОбласть(иСтр, иКол));
			
			ЗначЯчейки = Лист.Получить(иСтр).Получить(иКол);
			Попытка
				А = Число(ЗначЯчейки);
				ЭтоЧисло = Истина;
				ЗначЯчейки = СтрЗаменить(Формат(А, "ЧРД=."), Символы.НПП, ""); // Артур
			Исключение
				ЭтоЧисло = Ложь;
			КонецПопытки;
			
			Т = ТипЗнч(ЗначЯчейки);
			Если НЕ ЭтоЧисло И ТипЗнч(ЗначЯчейки) = Тип("Строка") Тогда
				Если НЕ ЗначЯчейки = "" тогда // mozz 30.04.2013 (здесь вываливалось на пустых ячейках)
					хмл.ЗаписатьАтрибут("t", "s");
					Элем = СписокСтрок.НайтиПоЗначению(ЗначЯчейки);
					ЗначЯчейки = СписокСтрок.Индекс(Элем);
				КонецЕсли; // mozz 30.04.2013
			КонецЕсли;
			
			хмл.ЗаписатьНачалоЭлемента("v");
			хмл.ЗаписатьТекст(Строка(ЗначЯчейки));
			хмл.ЗаписатьКонецЭлемента();
			
			хмл.ЗаписатьКонецЭлемента();
		КонецЦикла;
		
		хмл.ЗаписатьКонецЭлемента();
	КонецЦикла;
КонецПроцедуры
...Показать Скрыть
66. mozz mozz (mozz) 144 07.05.13 13:44 Сейчас в теме
(63) tehas,

в функции:
Функция ОткрытьЛист(НомерЛиста) Экспорт
найди:
НоваяСтрока[МассивБукв[ИндексСтроки]] = ЗначениеЯчейки;


замени на:

Если Лист.Колонки.Найти(МассивБукв[ИндексСтроки]) = Неопределено тогда
				Лист.Колонки.Добавить(МассивБукв[ИндексСтроки]);
			КонецЕсли;
			  
			НоваяСтрока[МассивБукв[ИндексСтроки]] = ЗначениеЯчейки;
...Показать Скрыть


и все взлетит!
67. 1cSupport - третий (Зеленоград) 04.09.13 11:35 Сейчас в теме
Спасибо, Мастер! Покойся с миром!
68. 1cSupport - третий (Зеленоград) 05.09.13 13:27 Сейчас в теме
Спасибо, Мастер! Покойся с миром!



Коллеги, сайт автора перестал открываться. Там, как минимум, были полезные разработки.

Есть ли необходимость и возможность сохранения ценных ресурсов в подобных случаях, кроме archive.org?
Отвечайте или здесь, или в личку. Если это важно многим - будем думать, как реализовать.
69. Макас (makas) 41 27.09.13 12:34 Сейчас в теме
ОткрытьФайлЭкзекль2007


может быть ОткрытьФайлЭкзель2007 ?
70. Александр Лобачёв (SANILLA) 05.10.13 03:36 Сейчас в теме
да ну на фик, не уже ли, так и есть, щас попробую, если работает, то точно то что надо. Благодарю!
71. Александр Лобачёв (Myskyl) 05.10.13 03:39 Сейчас в теме
да да то что и искал, как раз нужен был пример работы с Экселем, а тут и ещё без всяких врешних компонент, супер, спасибо
72. Илья Быстров (host_kms) 123 10.10.13 08:55 Сейчас в теме
Папка=Шел.namespace(Архив+"\"+Путь);
{Глобальный модуль(365)}: Плохой тип переменной

Кто-нибудь решил эту проблему?
73. mukoza (mukoza) 12.12.13 10:18 Сейчас в теме
Поддерживаю предыдущий вопрос. Неужели у ни у кого не возникает подобной ошибки?
74. Григорий Усольцев (ugn-omsk) 15.03.15 18:17 Сейчас в теме
Папка=Шел.namespace(Архив+"\"+Путь);
{Глобальный модуль(365)}: Плохой тип переменной

Ошибка возникает на Windows7, в XP все работает "из коробки".
На 7-ке видимо по-другому работает namespace в javascript.
Вобщем, глубоко не ковырял, ибо нет времени.
Обошел проблему очень тупо, ибо не программист.
Просто "подрезал" местами длинные пути до их нужного значения.
Например, переменная Архив принимает значение X:\Путь_к_БД\Template.zip
а переменная Путь должна принять значение xl\workbook.xml (и не только его, а всю структуру внутри архива). Но в Win7 переменная Путь принимает значение X:\Путь_к_БД\Template.zip\xl\workbook.xml
На выходе получаем Архив+"\"+Путь = X:\Путь_к_БД\Template.zip\X:\Путь_к_БД\Template.zip\xl\workbook.xml
Конечно, это будет "плохой тип переменной" )))

Вот рабочий вариант - просто замените текст функции в глобальном модуле.

//*******************************************
Функция архив_ПросмотрРекурс(Архив,Путь="",Сп)
// Функция просматривает содержимое файла Template.zip
// по всем вложенным папкам,
// и заполняет список путями ко всем файлам и папкам



// Исправляем некорректную работу с путями в Windows7
Если Путь <> "" Тогда
Путь=СтрЗаменить(Путь, Архив,""); // Убираем в переменной путь то, что уже записано в переменной Архив (дублирование)
Если Сред(Путь,1,1)="\" Тогда
Путь=Сред(Путь,2); // Если первым символом в пути является разделитель \, то его тоже уберем
КонецЕсли;
КонецЕсли;


Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
Скрипт.language="javascript";
Шел=СоздатьОбъект("shell.application");

//Сообщить(Архив+""+Путь);
//Сообщить("Архив: "+Архив);
//Сообщить("Путь: "+Путь);
//Сообщить("-----------------------------------------");




Папка=Шел.namespace(Архив+""+Путь);
Скрипт.AddObject("Папка",Папка);
Вложения=Скрипт.Eval("new Enumerator(Папка.Items())");
Пока Вложения.atEnd(0)=0 Цикл

// Таже беда под Win 7. Будем "резать" длиные пути, используя промежуточную переменную //ПутьДляДобавления
ПутьДляДобавления=СтрЗаменить(Вложения.item(0).path,Архив,"");
Если Сред(ПутьДляДобавления,1,1)="\" Тогда
ПутьДляДобавления=Сред(ПутьДляДобавления,2);
КонецЕсли;
//Сп.ДобавитьЗначение(Вложения.item(0).path);
Сп.ДобавитьЗначение(ПутьДляДобавления);

//Сообщить("Добавлено в список: "+ Строка(Вложения.item(0).path));
Если Вложения.item(0).IsFolder=-1 Тогда
архив_ПросмотрРекурс(Архив,Вложения.item(0).path,Сп);
КонецЕсли;
Вложения.moveNext(0);
КонецЦикла;
КонецФункции
//*******************************************
...Показать Скрыть


Если, кто из программистов, сделает решение этой проблемы элегантнее - большой респект ему!
А пока вот так, коряво, зато работает!
Надеюсь, кому-то поможет.
75. Григорий Усольцев (ugn-omsk) 15.03.15 18:31 Сейчас в теме
(55) Yury1001,
Вы пошли тем же путем, что и я.

поправил, теперь плохой тип 404

ПутьФайла = "D:\DataBase\Джигель\ЧтениеЗаписьExcel\Excel2007\Template.zip\[Content_Types].xml"


Здесь нужно добиться, чтобы
ПутьФайла = "D:\DataBase\Джигель\ЧтениеЗаписьExcel\Excel2007\Template.zip\[Content_Types].xml",
т.е. просто [Content_Types].xml
Постом выше привел код. Понимаю, что уже давно неактуально, но если вдруг на будущее кому-то пригодится.
Потому как идея действительно очень интересная!
76. Дмитрий Самончик (Пикачу) 28.04.15 17:38 Сейчас в теме
7.7 такое не понимает:

Пока Вложения.atEnd<a rel="noindex,nofollow"...

Это код для 8?
А можно для 7.7?
77. sai_ NT (sai_NT) 19.01.16 17:57 Сейчас в теме
(76) Пикачу, Там скопированы стили с кодом html, правильно так:
Пока Вложения.atEnd(0)=0 Цикл
...


и так далее, то есть смело удаляй тег а, оставив только текст: <a hrеf=...>бла-бла</a> -> бла-бла