Честно говоря, это не столько публикация, сколько антисклерозник для меня самого. Вот как Трактор делает — собрал свои наработки, укомпоновал и выложил, удобно отовсюду доставать. А поскольку я этот блок свой уже пару раз про…любил и заново написал, то во избежание — пусть будет таким образом. Как говорится, «в копипасте — щастье».
// Внимание! Исходная таблица тДанных должна содержать только данные простых типов!!!
Процедура БыстроВывестиТаблицуЗначенийВExcel(тДанных,рПутьИмяФайла,рОткрыватьДляПросмотра=Ложь) Экспорт
Попытка
Если тДанных.Количество()=0 Или ПустаяСтрока(рПутьИмяФайла) Тогда Возврат КонецЕсли;
// если таблица для экселя спецслужебная, то выводим в двумерный массив, и теперь уже знаем его размеры
квоКолонокДЭ=тДанных.Колонки.Количество();
квоСтрокДЭ=тДанных.Количество()+1; // припуск на заголовок
РезДокумент=Новый Массив(квоКолонокДЭ,квоСтрокДЭ);
// заголовки
мКолонокДат=Новый Массив;
Для итерКолонок=1 По квоКолонокДЭ Цикл
кол=тДанных.Колонки[итерКолонок—1];
РезДокумент[итерКолонок—1][0]=кол.Заголовок;
Если кол.ТипЗначения.СодержитТип(Тип(«Дата»)) Тогда мКолонокДат.Добавить(кол.Имя) КонецЕсли;
КонецЦикла;
// основные данные
квоиз=» из «+СокрЛП(квоСтрокДЭ—1);
Для й=0 По квоСтрокДЭ—2 Цикл
#Если Клиент Тогда
ОбработкаПрерыванияПользователя();
Состояние(«Вывод в Excel: «+Строка(й+1)+квоиз);
#КонецЕсли
стро=тДанных.Получить(й);
Для итерКолонок=1 По квоКолонокДЭ Цикл
знч=стро[итерКолонок—1];
Если мКолонокДат.Найти(тДанных.Колонки[итерКолонок—1])<>Неопределено Тогда
// выгрузка в эксель через COMSafeArray не понимает совсем пустые даты, поэтому надо это учесть!!!
знч=?(ЗначениеЗаполнено(знч),знч,Дата(1900,1,1));
КонецЕсли;
РезДокумент[итерКолонок—1][й+1]=знч;
КонецЦикла;
КонецЦикла;
// сохраняем все в произвольный тип, подробнее см. типизацию в описании конструктора «По типу элемента 1»
рТипМассива=«VT_VARIANT»;
рМассив=Новый COMSafeArray(РезДокумент,рТипМассива,квоКолонокДЭ,квоСтрокДЭ);
Ексель=Новый COMОбъект(«Excel.Application»);
Книга=Ексель.Workbooks.Add();
Если Книга.WorkSheets.Count=0 Тогда
Лист=Книга.WorkSheets.Add();
Иначе
Лист=Книга.WorkSheets.Item(1); // нумерация с 1
КонецЕсли;
// самое главное: диапазону ячеек можно просто присвоить SafeArray со значениями
рНачало=Лист.Cells(1,1);
рКонец=Лист.Cells(квоСтрокДЭ,квоКолонокДЭ);
Лист.Range(рНачало,рКонец).Value=рМассив;
//
// соответствие форматов: xlOpenXMLWorkbook=51 это xlsx, xlExcel12=50 это xlsb, xlExcel8=56 это xls
стрпф=Новый Структура(«xls,xslx,xlsb»,56,51,50);
рФайл=Новый Файл(СокрЛП(рПутьИмяФайла));
расш=СтрЗаменить(рФайл.Расширение,«.»,«»);
рФормат=?(стрпф.Свойство(расш),стрпф[расш],51); // по умолчанию xlsx
Книга.SaveAs(СокрЛП(рПутьИмяФайла),рФормат);
Если рОткрыватьДляПросмотра Тогда
#Если Клиент Тогда
Ексель.Visible=Истина;
#КонецЕсли
КонецЕсли;
//
Ексель=Null;
Исключение
Сообщить(«БыстроВывестиТаблицуЗначенийВExcel, ошибка: «+ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецПроцедуры
Желающим плюсить — сюда: //infostart.ru/public/269846/
Ну а первоисточник, который применял я, здесь: http://kb.mista.ru/article.php?id=707
Поскольку моё тут только конкретное воплощение, публикацию особо плюсить не стоит, и вообще она life.
Всего вторую публикацию за сегодня читаю и уже второй способ удаления гланд через задницу. Сегодня «День проктолога» что ли?
Вопрос в автору, как у гуру: можно в предложенном коде сделать «Попытку ..» не в блоке загрузки данных? То бишь, я хочу в начале проверить, что все загрузиться, а уже потом точно загружать данные! Спасибо!
(1) BigClock, господин «пионэр», вы, вероятно, не поняли фишку, что, возможно, ввиду малого опыта простительно. Я ведь написал — это вариант быстрого способа. Да ещё и не подвешивающего клиентскую машину. Флаг вам в руки сохранять моксель на 300 тысяч строк методом Записать() при небольшой оперативке, тогда поймёте.
(3) Что будет являться критерием «успешной загрузки» при проверке, и чем тогда, на ваш взгляд, загрузка будет отличаться от проверки оной?
(5) так работает типовой механизм. Куда не поставь 1С везде создаст файл эксель. Ваш вариант предполагает установку экселя на сервер с 1С. Что может быть и вообще не быстро, т.к. просто не создастся наш файл.
(5) вполне все работает. (не про производительность речь)
(6), (7), мы с вами на разных 1С работаем, видимо, или у вас эксели ооочень сильно продвинутые. Позволю себе процитировать СП:
Записать (Write)
Синтаксис:
Записать(<ИмяФайла>, <ТипФайлаТаблицы>)
Параметры:
<ИмяФайла> (обязательный)
Тип: Строка.
Имя файла, в котором сохраняется табличный документ.
<ТипФайлаТаблицы> (необязательный)
Тип: ТипФайлаТабличногоДокумента.
Формат, в котором будет сохранен табличный документ.
Значение по умолчанию: MXL.
А теперь скажите мне, в приведённом фрагменте кода явно указан второй параметр, определяющий формат документа? Нет, не указан. А это означает, что эксель нихрена не откроет файл, сделанный таким образом. Желающие приглашаются проверить.
Вообще это напоминает старый анекдот, как преобразовать pdf в вордовский файл — взять да и поменять расширение файла)))
(8) а вот хамить не надо. Я понимаю, обидно, когда сидишь тут, ваяешь супермегастатью про свой убергиперспособ, а тут первый же комментатор пишет шесть строк кода, которые делают то же самое. И — о, чудо! о, подарок судьбы! — допускает мелкую ошибку. В коде, набитом на коленке чисто ради примера.
Движок сайта не даёт ставить минусы чаще, чем раз в пять минут, но я никуда не тороплюсь.
(8) в (1) Действительно ошибка, но сам способ я использую тоже, не могу сказать про 300тыщ, это реально много, но я регулярно сохраняю таким образом в экселевккий файлик результат СКД отчета размером в 80К строк и десяток колонок, на стареньком ноуте со старым процом и 2гигами памяти. Занимает секунд 10-20 гдето, не могу сказать точнее.
(8) то, что там не указано расширение. Это косяк поста 1, но метод рабочий и расширение явно зададим и получим результат без тонны кода.
Естественно для вывода простого отчета это то что нужно, ваш метод как раз таки не для таких случаем.
Так что вопрос в задаче, а не быстроте/простоте!
Очень странно читать некоторые комментарии, с производительностью кто нибудь сталкивался вообще? С нагрузкой? С требованиями оптимизировать код? Автору плюс. Практически так же записываю.
(3) DoctorRoza, Не проще тогда все делать в транзакции?
(13) zikonza, туманно представляю, чем может помочь транзакция. 1С ведь не будет откатывать изменения в стороннем клиентском приложении при отказе транзакции.
(14) не сохраню его так же,как и при попытке. По сути смысл тотже
(16) zikonza, а, это да. Это вариант.
Yashazz,
Да, в (1) есть косяк.
Но в статье не было приведено никаких цифр (хотя бы ориентировочных) по сравнению Вашего способа с очевидным.
Становится непонятным: стоит ли городить огород с такой большой процедурой?
В (10) были приведены цифры. Очевидно, что для большинства применений этого простейшего способа из 6 строк более, чем достаточно.
Речь идет о подходе к решению задачи, а не о том, что именно этот код я буду внедрять у клиента. Тем более, что перед внедрением я обязательно проведу тестирование решения, в результате которого эта ошибка будет обнаружена.
(18) BigClock,
Не ставил такой цели. Я русским по белому написал, что это за публикация и зачем, а некоторые с таким жаром накинулись, будто я ноу-хау анонсировал. Прямо жаль, что того автора, ссылку на публикацию которого я привёл, так не комментили, потому что вон он понты раскидывал — не мне чета)
В моих случаях, в решениях промышленного масштаба, ещё как стоит.
Согласен. Более того, если условия задачи допускают простое решение, то именно городить сложный огород и есть ошибка. Можно сделать просто — нужно сделать просто.
(4) А 300 тысяч строк в Екселе нужны чтобы что с ними делать?
(20) genayo, Например загрузить в другую систему, которая умеет грузить только из файла эксела
ячейки с датами как сохранятся в экселе в приведнном коде? к примеру результат выводя СКД?
(21) Именно.
(22) anosin, как даты сохраняются. Или это не ко мне вопрос?
Как отлавливаете незакрывшиеся процессы экселя на сервере?
(24) MadDAD, правду сказать — никак. Всё руки не доходят заняться этой частью задачи.
(8) Эксель отлично открывает формат MXL !
(26) androgin, это в вас говорит или малый опыт, или большой оптимизм. Далеко не все версии и далеко не всегда способны открыть mxl. А иногда вроде и открывают, но лучше бы отказались, таков бывает результат.
Не понимаю восторгов автора от собственного творения. Метод не самый быстрый, хотя и не самый медленный. Но самый главный минус — использование Excel для выгрузки просто таблицы значений без форматирования. Копайте в сторону ADO и будет вам счастье — там можно выгружать и в Excel и в Access не имея установленного офиса.
(28) Ivon, во-первых, восторгов особых вроде не вижу. Покажите, где вы их нашли, а? Уж не фраза ли «публикацию особо плюсить не стоит» это восторг?
Во-вторых, спасибо, но механикой ADO я владею в достаточной мере.
В третьих, если кто-то справедливо раскритиковал вашу разработку, ползать по ИС и цепляться к его работам — ну, несколько странно выглядит.
(29) Если вы так хорошо во всем разбираетесь, зачем постить подобный шлак. И это тоже справедливая критика